Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a python script to compile and run a c++ file

I have been writing a simple python script to compile and run a given .cpp file.

I've gotten it to work as expected but I want to be able to stop the script if the compilation of the .cpp file produces errors or warnings, rather then going on to execute the .exe file.

# run_cpp.py
# Script that compiles and executes a .cpp file
# Usage:
# python run_cpp.py -i <filename> (without .cpp extension)

import sys, os, getopt

def main(argv):
    cpp_file = ''
    exe_file = ''
    try:
        opts, args = getopt.getopt(argv, "hi:",["help",'ifile='])
    except getopt.GetoptError as err:
        # print help information and exit
        print(err)      
        usage()
        sys.exit(2)
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-i", "--ifile"):
            cpp_file = a + '.cpp'
            exe_file = a + '.exe'
            run(cpp_file, exe_file)


def usage():
    print('run_cpp.py -i <filename> (without .cpp extension)')

def run(cpp_file, exe_file):
    os.system("echo Compiling " + cpp_file)
    os.system('g++ ' + cpp_file + ' -o ' + exe_file)
    os.system("echo Running " + exe_file)
    os.system("echo -------------------")
    os.system(exe_file)

if __name__=='__main__':
    main(sys.argv[1:])

When I run the following command on windows MINGW, everything is great.

$ python run_cpp.py -i hello
Compiling hello.cpp
Running hello.exe
-------------------
Hello, world!

where hello.cpp is :-

#include <iostream>
using namespace std;

int main() {
    cout << "Hello, world!" << endl;
    return 0;
}

If I leave out the semicolon after endl, the script goes on to run the .exe file, despite the compile errors.

$ python run_cpp.py -i hello
Compiling hello.cpp
hello.cpp: In function 'int main()':
hello.cpp:8:5: error: expected ';' before 'return'
     return 0;
     ^~~~~~
Running hello.exe
-------------------
Hello, world!

How can I make my script know whether or not compilation was successful before trying to run the .exe file?


I've updated the code based on the answer.

if os.system('g++ ' + cpp_file + ' -o ' + exe_file) == 0:
    os.system(exe_file)

Now the script will only execute the .exe file when compilation succeeds.

Another way to do the same thing but using the subprocess library instead of the os library, as recommended by the python documentation would be -

def run(cpp_file, exe_file):
    x = subprocess.getoutput('g++ ' + cpp_file + ' -o ' + exe_file)
    if x == "":                         # no error/warning messages
        subprocess.run(exe_file)        # run the program
    else:
        print(x)                        # display the error/warning
like image 558
karanveer41 Avatar asked Oct 29 '22 16:10

karanveer41


1 Answers

All commands return an exit code specifying whether or not the command succeeded, for some command specific definition of success. os.system typically returns this exit code, where 0 conventionally means "success" and any other exit code indicates an error:

if os.system("g++ foo.c") == 0:
    print ("Worked")
else:
    print ("Failed")

The documentation mentions some caveats and better APIs to use:

On Unix, the return value is the exit status of the process encoded in the format specified for wait(). Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent.

On Windows, the return value is that returned by the system shell after running command. The shell is given by the Windows environment variable COMSPEC: it is usually cmd.exe, which returns the exit status of the command run; on systems using a non-native shell, consult your shell documentation.

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

like image 116
that other guy Avatar answered Oct 31 '22 21:10

that other guy