【问题标题】:Calling gcc from python script gives me 'Undefined symbols: "_main"从 python 脚本调用 gcc 给了我'未定义的符号:“_main”
【发布时间】:2011-05-16 15:37:03
【问题描述】:

我正在尝试用 Python 编写一个代码生成器脚本,它生成一个 C 源文件,编译并运行它。但是,我无法从脚本调用 gcc。

一个简单的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 中做同样的事情,它工作正常。我也可以直接在shell中编译没有问题的代码。

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

有人知道我的问题是什么吗?

【问题讨论】:

  • 这听起来像是一个非常糟糕的想法的精简示例。如果不使用(非字符串!)内部表示(AST = abstract 语法 tree),您将无法编写编译器,同样您也无法仅使用字符串。
  • 代码生成器将生成、编译和运行一段非常具体的代码,并针对各种优化参数(即自动调谐器)对其进行评估,并最终生成最佳版本代码,运行时。我非常清楚需要对代码进行更高级别的抽象,但有时我需要生成和编译代码,这篇文章就是一个简单的例子。

标签: python c gcc code-generation


【解决方案1】:

你实际上并没有打电话给outfile.close;它应该是outfile.close()。很有可能源仍然卡在某个缓冲区中,而 GCC 看不到它。

【讨论】:

  • 是的,这就是问题所在。谢谢!
【解决方案2】:

改变这个

outfile.close;

到这里:

outfile.close()

你实际上并没有关闭文件,所以 Python 没有刷新它的缓冲区,所以源文件中的所有内容都是一个空文件。 gcc 编译一个空文件时,它会抱怨没有main 函数可以作为程序的入口点。

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

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

【讨论】:

  • 谢谢,这行得通。几个小时以来,我一直盯着我的眼睛瞎了,但我没有看到它(为什么 Python 没有给我一条错误消息?)。分号只是一种自动习惯,因为我主要编写 C/C++ 代码。
  • @Magnus:因为这不是错误。不是必要。是的,不管它可能是一个错误,但我不想错过一流的函数,只有在丢弃它时发出警告需要比 CPython 更多的静态分析。另外,我自己也很少遇到这种情况……也许只是习惯问题。
【解决方案3】:

你可以通过使用 with-block 来管理文件来避免这个问题:

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

另外请注意,除非您在同一行上编写多个语句,否则 Python 中不需要分号。

【讨论】:

    猜你喜欢
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 2017-08-12
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多