From 3415672f31a48d40768e35cc31292fd6bba2ac55 Mon Sep 17 00:00:00 2001
From: Michael Lowell Roberts <mirobert@microsoft.com>
Date: Tue, 28 Feb 2017 08:24:35 -0800
Subject: [PATCH] fixed bug where `mk_make.py --build=...` would fail to handle
 absolute paths correctly.

---
 doc/mk_api_doc.py       | 18 +++++++-----------
 scripts/mk_unix_dist.py | 12 ++++++------
 scripts/mk_util.py      | 23 +++++++++++------------
 scripts/mk_win_dist.py  | 22 +++++++++++-----------
 4 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/doc/mk_api_doc.py b/doc/mk_api_doc.py
index 45bc9a99c..edabcbd1b 100644
--- a/doc/mk_api_doc.py
+++ b/doc/mk_api_doc.py
@@ -12,10 +12,6 @@ import shutil
 ML_ENABLED=False
 BUILD_DIR='../build'
 
-def norm_path(p):
-    # We use '/' on mk_project for convenience
-    return os.path.join(*(p.split('/')))
-
 def display_help(exit_code):
     print("mk_api_doc.py: Z3 documentation generator\n")
     print("\nOptions:")
@@ -36,12 +32,12 @@ def parse_options():
 
     for opt, arg in options:
         if opt in ('-b', '--build'):
-            BUILD_DIR = norm_path(arg)
+            BUILD_DIR = mk_util.norm_path(arg)
         elif opt in ('h', '--help'):
             display_help()
             exit(1)
         elif opt in ('--ml'):
-            ML_ENABLED=True            
+            ML_ENABLED=True
         else:
             print("ERROR: Invalid command line option: %s" % opt)
             display_help(1)
@@ -59,7 +55,7 @@ def cleanup_API(inf, outf):
     pat1  = re.compile(".*def_API.*")
     pat2  = re.compile(".*extra_API.*")
     _inf  = open(inf, 'r')
-    _outf = open(outf, 'w') 
+    _outf = open(outf, 'w')
     for line in _inf:
         if not pat1.match(line) and not pat2.match(line):
             _outf.write(line)
@@ -90,9 +86,9 @@ try:
     cleanup_API('../src/api/z3_rcf.h', 'tmp/z3_rcf.h')
     cleanup_API('../src/api/z3_fixedpoint.h', 'tmp/z3_fixedpoint.h')
     cleanup_API('../src/api/z3_optimization.h', 'tmp/z3_optimization.h')
-    cleanup_API('../src/api/z3_interp.h', 'tmp/z3_interp.h')    
+    cleanup_API('../src/api/z3_interp.h', 'tmp/z3_interp.h')
     cleanup_API('../src/api/z3_fpa.h', 'tmp/z3_fpa.h')
-    
+
     print("Removed annotations from z3_api.h.")
     try:
         if subprocess.call(['doxygen', 'z3api.dox']) != 0:
@@ -112,7 +108,7 @@ try:
     os.remove('tmp/z3_interp.h')
     os.remove('tmp/z3_fpa.h')
     print("Removed temporary file header files.")
-    
+
     os.remove('tmp/website.dox')
     print("Removed temporary file website.dox")
     os.remove('tmp/z3py.py')
@@ -130,7 +126,7 @@ try:
             print("ERROR: ocamldoc failed.")
             exit(1)
         print("Generated ML/OCaml documentation.")
-        
+
     print("Documentation was successfully generated at subdirectory './api/html'.")
 except:
     exctype, value = sys.exc_info()[:2]
diff --git a/scripts/mk_unix_dist.py b/scripts/mk_unix_dist.py
index 488bc4364..00cf3c706 100644
--- a/scripts/mk_unix_dist.py
+++ b/scripts/mk_unix_dist.py
@@ -1,7 +1,7 @@
 ############################################
 # Copyright (c) 2013 Microsoft Corporation
-# 
-# Scripts for automatically generating 
+#
+# Scripts for automatically generating
 # Linux/OSX/BSD distribution zip files.
 #
 # Author: Leonardo de Moura (leonardo)
@@ -42,7 +42,7 @@ def mk_dir(d):
 
 def set_build_dir(path):
     global BUILD_DIR
-    BUILD_DIR = path
+    BUILD_DIR = mk_util.norm_path(path)
     mk_dir(BUILD_DIR)
 
 def display_help():
@@ -65,7 +65,7 @@ def display_help():
 def parse_options():
     global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE
     path = BUILD_DIR
-    options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=', 
+    options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
                                                                    'help',
                                                                    'silent',
                                                                    'force',
@@ -89,7 +89,7 @@ def parse_options():
         elif opt == '--nodotnet':
             DOTNET_ENABLED = False
         elif opt == '--nopython':
-            PYTHON_ENABLED = False            
+            PYTHON_ENABLED = False
         elif opt == '--dotnet-key':
             DOTNET_KEY_FILE = arg
         elif opt == '--nojava':
@@ -121,7 +121,7 @@ def mk_build_dir(path):
             opts.append('--python')
         if subprocess.call(opts) != 0:
             raise MKException("Failed to generate build directory at '%s'" % path)
-    
+
 # Create build directories
 def mk_build_dirs():
     mk_build_dir(BUILD_DIR)
diff --git a/scripts/mk_util.py b/scripts/mk_util.py
index 9451e67c0..17ab8dea0 100644
--- a/scripts/mk_util.py
+++ b/scripts/mk_util.py
@@ -153,8 +153,7 @@ def is_cygwin_mingw():
     return IS_CYGWIN_MINGW
 
 def norm_path(p):
-    # We use '/' on mk_project for convenience
-    return os.path.join(*(p.split('/')))
+    return os.path.expanduser(os.path.normpath(p))
 
 def which(program):
     import os
@@ -1393,7 +1392,7 @@ class DLLComponent(Component):
             shutil.copy('%s.a' % os.path.join(build_path, self.dll_name),
                         '%s.a' % os.path.join(dist_path, INSTALL_BIN_DIR, self.dll_name))
 
-class PythonComponent(Component): 
+class PythonComponent(Component):
     def __init__(self, name, libz3Component):
         assert isinstance(libz3Component, DLLComponent)
         global PYTHON_ENABLED
@@ -1418,7 +1417,7 @@ class PythonComponent(Component):
 
     def mk_makefile(self, out):
         return
-   
+
 class PythonInstallComponent(Component):
     def __init__(self, name, libz3Component):
         assert isinstance(libz3Component, DLLComponent)
@@ -1521,7 +1520,7 @@ class PythonInstallComponent(Component):
                                       os.path.join('python', 'z3', '*.pyc'),
                                       os.path.join(self.pythonPkgDir,'z3'),
                                       in_prefix=self.in_prefix_install)
-            
+
         if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib():
             out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR)
 
@@ -1586,7 +1585,7 @@ class DotNetDLLComponent(Component):
 
     def mk_makefile(self, out):
         global DOTNET_KEY_FILE
-        
+
         if not is_dotnet_enabled():
             return
         cs_fp_files = []
@@ -1631,7 +1630,7 @@ class DotNetDLLComponent(Component):
             else:
                 print("Keyfile '%s' could not be found; %s.dll will be unsigned." % (self.key_file, self.dll_name))
                 self.key_file = None
-                
+
         if not self.key_file is None:
             print("%s.dll will be signed using key '%s'." % (self.dll_name, self.key_file))
             cscCmdLine.append('/keyfile:{}'.format(self.key_file))
@@ -1658,7 +1657,7 @@ class DotNetDLLComponent(Component):
                              )
         else:
             cscCmdLine.extend(['/optimize+'])
-            
+
         if IS_WINDOWS:
             if VS_X64:
                 cscCmdLine.extend(['/platform:x64'])
@@ -1962,7 +1961,7 @@ class MLComponent(Component):
 
             OCAMLMKLIB = 'ocamlmklib'
 
-            LIBZ3 = '-L. -lz3'           
+            LIBZ3 = '-L. -lz3'
             if is_cygwin() and not(is_cygwin_mingw()):
                 LIBZ3 = 'libz3.dll'
 
@@ -2214,7 +2213,7 @@ class PythonExampleComponent(ExampleComponent):
     def mk_win_dist(self, build_path, dist_path):
         full = os.path.join(EXAMPLE_DIR, self.path)
         py = 'example.py'
-        shutil.copyfile(os.path.join(full, py), 
+        shutil.copyfile(os.path.join(full, py),
                         os.path.join(dist_path, INSTALL_BIN_DIR, 'python', py))
 
     def mk_unix_dist(self, build_path, dist_path):
@@ -2263,7 +2262,7 @@ def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, man
 def add_python(libz3Component):
     name = 'python'
     reg_component(name, PythonComponent(name, libz3Component))
-    
+
 def add_python_install(libz3Component):
     name = 'python_install'
     reg_component(name, PythonInstallComponent(name, libz3Component))
@@ -2689,7 +2688,7 @@ def get_full_version_string(major, minor, build, revision):
         branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD', '--long'])
         res += " master " + check_output(['git', 'describe'])
     return '"' + res + '"'
-        
+
 # Update files with the version number
 def mk_version_dot_h(major, minor, build, revision):
     c = get_component(UTIL_COMPONENT)
diff --git a/scripts/mk_win_dist.py b/scripts/mk_win_dist.py
index 66f44426f..384e1d080 100644
--- a/scripts/mk_win_dist.py
+++ b/scripts/mk_win_dist.py
@@ -1,7 +1,7 @@
 ############################################
 # Copyright (c) 2012 Microsoft Corporation
-# 
-# Scripts for automatically generating 
+#
+# Scripts for automatically generating
 # Window distribution zip files.
 #
 # Author: Leonardo de Moura (leonardo)
@@ -46,7 +46,7 @@ def mk_dir(d):
 
 def set_build_dir(path):
     global BUILD_DIR, BUILD_X86_DIR, BUILD_X64_DIR
-    BUILD_DIR = path
+    BUILD_DIR = mk_util.norm_path(path)
     BUILD_X86_DIR = os.path.join(path, 'x86')
     BUILD_X64_DIR = os.path.join(path, 'x64')
     mk_dir(BUILD_X86_DIR)
@@ -74,7 +74,7 @@ def display_help():
 def parse_options():
     global FORCE_MK, JAVA_ENABLED, GIT_HASH, DOTNET_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED, X86ONLY, X64ONLY
     path = BUILD_DIR
-    options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=', 
+    options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
                                                                    'help',
                                                                    'silent',
                                                                    'force',
@@ -102,7 +102,7 @@ def parse_options():
         elif opt == '--nopython':
             PYTHON_ENABLED = False
         elif opt == '--dotnet-key':
-            DOTNET_KEY_FILE = arg            
+            DOTNET_KEY_FILE = arg
         elif opt == '--nojava':
             JAVA_ENABLED = False
         elif opt == '--githash':
@@ -139,7 +139,7 @@ def mk_build_dir(path, x64):
             opts.append('--python')
         if subprocess.call(opts) != 0:
             raise MKException("Failed to generate build directory at '%s'" % path)
-    
+
 # Create build directories
 def mk_build_dirs():
     mk_build_dir(BUILD_X86_DIR, False)
@@ -176,7 +176,7 @@ def mk_z3(x64):
     cmds = []
     if x64:
         cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" amd64')
-        cmds.append('cd %s' % BUILD_X64_DIR)    
+        cmds.append('cd %s' % BUILD_X64_DIR)
     else:
         cmds.append('call "%VCINSTALLDIR%vcvarsall.bat" x86')
         cmds.append('cd %s' % BUILD_X86_DIR)
@@ -248,12 +248,12 @@ def mk_zips():
 VS_RUNTIME_PATS = [re.compile('vcomp.*\.dll'),
                    re.compile('msvcp.*\.dll'),
                    re.compile('msvcr.*\.dll')]
-                              
+
 # Copy Visual Studio Runtime libraries
-def cp_vs_runtime(x64):    
+def cp_vs_runtime(x64):
     if x64:
         platform = "x64"
-        
+
     else:
         platform = "x86"
     vcdir = os.environ['VCINSTALLDIR']
@@ -261,7 +261,7 @@ def cp_vs_runtime(x64):
     VS_RUNTIME_FILES = []
     for root, dirs, files in os.walk(path):
         for filename in files:
-            if fnmatch(filename, '*.dll'):            
+            if fnmatch(filename, '*.dll'):
                 for pat in VS_RUNTIME_PATS:
                     if pat.match(filename):
                         fname = os.path.join(root, filename)