Skip to content

Commit 99ebbd6

Browse files
porting unix distribution script to cmake
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 28c44a6 commit 99ebbd6

File tree

1 file changed

+268
-0
lines changed

1 file changed

+268
-0
lines changed

scripts/mk_unix_dist_cmake.py

+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
############################################
2+
# Copyright (c) 2013 Microsoft Corporation
3+
#
4+
# Scripts for automatically generating
5+
# Linux/OSX/BSD distribution zip files.
6+
#
7+
# Author: Leonardo de Moura (leonardo)
8+
############################################
9+
10+
import os
11+
import subprocess
12+
import zipfile
13+
import re
14+
import getopt
15+
import sys
16+
import shutil
17+
from mk_exception import *
18+
from fnmatch import fnmatch
19+
20+
def getenv(name, default):
21+
try:
22+
return os.environ[name].strip(' "\'')
23+
except:
24+
return default
25+
26+
BUILD_DIR = 'build-dist'
27+
DIST_DIR = 'dist'
28+
VERBOSE = True
29+
FORCE_MK = False
30+
ASSEMBLY_VERSION = None
31+
DOTNET_CORE_ENABLED = True
32+
DOTNET_KEY_FILE = None
33+
JAVA_ENABLED = True
34+
JULIA_ENABLED = False
35+
GIT_HASH = False
36+
PYTHON_ENABLED = True
37+
ARM64 = False
38+
MAKEJOBS = getenv("MAKEJOBS", "24")
39+
40+
def set_verbose(flag):
41+
global VERBOSE
42+
VERBOSE = flag
43+
44+
def is_verbose():
45+
return VERBOSE
46+
47+
def mk_dir(d):
48+
if not os.path.exists(d):
49+
if is_verbose():
50+
print("Make directory", d)
51+
os.makedirs(d)
52+
53+
def get_z3_name():
54+
version = "4"
55+
if ASSEMBLY_VERSION:
56+
version = ASSEMBLY_VERSION
57+
print("Assembly version:", version)
58+
if GIT_HASH:
59+
return 'z3-%s.%s' % (version, get_git_hash())
60+
else:
61+
return 'z3-%s' % (version)
62+
63+
def get_build_dir():
64+
return BUILD_DIR
65+
66+
def get_build_dist():
67+
return os.path.join(get_build_dir(), DIST_DIR)
68+
69+
def get_build_dist_path():
70+
return os.path.join(get_build_dist(), get_z3_name())
71+
72+
def set_build_dir(path):
73+
global BUILD_DIR
74+
BUILD_DIR = os.path.expanduser(os.path.normpath(path))
75+
mk_dir(BUILD_DIR)
76+
77+
def display_help():
78+
print("mk_unix_dist_cmake.py: Z3 Unix distribution generator\n")
79+
print("This script generates the zip files containing executables, shared objects, header files for Unix.")
80+
print("It must be executed from the Z3 root directory.")
81+
print("\nOptions:")
82+
print(" -h, --help display this message.")
83+
print(" -s, --silent do not print verbose messages.")
84+
print(" -b <subdir>, --build=<subdir> subdirectory where Z3 will be built (default: build-dist).")
85+
print(" -f, --force force script to regenerate Makefiles.")
86+
print(" --version=<version> release version.")
87+
print(" --assembly-version assembly version for dll")
88+
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
89+
print(" --dotnet-key=<file> strongname sign the .NET assembly with the private key in <file>.")
90+
print(" --nojava do not include Java bindings in the binary distribution files.")
91+
print(" --nopython do not include Python bindings in the binary distribution files.")
92+
print(" --julia build Julia bindings.")
93+
print(" --githash include git hash in the Zip file.")
94+
print(" --arm64 build for ARM64 architecture.")
95+
exit(0)
96+
97+
# Parse configuration option for mk_make script
98+
def parse_options():
99+
global FORCE_MK, JAVA_ENABLED, JULIA_ENABLED, GIT_HASH, DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, ASSEMBLY_VERSION, PYTHON_ENABLED, ARM64
100+
path = BUILD_DIR
101+
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
102+
'help',
103+
'silent',
104+
'force',
105+
'nojava',
106+
'nodotnet',
107+
'dotnet-key=',
108+
'assembly-version=',
109+
'githash',
110+
'nopython',
111+
'julia',
112+
'arm64'
113+
])
114+
for opt, arg in options:
115+
if opt in ('-b', '--build'):
116+
if arg == 'src':
117+
raise MKException('The src directory should not be used to host the Makefile')
118+
path = arg
119+
elif opt in ('-s', '--silent'):
120+
set_verbose(False)
121+
elif opt in ('-h', '--help'):
122+
display_help()
123+
elif opt in ('-f', '--force'):
124+
FORCE_MK = True
125+
elif opt == '--nodotnet':
126+
DOTNET_CORE_ENABLED = False
127+
elif opt == '--assembly-version':
128+
ASSEMBLY_VERSION = arg
129+
elif opt == '--nopython':
130+
PYTHON_ENABLED = False
131+
elif opt == '--dotnet-key':
132+
DOTNET_KEY_FILE = arg
133+
elif opt == '--nojava':
134+
JAVA_ENABLED = False
135+
elif opt == '--julia':
136+
JULIA_ENABLED = True
137+
elif opt == '--githash':
138+
GIT_HASH = True
139+
elif opt == '--arm64':
140+
ARM64 = True
141+
else:
142+
raise MKException("Invalid command line option '%s'" % opt)
143+
set_build_dir(path)
144+
145+
def check_output(cmd):
146+
out = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
147+
if out != None:
148+
enc = sys.getdefaultencoding()
149+
if enc != None: return out.decode(enc).rstrip('\r\n')
150+
else: return out.rstrip('\r\n')
151+
else:
152+
return ""
153+
154+
def get_git_hash():
155+
try:
156+
branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
157+
r = check_output(['git', 'show-ref', '--abbrev=12', 'refs/heads/%s' % branch])
158+
except:
159+
raise MKException("Failed to retrieve git hash")
160+
ls = r.split(' ')
161+
if len(ls) != 2:
162+
raise MKException("Unexpected git output " + r)
163+
return ls[0]
164+
165+
# Create a build directory using CMake
166+
def mk_build_dir():
167+
build_path = get_build_dir()
168+
if not os.path.exists(build_path) or FORCE_MK:
169+
mk_dir(build_path)
170+
cmds = []
171+
cmds.append(f"cd {build_path}")
172+
cmd = []
173+
cmd.append("cmake -S .")
174+
if DOTNET_CORE_ENABLED:
175+
cmd.append(' -DZ3_BUILD_DOTNET_BINDINGS=ON')
176+
if JAVA_ENABLED:
177+
cmd.append(' -DZ3_BUILD_JAVA_BINDINGS=ON')
178+
cmd.append(' -DZ3_INSTALL_JAVA_BINDINGS=ON')
179+
cmd.append(' -DZ3_JAVA_JAR_INSTALLDIR=java')
180+
cmd.append(' -DZ3_JAVA_JNI_LIB_INSTALLDIR=bin/java')
181+
if PYTHON_ENABLED:
182+
cmd.append(' -DZ3_BUILD_PYTHON_BINDINGS=ON')
183+
cmd.append(' -DZ3_INSTALL_PYTHON_BINDINGS=ON')
184+
cmd.append(' -DCMAKE_INSTALL_PYTHON_PKG_DIR=bin/python')
185+
if JULIA_ENABLED:
186+
cmd.append(' -DZ3_BUILD_JULIA_BINDINGS=ON')
187+
cmd.append(' -DZ3_INSTALL_JULIA_BINDINGS=ON')
188+
if GIT_HASH:
189+
git_hash = get_git_hash()
190+
cmd.append(' -DGIT_HASH=' + git_hash)
191+
cmd.append(' -DZ3_USE_LIB_GMP=OFF')
192+
cmd.append(' -DZ3_BUILD_LIBZ3_SHARED=ON')
193+
cmd.append(' -DCMAKE_BUILD_TYPE=RelWithDebInfo')
194+
cmd.append(' -DCMAKE_INSTALL_PREFIX=' + get_build_dist_path())
195+
cmd.append(' -G "Ninja"')
196+
cmd.append(' ..\n')
197+
cmds.append("".join(cmd))
198+
print("CMAKE commands:", cmds)
199+
sys.stdout.flush()
200+
if exec_cmds(cmds) != 0:
201+
raise MKException("failed to run commands")
202+
203+
def exec_cmds(cmds):
204+
cmd_file = 'z3_tmp.sh'
205+
f = open(cmd_file, 'w')
206+
for cmd in cmds:
207+
f.write(cmd)
208+
f.write('\n')
209+
f.close()
210+
res = 0
211+
try:
212+
res = subprocess.call(['sh', cmd_file])
213+
except:
214+
res = 1
215+
try:
216+
os.remove(cmd_file)
217+
except:
218+
pass
219+
return res
220+
221+
def build_z3():
222+
if is_verbose():
223+
print("build z3")
224+
build_dir = get_build_dir()
225+
cmds = []
226+
cmds.append('cd %s' % build_dir)
227+
cmds.append('ninja install')
228+
if exec_cmds(cmds) != 0:
229+
raise MKException("Failed to make z3")
230+
231+
def mk_zip():
232+
build_dist = get_build_dist_path()
233+
dist_name = get_z3_name()
234+
old = os.getcwd()
235+
try:
236+
if is_verbose():
237+
print("dist path", build_dist)
238+
mk_dir(build_dist)
239+
zfname = '%s.zip' % dist_name
240+
zipout = zipfile.ZipFile(zfname, 'w', zipfile.ZIP_DEFLATED)
241+
os.chdir(get_build_dist())
242+
for root, dirs, files in os.walk("."):
243+
for f in files:
244+
if is_verbose():
245+
print("adding ", os.path.join(root, f))
246+
zipout.write(os.path.join(root, f))
247+
if is_verbose():
248+
print("Generated '%s'" % zfname)
249+
except:
250+
pass
251+
os.chdir(old)
252+
253+
def cp_license():
254+
if is_verbose():
255+
print("copy licence")
256+
path = get_build_dist_path()
257+
mk_dir(path)
258+
shutil.copy("LICENSE.txt", path)
259+
260+
# Entry point
261+
def main():
262+
parse_options()
263+
mk_build_dir()
264+
build_z3()
265+
cp_license()
266+
mk_zip()
267+
268+
main()

0 commit comments

Comments
 (0)