Search code examples
pythoneclipsecross-platformcode-composer

How can I invoke a Python 3 script as a CCS/Eclipse build step on both Linux and Windows?


I have a Python 3.5 script that I would like to invoke as a pre-build step in my Code Composer build. To be clear, it should be run as one of the entries in (my project) > Properties > CCS Build > Steps > Pre-build steps.

The script currently begins with the hashbang #!/usr/bin/env python3, but I can change this.

On Linux, I can invoke the script as ../prebuild.py ../output_file. This fails on Windows 10 with:

"C:\\ti\\ccsv6\\utils\\bin\\gmake" -k all 
../prebuild.py ../output_file
makefile:217: recipe for target 'pre-build' failed
process_begin: CreateProcess(NULL, env python3 C:\path\to\prebuild.py ../output_file, ...) failed.
make (e=2): The system cannot find the file specified.

The path separator does not affect this at all.

I also tried python3 ../prebuild.py ../output_file. This does not work on Windows 10 because there is no python3 executable. Python 3 is installed as python.exe. Using python fails on Linux because of course Python 3 is installed as python3, and python refers to Python 2.

I also tried py ../prebuild.py ../output_file. This fails on Linux because there is no py executable.

Is there a cross-platform way to invoke a Python 3 script that can be used for an Eclipse pre-build step? I would like to avoid requiring that developers modify their distribution/Python installation.

I am using Code Composer Studio 6, which is based on Eclipse. I expect any answer to this would apply to either.

Context

One of the things I am trying to achieve is to insert the SHA1 of the current Git commit into a file. The accepted answer for doing this is to generate the file as part of the build process by parsing Git output. I have a Python script that can do this on both Windows and Linux, so I need a way to invoke it as part of Eclipse's build process.


Solution

  • Have a wrapper script that works under both Python 2 and 3 to detect and run the script with the correct Python version. The Eclipse/CCS pre build step can then be python ../wrapper.py (possibly with extra arguments like ../prebuild.py args).

    You could just check if it is running on Windows or Linux and what version of Python it is running. If it is running on Linux and running the wrong Python version, run subprocess.call(['python3','prebuild.py']). To check the Python version and OS use:

    import os, sys, subprocess
    
    if sys.version_info[0] < 3 and os.name == 'posix':
         subprocess.call(['python3','../prebuild.py'])
         sys.exit()
    else:
        subprocess.call(['python','../prebuild.py'])
        sys.exit()
    

    A more generic script might check if the interpreter is already the right one and try to pass through arguments if it is:

    import sys
    
    if sys.version_info[0] >= 3 and sys.version_info[1] >= 3:
        subprocess.call([sys.executable] + sys.argv[1:]
    

    Otherwise the wrapper could iterate over a list of possible interpreters until it succeeds, like:

    interpreters = [["py", "-3"], ["python3"]]
    
    for interp in interpreters:
         # Try a subprocess.call(...) as above. Detect bad return codes (eg. py failed) or OSErrors (ie. command wasn't found).
         success = False
         try:
            success = subprocess.call(...) == 0
         except OSError:
             pass
    
         if success:
             break