summaryrefslogtreecommitdiffstats
path: root/lldb/scripts/install_custom_python.py
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2015-04-10 22:58:56 +0000
committerZachary Turner <zturner@google.com>2015-04-10 22:58:56 +0000
commitdd50f7421cebbbdf6ba0a5116e40329d6522c9e6 (patch)
tree42a07c7941af7c17c489d45cb0a0b7465ed5626e /lldb/scripts/install_custom_python.py
parent1290047a7d70b304114127dbcabe5f79dbca325e (diff)
downloadbcm5719-llvm-dd50f7421cebbbdf6ba0a5116e40329d6522c9e6.tar.gz
bcm5719-llvm-dd50f7421cebbbdf6ba0a5116e40329d6522c9e6.zip
Making linking against Python simpler on Windows.
This patch deprecates the three Python CMake variables in favor of a single variable PYTHON_HOME which points to the root of a python installation. Since building Python doesn't output the files in a structure that is compatible with the PYTHONHOME environment variable, we also provide a script install_custom_python.py which will copy the output of a custom python build to the correct directory structure. The supported workflow after this patch will be to build python once for each configuration and architecture {Debug,Release} x {x86,x64} and then run the script. Then run CMake specifying -DPYTHON_HOME=<path> The first time you do this will probably require you to delete your CMake cache. The old workflow is still supported during a transitionary period, but a warning is printed at CMake time, and this will eventually be removed. Differential Revision: http://reviews.llvm.org/D8979 llvm-svn: 234660
Diffstat (limited to 'lldb/scripts/install_custom_python.py')
-rw-r--r--lldb/scripts/install_custom_python.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/lldb/scripts/install_custom_python.py b/lldb/scripts/install_custom_python.py
new file mode 100644
index 00000000000..5a8f48aac94
--- /dev/null
+++ b/lldb/scripts/install_custom_python.py
@@ -0,0 +1,134 @@
+""" Copies the build output of a custom python interpreter to a directory
+ structure that mirrors that of an official Python distribution.
+
+ --------------------------------------------------------------------------
+ File: install_custom_python.py
+
+ Overview: Most users build LLDB by linking against the standard
+ Python distribution installed on their system. Occasionally
+ a user may want to build their own version of Python, and on
+ platforms such as Windows this is a hard requirement. This
+ script will take the build output of a custom interpreter and
+ install it into a canonical structure that mirrors that of an
+ official Python distribution, thus allowing PYTHONHOME to be
+ set appropriately.
+
+ Gotchas: None.
+
+ Copyright: None.
+ --------------------------------------------------------------------------
+
+"""
+
+import argparse
+import itertools
+import os
+import shutil
+import sys
+
+def copy_one_file(dest_dir, source_dir, filename):
+ source_path = os.path.join(source_dir, filename)
+ dest_path = os.path.join(dest_dir, filename)
+ print 'Copying file %s ==> %s...' % (source_path, dest_path)
+ shutil.copyfile(source_path, dest_path)
+
+def copy_named_files(dest_dir, source_dir, files, extensions, copy_debug_suffix_also):
+ for (file, ext) in itertools.product(files, extensions):
+ copy_one_file(dest_dir, source_dir, file + '.' + ext)
+ if copy_debug_suffix_also:
+ copy_one_file(dest_dir, source_dir, file + '_d.' + ext)
+
+def copy_subdirectory(dest_dir, source_dir, subdir):
+ dest_dir = os.path.join(dest_dir, subdir)
+ source_dir = os.path.join(source_dir, subdir)
+ print 'Copying directory %s ==> %s...' % (source_dir, dest_dir)
+ shutil.copytree(source_dir, dest_dir)
+
+def copy_distro(dest_dir, dest_subdir, source_dir, source_prefix):
+ dest_dir = os.path.join(dest_dir, dest_subdir)
+
+ print 'Copying distribution %s ==> %s' % (source_dir, dest_dir)
+
+ os.mkdir(dest_dir)
+ PCbuild_dir = os.path.join(source_dir, 'PCbuild')
+ if source_prefix:
+ PCbuild_dir = os.path.join(PCbuild_dir, source_prefix)
+ # First copy the files that go into the root of the new distribution. This
+ # includes the Python executables, python27(_d).dll, and relevant PDB files.
+ print 'Copying Python executables...'
+ copy_named_files(dest_dir, PCbuild_dir, ['w9xpopen'], ['exe', 'pdb'], False)
+ copy_named_files(dest_dir, PCbuild_dir, ['python_d', 'pythonw_d'], ['exe'], False)
+ copy_named_files(dest_dir, PCbuild_dir, ['python', 'pythonw'], ['exe', 'pdb'], False)
+ copy_named_files(dest_dir, PCbuild_dir, ['python27'], ['dll', 'pdb'], True)
+
+ # Next copy everything in the Include directory.
+ print 'Copying Python include directory'
+ copy_subdirectory(dest_dir, source_dir, 'Include')
+
+ # Copy Lib folder (builtin Python modules)
+ print 'Copying Python Lib directory'
+ copy_subdirectory(dest_dir, source_dir, 'Lib')
+
+ # Copy tools folder. These are probably not necessary, but we copy them anyway to
+ # match an official distribution as closely as possible. Note that we don't just copy
+ # the subdirectory recursively. The source distribution ships with many more tools
+ # than what you get by installing python regularly. We only copy the tools that appear
+ # in an installed distribution.
+ tools_dest_dir = os.path.join(dest_dir, 'Tools')
+ tools_source_dir = os.path.join(source_dir, 'Tools')
+ os.mkdir(tools_dest_dir)
+ copy_subdirectory(tools_dest_dir, tools_source_dir, 'i18n')
+ copy_subdirectory(tools_dest_dir, tools_source_dir, 'pynche')
+ copy_subdirectory(tools_dest_dir, tools_source_dir, 'scripts')
+ copy_subdirectory(tools_dest_dir, tools_source_dir, 'versioncheck')
+ copy_subdirectory(tools_dest_dir, tools_source_dir, 'webchecker')
+
+ pyd_names = ['_ctypes', '_ctypes_test', '_elementtree', '_multiprocessing', '_socket',
+ '_testcapi', 'pyexpat', 'select', 'unicodedata', 'winsound']
+
+ # Copy builtin extension modules (pyd files)
+ dlls_dir = os.path.join(dest_dir, 'DLLs')
+ os.mkdir(dlls_dir)
+ print 'Copying DLLs directory'
+ copy_named_files(dlls_dir, PCbuild_dir, pyd_names, ['pyd', 'pdb'], True)
+
+ # Copy libs folder (implibs for the pyd files)
+ libs_dir = os.path.join(dest_dir, 'libs')
+ os.mkdir(libs_dir)
+ print 'Copying libs directory'
+ copy_named_files(libs_dir, PCbuild_dir, pyd_names, ['lib'], False)
+ copy_named_files(libs_dir, PCbuild_dir, ['python27'], ['lib'], True)
+
+
+parser = argparse.ArgumentParser(description='Install a custom Python distribution')
+parser.add_argument('--source', required=True, help='The root of the source tree where Python is built.')
+parser.add_argument('--dest', required=True, help='The location to install the Python distributions.')
+parser.add_argument('--overwrite', default=False, action='store_true', help='If the destination directory already exists, destroys its contents first.')
+parser.add_argument('--silent', default=False, action='store_true', help='If --overwite was specified, suppress confirmation before deleting a directory tree.')
+
+args = parser.parse_args()
+
+args.source = os.path.normpath(args.source)
+args.dest = os.path.normpath(args.dest)
+
+if not os.path.exists(args.source):
+ print 'The source directory %s does not exist. Exiting...'
+ sys.exit(1)
+
+if os.path.exists(args.dest):
+ if not args.overwrite:
+ print 'The destination directory \'%s\' already exists and --overwrite was not specified. Exiting...' % args.dest
+ sys.exit(1)
+ while not args.silent:
+ print 'Ok to recursively delete \'%s\' and all contents (Y/N)? Choosing Y will permanently delete the contents.' % args.dest
+ result = str.upper(sys.stdin.read(1))
+ if result == 'N':
+ print 'Unable to copy files to the destination. The destination already exists.'
+ sys.exit(1)
+ elif result == 'Y':
+ break
+ shutil.rmtree(args.dest)
+
+os.mkdir(args.dest)
+copy_distro(args.dest, 'x86', args.source, None)
+copy_distro(args.dest, 'x64', args.source, 'amd64')
OpenPOWER on IntegriCloud