从python脚本调用gcc给我'未定义的符号:“_main”

问题描述:

我想在Python中编写一个代码生成器脚本,生成一个C源文件,编译并运行它。但是,我无法从脚本中调用gcc。从python脚本调用gcc给我'未定义的符号:“_main”

简单的Hello World例子:

import subprocess 

basename = "CodeGenTest"; 
execname = basename; 
srcname = basename + ".c"; 

codeList = []; 
codeList.append("#include <stdio.h>"); 
codeList.append("int main(int argc, char *argv[])\n{"); 
codeList.append("printf(\"Hello world.\\n\");"); 
codeList.append("}"); 

# Convert codelist to string. 
codeList.append(""); 
codeString = "\n".join(codeList); 

# Print code to output source file 
outfile=open(srcname,'w'); 
outfile.write(codeString); 
outfile.close; 

print "Compile."; 
cmd = ["gcc", "-O2", srcname, "-o", execname]; 
p = subprocess.Popen(cmd); 
p.wait(); 

subprocess.call(["./"+execname]); 

如果我运行该脚本,我碰到下面的错误输出

Compile. 
Undefined symbols: 
    "_main", referenced from: 
     start in crt1.10.6.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

如果我做同样的事情在Python解释器的外壳,它工作正常。我也可以在shell中直接编译代码。

我尝试了各种变体,使用subprocess.Popen(),subprocess.call(),有和没有我能想到的所有可能的参数组合,仍然是同样的问题。

任何人有任何想法可能是我的问题在这里?

+0

这听起来像是一个可怕的坏主意的简单例子。如果不使用(非字符串!)内部表示形式(AST = ** abstract ** syntax ** tree **),则不能编写编译器,同样,只能使用字符串生成非平凡源代码。 – delnan 2010-11-27 19:04:59

+0

代码生成器将生成,编译并运行一段非常特定的代码,并针对各种优化参数(即自动调谐器)对其进行评估,并最终以运行时方式吐出最佳版本的代码。我完全意识到需要更高层次的代码抽象,但是在某些时候我需要生成和编译代码,这篇文章就是一个简单的例子。 – Magnus 2010-11-28 06:01:01

你其实并没有打电话给outfile.close;它应该是outfile.close()。很有可能源代码仍然停留在某个缓冲区,而GCC不会看到它。

+0

是的,这是问题所在。谢谢! – Magnus 2010-11-27 19:08:58

更改此

outfile.close; 

这样:

outfile.close() 

您实际上并不关闭文件,所以Python是不是刷新其缓冲区,因此,所有这就是在源文件中是空的文件。当gcc编译一个空文件时,它会抱怨没有main函数作为程序的入口点。

我还建议你检查p.returncode是否为0,以确保gcc在尝试执行(可能不存在的)输出二进制文件之前成功。

也不需要用分号结束每个语句。如果每行有多个语句,则只需要一个分号,在这种情况下,您需要在两个语句之间使用它们。在没有反斜杠之前,将行结束服务器作为语句终结符。

您可以通过使用与块来管理文件,避免此类问题:

with file(srcname, 'w') as outfile: outfile.write(codeString) 

同时请注意,除非你正在写在同一行多个语句分号不是用Python要求。