Search code examples
pythoncgcccode-generation

Calling gcc from python script gives me 'Undefined symbols: "_main"


I am trying to write a code generator script in Python, that generates a C-source file, compiles it and runs it. However, I am having trouble calling gcc from my script.

A simple hello world example:

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]);  

If I run this script, I get the following error output

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

If I do the exact same thing in the python interpreter shell, it works fine. I can also compile the code without problems directly in the shell.

I have tried various variants, using subprocess.Popen(), subprocess.call(), with and without all possible combinations of arguments that I can think of, still the same problem.

Anyone has any idea what might be my problem here?


Solution

  • Change this

    outfile.close;
    

    to this:

    outfile.close()
    

    You're not actually closing the file, so Python isn't flushing its buffers, so all that's in the source file is an empty file. When gcc compiles an empty file, it complains that there's no main function to serve as the program's entry point.

    I'd also suggest that you check that p.returncode is 0 to ensure that gcc succeeded before trying to execute the (possibly non-existant) output binary.

    Also there's no need to end each statement with a semicolon. You only need a semicolon if you have multiple statements per line, in which case you need them in between statements. End-of-line servers as a statement terminator when not preceded by a backslash.