From 1b35668eb7255ae5534d278ba980e4de92b93a92 Mon Sep 17 00:00:00 2001 From: Leonardo de Moura Date: Wed, 26 Dec 2012 17:24:26 -0800 Subject: [PATCH] Improve Z3Py installation in non-standard prefix. Signed-off-by: Leonardo de Moura --- scripts/mk_util.py | 61 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 268a6d27b..242e8797a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -68,7 +68,7 @@ VER_MAJOR=None VER_MINOR=None VER_BUILD=None VER_REVISION=None -PREFIX='/usr' +PREFIX=os.path.split(os.path.split(os.path.split(PYTHON_PACKAGE_DIR)[0])[0])[0] GMP=False VS_PAR=False VS_PAR_NUM=8 @@ -357,7 +357,6 @@ def display_help(exit_code): print(" -s, --silent do not print verbose messages.") if not IS_WINDOWS: print(" -p , --prefix= installation prefix (default: %s)." % PREFIX) - print(" -y , --pydir= installation prefix for Z3 python bindings (default: %s)." % PYTHON_PACKAGE_DIR) else: print(" --parallel=num use cl option /MP with 'num' parallel processes") print(" -b , --build= subdirectory where Z3 will be built (default: build).") @@ -393,9 +392,9 @@ def parse_options(): global DOTNET_ENABLED, JAVA_ENABLED, STATIC_LIB, PREFIX, GMP, PYTHON_PACKAGE_DIR try: options, remainder = getopt.gnu_getopt(sys.argv[1:], - 'b:dsxhmcvtnp:gjy:', + 'b:dsxhmcvtnp:gj', ['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', - 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'pydir=', 'parallel=']) + 'trace', 'nodotnet', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=']) except: print("ERROR: Invalid command line option") display_help(1) @@ -429,12 +428,13 @@ def parse_options(): STATIC_LIB = True elif not IS_WINDOWS and opt in ('-p', '--prefix'): PREFIX = arg + PYTHON_PACKAGE_DIR = os.path.join(PREFIX, 'lib', 'python%s' % distutils.sysconfig.get_python_version(), 'dist-packages') + mk_dir(PYTHON_PACKAGE_DIR) + if sys.version >= "3": + mk_dir(os.path.join(PYTHON_PACKAGE_DIR, '__pycache__')) elif IS_WINDOWS and opt == '--parallel': VS_PAR = True VS_PAR_NUM = int(arg) - elif opt in ('-y', '--pydir'): - PYTHON_PACKAGE_DIR = arg - mk_dir(PYTHON_PACKAGE_DIR) elif opt in ('-g', '--gmp'): GMP = True elif opt in ('-j', '--java'): @@ -1402,6 +1402,7 @@ def mk_config(): print('OpenMP: %s' % HAS_OMP) print('Prefix: %s' % PREFIX) print('64-bit: %s' % is64()) + print('Python version: %s' % distutils.sysconfig.get_python_version()) if is_java_enabled(): print('Java Home: %s' % JAVA_HOME) print('Java Compiler: %s' % JAVAC) @@ -1414,15 +1415,30 @@ def mk_install(out): out.write('\t@mkdir -p %s\n' % os.path.join('$(PREFIX)', 'lib')) for c in get_components(): c.mk_install(out) - out.write('\t@cp z3*.pyc %s\n' % PYTHON_PACKAGE_DIR) + out.write('\t@cp z3*.py %s\n' % PYTHON_PACKAGE_DIR) + if sys.version >= "3": + out.write('\t@cp %s*.pyc %s\n' % (os.path.join('__pycache__', 'z3'), + os.path.join(PYTHON_PACKAGE_DIR, '__pycache__'))) + else: + out.write('\t@cp z3*.pyc %s\n' % PYTHON_PACKAGE_DIR) out.write('\t@echo Z3 was successfully installed.\n') + if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib(): + if os.uname()[0] == 'Darwin': + LD_LIBRARY_PATH = "DYLD_LIBRARY_PATH" + else: + LD_LIBRARY_PATH = "LD_LIBRARY_PATH" + out.write('\t@echo Z3 shared libraries were installed at \'%s\', make sure this directory is in your %s environment variable.\n' % + (os.path.join(PREFIX, 'lib'), LD_LIBRARY_PATH)) + out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR) out.write('\n') def mk_uninstall(out): out.write('uninstall:\n') for c in get_components(): c.mk_uninstall(out) + out.write('\t@rm -f %s*.py\n' % os.path.join(PYTHON_PACKAGE_DIR, 'z3')) out.write('\t@rm -f %s*.pyc\n' % os.path.join(PYTHON_PACKAGE_DIR, 'z3')) + out.write('\t@rm -f %s*.pyc\n' % os.path.join(PYTHON_PACKAGE_DIR, '__pycache__', 'z3')) out.write('\t@echo Z3 was successfully uninstalled.\n') out.write('\n') @@ -1441,6 +1457,8 @@ def mk_makefile(): if c.main_component(): out.write(' %s' % c.name) out.write('\n\t@echo Z3 was successfully built.\n') + out.write("\t@echo \"Z3Py scripts can already be executed in the \'%s\' directory.\"\n" % BUILD_DIR) + out.write("\t@echo \"Z3Py scripts stored in arbitrary directories can be also executed if \'%s\' directory is added to the PYTHONPATH environment variable.\"\n" % BUILD_DIR) if not IS_WINDOWS: out.write("\t@echo Use the following command to install Z3 at prefix $(PREFIX).\n") out.write('\t@echo " sudo make install"\n') @@ -1920,17 +1938,30 @@ def mk_def_files(): if c.require_def_file(): mk_def_file(c) -def cp_z3pyc_to_build(): +def cp_z3py_to_build(): mk_dir(BUILD_DIR) + # Erase existing .pyc files + for root, dirs, files in os.walk(Z3PY_SRC_DIR): + for f in files: + if f.endswith('.pyc'): + rmf(os.path.join(root, f)) + # Compile Z3Py files if compileall.compile_dir(Z3PY_SRC_DIR, force=1) != 1: raise MKException("failed to compile Z3Py sources") + # Copy sources to build + for py in filter(lambda f: f.endswith('.py'), os.listdir(Z3PY_SRC_DIR)): + shutil.copyfile(os.path.join(Z3PY_SRC_DIR, py), os.path.join(BUILD_DIR, py)) + if is_verbose(): + print("Copied '%s'" % py) + # Python 2.x support for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(Z3PY_SRC_DIR)): - try: - os.remove(os.path.join(BUILD_DIR, pyc)) - except: - pass shutil.copyfile(os.path.join(Z3PY_SRC_DIR, pyc), os.path.join(BUILD_DIR, pyc)) - os.remove(os.path.join(Z3PY_SRC_DIR, pyc)) + if is_verbose(): + print("Generated '%s'" % pyc) + # Python 3.x support + for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(os.path.join(Z3PY_SRC_DIR, '__pycache__'))): + mk_dir(os.path.join(BUILD_DIR, '__pycache__')) + shutil.copyfile(os.path.join(Z3PY_SRC_DIR, '__pycache__', pyc), os.path.join(BUILD_DIR, '__pycache__', pyc)) if is_verbose(): print("Generated '%s'" % pyc) @@ -1949,7 +1980,7 @@ def mk_bindings(api_files): check_java() mk_z3consts_java(api_files) _execfile(os.path.join('scripts', 'update_api.py'), g) # HACK - cp_z3pyc_to_build() + cp_z3py_to_build() # Extract enumeration types from API files, and add python definitions. def mk_z3consts_py(api_files):