detly detly - 3 months ago 18
Python Question

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.

Answer

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