commit 94f1d2fa9582a2942d5154b85c849cc3c6140e31 Author: Raphael Kubo da Costa Date: Wed Dec 16 18:25:13 2015 +0100 PythonMacros: specify destination directory in byte-compiled files. The PYTHON_INSTALL() macro is a wrapper around the py_compile Python module that also installs the byte-code (.pyc) file it generates. However, when a .py file is passed to py_compile without any additional arguments, its full path is recorded in the .pyc file. This is problematic, as most distributions install all files into a build root instead of simply copying files to / as part of the packaging process. In this case, the generated .pyc file will have something like /wrkdir/buildroot/usr/lib/python2.7/site-packages/Foo/my_module.py in it. Not only does this show up in exception tracebacks, but if the user later invokes my_module.py and has write access to my_module's directory, my_module.pyc will be rewritten with the right path to my_module.py (without the build root). This can lead to uninstallation errors if the package management system checks each file before removal, for example. Fix it by rewritting the PythonCompile.py script so that it takes a --destination-dir argument that we use to pass the full path to my_module.py instead of letting it be (wrongly) deduced. It is important to note that PythonCompile.py now uses the argparse module, which is not present in Python <= 2.6, Python 3.0 and Python 3.1. REVIEW: 126345 Required for PR 200018. Part of this commit is in patch-cmake_modules_PythonMacros.py. --- cmake/modules/PythonCompile.py +++ cmake/modules/PythonCompile.py @@ -1,4 +1,29 @@ # By Simon Edwards # This file is in the public domain. -import py_compile, sys -sys.exit(py_compile.main()) + +""" +Byte-compiles a given Python source file, generating a .pyc file or, if the +Python executable was invoked with -O, a .pyo file from it. +It uses the --destination-dir option to set the path to the source file (which +will appear in tracebacks, for example), so that if the .py file was in a build +root will appear with the right path. +""" + +import argparse +import os +import py_compile + + +if __name__ == '__main__': + parser = argparse.ArgumentParser('Byte-compiles a Python source file.') + parser.add_argument('-d', '--destination-dir', required=True, + help='Location where the source file will be ' + 'installed, without any build roots.') + parser.add_argument('source_file', + help='Source file to byte-compile.') + + args = parser.parse_args() + + dfile = os.path.join(args.destination_dir, + os.path.basename(args.source_file)) + py_compile.compile(args.source_file, dfile=dfile)