3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

resolved merge conflicts

This commit is contained in:
Christoph M. Wintersteiger 2016-03-07 14:20:10 +00:00
commit 027331aef2
134 changed files with 4579 additions and 651 deletions

47
scripts/mk_consts_files.py Executable file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
"""
Reads a list of Z3 API header files and
generate the constant declarations need
by one or more Z3 language bindings
"""
import mk_util
import argparse
import logging
import os
import sys
def check_dir(output_dir):
if not os.path.isdir(output_dir):
logging.error('"{}" is not an existing directory'.format(output_dir))
return 1
return 0
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("api_files", nargs="+")
parser.add_argument("--z3py-output-dir", dest="z3py_output_dir", default=None)
pargs = parser.parse_args(args)
for api_file in pargs.api_files:
if not os.path.exists(api_file):
logging.error('"{}" does not exist'.format(api_file))
return 1
count = 0
if pargs.z3py_output_dir:
if check_dir(pargs.z3py_output_dir) != 0:
return 1
mk_util.mk_z3consts_py_internal(pargs.api_files, pargs.z3py_output_dir)
count += 1
if count == 0:
logging.info('No files generated. You need to specific an output directory'
' for the relevant langauge bindings')
# TODO: Add support for other bindings
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

36
scripts/mk_def_file.py Executable file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env python
"""
Reads a list of Z3 API header files and
generate a ``.def`` file to define the
exported symbols of a dll. This file
can be passed to the ``/DEF`` to the
linker used by MSVC.
"""
import mk_util
import argparse
import logging
import os
import sys
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("output_file", help="output def file path")
parser.add_argument("dllname", help="dllname to use in def file")
parser.add_argument("api_files", nargs="+")
pargs = parser.parse_args(args)
for api_file in pargs.api_files:
if not os.path.exists(api_file):
logging.error('"{}" does not exist'.format(api_file))
return 1
mk_util.mk_def_file_internal(
pargs.output_file,
pargs.dllname,
pargs.api_files)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
"""
Determines the available global parameters
in header files in the list of source directions
and generates a ``gparams_register_modules.cpp`` file in
the destination directory that defines a function
``void gparams_register_modules()``.
"""
import mk_util
import argparse
import logging
import os
import sys
def check_dir(path):
if not os.path.exists(path):
logging.error('"{}" does not exist'.format(path))
return 1
if not os.path.isdir(path):
logging.error('"{}" is not a directory'.format(path))
return 1
return 0
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
pargs = parser.parse_args(args)
if check_dir(pargs.destination_dir) != 0:
return 1
for source_dir in pargs.source_dirs:
if check_dir(source_dir) != 0:
return 1
mk_util.mk_gparams_register_modules_internal(pargs.source_dirs, pargs.destination_dir)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
"""
Determines the available tactics
in header files in the list of source directions
and generates a ``install_tactic.cpp`` file in
the destination directory that defines a function
``void install_tactics(tactic_manager& ctx)``.
"""
import mk_util
import argparse
import logging
import os
import sys
def check_dir(path):
if not os.path.exists(path):
logging.error('"{}" does not exist'.format(path))
return 1
if not os.path.isdir(path):
logging.error('"{}" is not a directory'.format(path))
return 1
return 0
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
pargs = parser.parse_args(args)
if check_dir(pargs.destination_dir) != 0:
return 1
for source_dir in pargs.source_dirs:
if check_dir(source_dir) != 0:
return 1
mk_util.mk_install_tactic_cpp_internal(pargs.source_dirs, pargs.destination_dir)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View file

@ -0,0 +1,48 @@
#!/usr/bin/env python
"""
Scans the source directories for
memory initializers and finalizers and
emits and implementation of
``void mem_initialize()`` and
``void mem_finalize()`` into ``mem_initializer.cpp``
in the destination directory.
"""
import mk_util
import argparse
import logging
import os
import sys
def check_dir(path):
if not os.path.exists(path):
logging.error('"{}" does not exist'.format(path))
return 1
if not os.path.isdir(path):
logging.error('"{}" is not a directory'.format(path))
return 1
return 0
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("destination_dir", help="destination directory")
parser.add_argument("source_dirs", nargs="+",
help="One or more source directories to search")
pargs = parser.parse_args(args)
if check_dir(pargs.destination_dir) != 0:
return 1
for source_dir in pargs.source_dirs:
if check_dir(source_dir) != 0:
return 1
mk_util.mk_mem_initializer_cpp_internal(pargs.source_dirs, pargs.destination_dir)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

34
scripts/mk_pat_db.py Executable file
View file

@ -0,0 +1,34 @@
#!/usr/bin/env python
"""
Reads a pattern database and generates the corresponding
header file.
"""
import mk_util
import argparse
import logging
import os
import sys
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("db_file", help="pattern database file")
parser.add_argument("output_file", help="output header file path")
pargs = parser.parse_args(args)
if not os.path.exists(pargs.db_file):
logging.error('"{}" does not exist'.format(pargs.db_file))
return 1
if (os.path.exists(pargs.output_file) and
not os.path.isfile(pargs.output_file)):
logging.error('Refusing to overwrite "{}"'.format(
pargs.output_file))
return 1
mk_util.mk_pat_db_internal(pargs.db_file, pargs.output_file)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View file

@ -65,6 +65,7 @@ def parse_options():
'silent',
'force',
'nojava',
'nodotnet',
'githash'
])
for opt, arg in options:
@ -95,7 +96,7 @@ def check_build_dir(path):
# Create a build directory using mk_make.py
def mk_build_dir(path):
if not check_build_dir(path) or FORCE_MK:
opts = ["python", os.path.join('scripts', 'mk_make.py'), "-b", path, "--static"]
opts = ["python", os.path.join('scripts', 'mk_make.py'), "-b", path, "--staticlib"]
if DOTNET_ENABLED:
opts.append('--dotnet')
if JAVA_ENABLED:

View file

@ -83,6 +83,7 @@ JAVA_ENABLED=False
ML_ENABLED=False
PYTHON_INSTALL_ENABLED=False
STATIC_LIB=False
STATIC_BIN=False
VER_MAJOR=None
VER_MINOR=None
VER_BUILD=None
@ -536,6 +537,9 @@ def get_version():
def build_static_lib():
return STATIC_LIB
def build_static_bin():
return STATIC_BIN
def is_cr_lf(fname):
# Check whether text files use cr/lf
f = open(fname, 'r')
@ -622,6 +626,7 @@ def display_help(exit_code):
print(" --ml generate OCaml bindings.")
print(" --python generate Python bindings.")
print(" --staticlib build Z3 static library.")
print(" --staticbin build a statically linked Z3 binary.")
if not IS_WINDOWS:
print(" -g, --gmp use GMP.")
print(" --gprof enable gprof")
@ -652,14 +657,14 @@ def display_help(exit_code):
# Parse configuration option for mk_make script
def parse_options():
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
global DOTNET_ENABLED, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, PYTHON_INSTALL_ENABLED
global DOTNET_ENABLED, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, PYTHON_INSTALL_ENABLED
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP
try:
options, remainder = getopt.gnu_getopt(sys.argv[1:],
'b:df:sxhmcvtnp:gj',
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj',
'trace', 'dotnet', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof',
'githash=', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python'])
'githash=', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin'])
except:
print("ERROR: Invalid command line option")
display_help(1)
@ -694,6 +699,8 @@ def parse_options():
DOTNET_ENABLED = True
elif opt in ('--staticlib'):
STATIC_LIB = True
elif opt in ('--staticbin'):
STATIC_BIN = True
elif opt in ('--optimize'):
SLOW_OPTIMIZE = True
elif not IS_WINDOWS and opt in ('-p', '--prefix'):
@ -2212,14 +2219,19 @@ def mk_config():
extra_opt = ' -D_NO_OMP_'
if GIT_HASH:
extra_opt = ' %s /D Z3GITHASH=%s' % (extra_opt, GIT_HASH)
if STATIC_BIN:
static_opt = '/MT'
else:
static_opt = '/MD'
if DEBUG_MODE:
static_opt = static_opt + 'd'
config.write(
'AR_FLAGS=/nologo\n'
'LINK_FLAGS=/nologo /MDd\n'
'SLINK_FLAGS=/nologo /LDd\n')
'LINK_FLAGS=/nologo %s\n'
'SLINK_FLAGS=/nologo /LDd\n' % static_opt)
if VS_X64:
config.write(
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze-\n' % extra_opt)
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _AMD64_ /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- %s %s\n' % (extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
@ -2228,7 +2240,7 @@ def mk_config():
exit(1)
else:
config.write(
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG %s /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % extra_opt)
'CXXFLAGS=/c /Zi /nologo /W3 /WX- /Od /Oy- /D WIN32 /D _DEBUG /D Z3DEBUG /D _CONSOLE /D _TRACE /D _WINDOWS /Gm- /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2 %s %s\n' % (extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n')
@ -2237,15 +2249,14 @@ def mk_config():
LTCG=' /LTCG' if SLOW_OPTIMIZE else ''
GL = ' /GL' if SLOW_OPTIMIZE else ''
config.write(
'AR_FLAGS=/nologo%s\n'
'LINK_FLAGS=/nologo /MD\n'
'SLINK_FLAGS=/nologo /LD\n'
% LTCG)
'AR_FLAGS=/nologo %s\n'
'LINK_FLAGS=/nologo %s\n'
'SLINK_FLAGS=/nologo /LD\n' % (LTCG, static_opt))
if TRACE:
extra_opt = '%s /D _TRACE ' % extra_opt
if VS_X64:
config.write(
'CXXFLAGS=/c%s /Zi /nologo /W3 /WX- /O2 /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _LIB /D _WINDOWS /D _AMD64_ /D _UNICODE /D UNICODE /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP\n' % (GL, extra_opt))
'CXXFLAGS=/c%s /Zi /nologo /W3 /WX- /O2 /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _LIB /D _WINDOWS /D _AMD64_ /D _UNICODE /D UNICODE /Gm- /EHsc /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP %s %s\n' % (GL, extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608\n'
'SLINK_EXTRA_FLAGS=/link%s /MACHINE:X64 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608\n' % (LTCG, LTCG))
@ -2254,7 +2265,7 @@ def mk_config():
exit(1)
else:
config.write(
'CXXFLAGS=/nologo /c%s /Zi /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG %s /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2\n' % (GL, extra_opt))
'CXXFLAGS=/nologo /c%s /Zi /W3 /WX- /O2 /Oy- /D _EXTERNAL_RELEASE /D WIN32 /D NDEBUG /D _CONSOLE /D _WINDOWS /D ASYNC_COMMANDS /Gm- /EHsc /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /analyze- /arch:SSE2 %s %s\n' % (GL, extra_opt, static_opt))
config.write(
'LINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:CONSOLE /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE /NXCOMPAT\n'
'SLINK_EXTRA_FLAGS=/link%s /DEBUG /MACHINE:X86 /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /STACK:8388608 /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE:NO\n' % (LTCG, LTCG))
@ -2363,7 +2374,9 @@ def mk_config():
LDFLAGS = '%s -m32' % LDFLAGS
SLIBFLAGS = '%s -m32' % SLIBFLAGS
if DEBUG_MODE:
CPPFLAGS = '%s -DZ3DEBUG' % CPPFLAGS
CPPFLAGS = '%s -DZ3DEBUG -D_DEBUG' % CPPFLAGS
else:
CPPFLAGS = '%s -DNDEBUG -D_EXTERNAL_RELEASE' % CPPFLAGS
if TRACE or DEBUG_MODE:
CPPFLAGS = '%s -D_TRACE' % CPPFLAGS
config.write('PREFIX=%s\n' % PREFIX)
@ -2379,7 +2392,10 @@ def mk_config():
config.write('AR_OUTFLAG=\n')
config.write('EXE_EXT=\n')
config.write('LINK=%s\n' % CXX)
config.write('LINK_FLAGS=\n')
if STATIC_BIN:
config.write('LINK_FLAGS=-static\n')
else:
config.write('LINK_FLAGS=\n')
config.write('LINK_OUT_FLAG=-o \n')
config.write('LINK_EXTRA_FLAGS=-lpthread %s\n' % LDFLAGS)
config.write('SO_EXT=%s\n' % SO_EXT)
@ -2511,10 +2527,10 @@ DOUBLE = 2
STRING = 3
SYMBOL = 4
UINT_MAX = 4294967295
CURR_PYG = None
CURRENT_PYG_HPP_DEST_DIR = None
def get_curr_pyg():
return CURR_PYG
def get_current_pyg_hpp_dest_dir():
return CURRENT_PYG_HPP_DEST_DIR
TYPE2CPK = { UINT : 'CPK_UINT', BOOL : 'CPK_BOOL', DOUBLE : 'CPK_DOUBLE', STRING : 'CPK_STRING', SYMBOL : 'CPK_SYMBOL' }
TYPE2CTYPE = { UINT : 'unsigned', BOOL : 'bool', DOUBLE : 'double', STRING : 'char const *', SYMBOL : 'symbol' }
@ -2547,8 +2563,8 @@ def to_c_method(s):
return s.replace('.', '_')
def def_module_params(module_name, export, params, class_name=None, description=None):
pyg = get_curr_pyg()
dirname = os.path.split(get_curr_pyg())[0]
dirname = get_current_pyg_hpp_dest_dir()
assert(os.path.exists(dirname))
if class_name is None:
class_name = '%s_params' % module_name
hpp = os.path.join(dirname, '%s.hpp' % class_name)
@ -2613,28 +2629,31 @@ def _execfile(file, globals=globals(), locals=locals()):
# Execute python auxiliary scripts that generate extra code for Z3.
def exec_pyg_scripts():
global CURR_PYG
global CURRENT_PYG_HPP_DEST_DIR
for root, dirs, files in os.walk('src'):
for f in files:
if f.endswith('.pyg'):
script = os.path.join(root, f)
CURR_PYG = script
CURRENT_PYG_HPP_DEST_DIR = root
_execfile(script, PYG_GLOBALS)
# TODO: delete after src/ast/pattern/expr_pattern_match
# database.smt ==> database.h
def mk_pat_db():
c = get_component(PATTERN_COMPONENT)
fin = open(os.path.join(c.src_dir, 'database.smt2'), 'r')
fout = open(os.path.join(c.src_dir, 'database.h'), 'w')
fout.write('static char const g_pattern_database[] =\n')
for line in fin:
fout.write('"%s\\n"\n' % line.strip('\n'))
fout.write(';\n')
fin.close()
fout.close()
fin = os.path.join(c.src_dir, 'database.smt2')
fout = os.path.join(c.src_dir, 'database.h')
mk_pat_db_internal(fin, fout)
def mk_pat_db_internal(inputFilePath, outputFilePath):
with open(inputFilePath, 'r') as fin:
with open(outputFilePath, 'w') as fout:
fout.write('static char const g_pattern_database[] =\n')
for line in fin:
fout.write('"%s\\n"\n' % line.strip('\n'))
fout.write(';\n')
if VERBOSE:
print("Generated '%s'" % os.path.join(c.src_dir, 'database.h'))
print("Generated '%s'" % outputFilePath)
# Update version numbers
def update_version():
@ -2652,15 +2671,20 @@ def update_version():
# Update files with the version number
def mk_version_dot_h(major, minor, build, revision):
c = get_component(UTIL_COMPONENT)
fout = open(os.path.join(c.src_dir, 'version.h'), 'w')
fout.write('// automatically generated file.\n')
fout.write('#define Z3_MAJOR_VERSION %s\n' % major)
fout.write('#define Z3_MINOR_VERSION %s\n' % minor)
fout.write('#define Z3_BUILD_NUMBER %s\n' % build)
fout.write('#define Z3_REVISION_NUMBER %s\n' % revision)
fout.close()
version_template = os.path.join(c.src_dir, 'version.h.in')
version_header_output = os.path.join(c.src_dir, 'version.h')
# Note the substitution names are what is used by the CMake
# builds system. If you change these you should change them
# in the CMake build too
configure_file(version_template, version_header_output,
{ 'Z3_VERSION_MAJOR': str(major),
'Z3_VERSION_MINOR': str(minor),
'Z3_VERSION_PATCH': str(build),
'Z3_VERSION_TWEAK': str(revision),
}
)
if VERBOSE:
print("Generated '%s'" % os.path.join(c.src_dir, 'version.h'))
print("Generated '%s'" % version_header_output)
# Generate AssemblyInfo.cs files with the right version numbers by using ``AssemblyInfo.cs.in`` files as a template
def mk_all_assembly_infos(major, minor, build, revision):
@ -2697,6 +2721,13 @@ def ADD_PROBE(name, descr, cmd):
# It installs all tactics in the given component (name) list cnames
# The procedure looks for ADD_TACTIC commands in the .h files of these components.
def mk_install_tactic_cpp(cnames, path):
component_src_dirs = []
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
mk_install_tactic_cpp_internal(component_src_dirs, path)
def mk_install_tactic_cpp_internal(component_src_dirs, path):
global ADD_TACTIC_DATA, ADD_PROBE_DATA
ADD_TACTIC_DATA = []
ADD_PROBE_DATA = []
@ -2708,12 +2739,11 @@ def mk_install_tactic_cpp(cnames, path):
fout.write('#include"cmd_context.h"\n')
tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)')
probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)')
for cname in cnames:
c = get_component(cname)
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir))
for component_src_dir in component_src_dirs:
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
for h_file in h_files:
added_include = False
fin = open(os.path.join(c.src_dir, h_file), 'r')
fin = open(os.path.join(component_src_dir, h_file), 'r')
for line in fin:
if tactic_pat.match(line):
if not added_include:
@ -2766,6 +2796,13 @@ def mk_all_install_tactic_cpps():
# void mem_finalize()
# These procedures are invoked by the Z3 memory_manager
def mk_mem_initializer_cpp(cnames, path):
component_src_dirs = []
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
mk_mem_initializer_cpp_internal(component_src_dirs, path)
def mk_mem_initializer_cpp_internal(component_src_dirs, path):
initializer_cmds = []
finalizer_cmds = []
fullname = os.path.join(path, 'mem_initializer.cpp')
@ -2775,12 +2812,11 @@ def mk_mem_initializer_cpp(cnames, path):
# ADD_INITIALIZER with priority
initializer_prio_pat = re.compile('[ \t]*ADD_INITIALIZER\(\'([^\']*)\',[ \t]*(-?[0-9]*)\)')
finalizer_pat = re.compile('[ \t]*ADD_FINALIZER\(\'([^\']*)\'\)')
for cname in cnames:
c = get_component(cname)
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir))
for component_src_dir in component_src_dirs:
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
for h_file in h_files:
added_include = False
fin = open(os.path.join(c.src_dir, h_file), 'r')
fin = open(os.path.join(component_src_dir, h_file), 'r')
for line in fin:
m = initializer_pat.match(line)
if m:
@ -2825,11 +2861,18 @@ def mk_all_mem_initializer_cpps():
cnames.append(c.name)
mk_mem_initializer_cpp(cnames, c.src_dir)
# Generate an mem_initializer.cpp at path.
# Generate an ``gparams_register_modules.cpp`` at path.
# This file implements the procedure
# void gparams_register_modules()
# This procedure is invoked by gparams::init()
def mk_gparams_register_modules(cnames, path):
component_src_dirs = []
for cname in cnames:
c = get_component(cname)
component_src_dirs.append(c.src_dir)
mk_gparams_register_modules_internal(component_src_dirs, path)
def mk_gparams_register_modules_internal(component_src_dirs, path):
cmds = []
mod_cmds = []
mod_descrs = []
@ -2840,12 +2883,11 @@ def mk_gparams_register_modules(cnames, path):
reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)')
reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)')
reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)')
for cname in cnames:
c = get_component(cname)
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir))
for component_src_dir in component_src_dirs:
h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(component_src_dir))
for h_file in h_files:
added_include = False
fin = open(os.path.join(c.src_dir, h_file), 'r')
fin = open(os.path.join(component_src_dir, h_file), 'r')
for line in fin:
m = reg_pat.match(line)
if m:
@ -2886,14 +2928,22 @@ def mk_all_gparams_register_modules():
# Generate a .def based on the files at c.export_files slot.
def mk_def_file(c):
pat1 = re.compile(".*Z3_API.*")
defname = '%s.def' % os.path.join(c.src_dir, c.name)
fout = open(defname, 'w')
fout.write('LIBRARY "%s"\nEXPORTS\n' % c.dll_name)
num = 1
dll_name = c.dll_name
export_header_files = []
for dot_h in c.export_files:
dot_h_c = c.find_file(dot_h, c.name)
api = open(os.path.join(dot_h_c.src_dir, dot_h), 'r')
api = os.path.join(dot_h_c.src_dir, dot_h)
export_header_files.append(api)
mk_def_file_internal(defname, dll_name, export_header_files)
def mk_def_file_internal(defname, dll_name, export_header_files):
pat1 = re.compile(".*Z3_API.*")
fout = open(defname, 'w')
fout.write('LIBRARY "%s"\nEXPORTS\n' % dll_name)
num = 1
for export_header_file in export_header_files:
api = open(export_header_file, 'r')
for line in api:
m = pat1.match(line)
if m:
@ -2959,7 +3009,28 @@ def mk_bindings(api_files):
if is_java_enabled():
check_java()
mk_z3consts_java(api_files)
_execfile(os.path.join('scripts', 'update_api.py'), g) # HACK
# Generate some of the bindings and "api" module files
import update_api
dotnet_output_dir = None
if is_dotnet_enabled():
dotnet_output_dir = get_component('dotnet').src_dir
java_output_dir = None
java_package_name = None
if is_java_enabled():
java_output_dir = get_component('java').src_dir
java_package_name = get_component('java').package_name
ml_output_dir = None
if is_ml_enabled():
ml_output_dir = get_component('ml').src_dir
# Get the update_api module to do the work for us
update_api.generate_files(api_files=new_api_files,
api_output_dir=get_component('api').src_dir,
z3py_output_dir=get_z3py_dir(),
dotnet_output_dir=dotnet_output_dir,
java_output_dir=java_output_dir,
java_package_name=java_package_name,
ml_output_dir=ml_output_dir
)
cp_z3py_to_build()
if is_ml_enabled():
check_ml()
@ -2972,6 +3043,17 @@ def mk_bindings(api_files):
def mk_z3consts_py(api_files):
if Z3PY_SRC_DIR is None:
raise MKException("You must invoke set_z3py_dir(path):")
full_path_api_files = []
api_dll = get_component(Z3_DLL_COMPONENT)
for api_file in api_files:
api_file_c = api_dll.find_file(api_file, api_dll.name)
api_file = os.path.join(api_file_c.src_dir, api_file)
full_path_api_files.append(api_file)
mk_z3consts_py_internal(full_path_api_files, Z3PY_SRC_DIR)
def mk_z3consts_py_internal(api_files, output_dir):
assert os.path.isdir(output_dir)
assert isinstance(api_files, list)
blank_pat = re.compile("^ *\r?$")
comment_pat = re.compile("^ *//.*$")
@ -2980,14 +3062,9 @@ def mk_z3consts_py(api_files):
openbrace_pat = re.compile("{ *")
closebrace_pat = re.compile("}.*;")
z3consts = open(os.path.join(Z3PY_SRC_DIR, 'z3consts.py'), 'w')
z3consts = open(os.path.join(output_dir, 'z3consts.py'), 'w')
z3consts.write('# Automatically generated file\n\n')
api_dll = get_component(Z3_DLL_COMPONENT)
for api_file in api_files:
api_file_c = api_dll.find_file(api_file, api_dll.name)
api_file = os.path.join(api_file_c.src_dir, api_file)
api = open(api_file, 'r')
SEARCHING = 0
@ -3048,7 +3125,7 @@ def mk_z3consts_py(api_files):
api.close()
z3consts.close()
if VERBOSE:
print("Generated '%s'" % os.path.join(Z3PY_SRC_DIR, 'z3consts.py'))
print("Generated '%s'" % os.path.join(output_dir, 'z3consts.py'))
# Extract enumeration types from z3_api.h, and add .Net definitions
@ -3480,7 +3557,7 @@ def mk_vs_proj_cl_compile(f, name, components, debug):
if debug:
f.write(' <PreprocessorDefinitions>WIN32;_DEBUG;Z3DEBUG;_TRACE;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n')
else:
f.write(' <PreprocessorDefinitions>WIN32;_NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n')
f.write(' <PreprocessorDefinitions>WIN32;NDEBUG;_MP_INTERNAL;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n')
if VS_PAR:
f.write(' <MinimalRebuild>false</MinimalRebuild>\n')
f.write(' <MultiProcessorCompilation>true</MultiProcessorCompilation>\n')

42
scripts/pyg2hpp.py Executable file
View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
"""
Reads a pyg file and emits the corresponding
C++ header file into the specified destination
directory.
"""
import mk_util
import argparse
import logging
import os
import sys
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("pyg_file", help="pyg file")
parser.add_argument("destination_dir", help="destination directory")
pargs = parser.parse_args(args)
if not os.path.exists(pargs.pyg_file):
logging.error('"{}" does not exist'.format(pargs.pyg_file))
return 1
if not os.path.exists(pargs.destination_dir):
logging.error('"{}" does not exist'.format(pargs.destination_dir))
return 1
if not os.path.isdir(pargs.destination_dir):
logging.error('"{}" is not a directory'.format(pargs.destination_dir))
return 1
pyg_full_path = os.path.abspath(pargs.pyg_file)
destination_dir_full_path = os.path.abspath(pargs.destination_dir)
logging.info('Using {}'.format(pyg_full_path))
# Use the existing infrastructure to do this
mk_util.CURRENT_PYG_HPP_DEST_DIR = destination_dir_full_path
mk_util._execfile(pyg_full_path, mk_util.PYG_GLOBALS)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

375
scripts/update_api.py Normal file → Executable file
View file

@ -1,113 +1,36 @@
#!/usr/bin/env python
############################################
# Copyright (c) 2012 Microsoft Corporation
#
# Scripts for generating Makefiles and Visual
#
# Scripts for generating Makefiles and Visual
# Studio project files.
#
# Author: Leonardo de Moura (leonardo)
############################################
from mk_util import *
from mk_exception import *
"""
This script generates the ``api_log_macros.h``,
``api_log_macros.cpp`` and ``api_commands.cpp``
files for the "api" module based on parsing
several API header files. It can also optionally
emit some of the files required for Z3's different
language bindings.
"""
import mk_util
import mk_exception
import argparse
import logging
import re
import os
import sys
##########################################################
# TODO: rewrite this file without using global variables.
# This file is a big HACK.
# It started as small simple script.
# Now, it is too big, and is invoked from mk_make.py
# The communication uses
#
##########################################################
#
# Generate logging support and bindings
#
api_dir = get_component('api').src_dir
dotnet_dir = get_component('dotnet').src_dir
log_h = open(os.path.join(api_dir, 'api_log_macros.h'), 'w')
log_c = open(os.path.join(api_dir, 'api_log_macros.cpp'), 'w')
exe_c = open(os.path.join(api_dir, 'api_commands.cpp'), 'w')
core_py = open(os.path.join(get_z3py_dir(), 'z3core.py'), 'w')
dotnet_fileout = os.path.join(dotnet_dir, 'Native.cs')
##
log_h.write('// Automatically generated file\n')
log_h.write('#include\"z3.h\"\n')
log_h.write('#ifdef __GNUC__\n')
log_h.write('#define _Z3_UNUSED __attribute__((unused))\n')
log_h.write('#else\n')
log_h.write('#define _Z3_UNUSED\n')
log_h.write('#endif\n')
##
log_c.write('// Automatically generated file\n')
log_c.write('#include<iostream>\n')
log_c.write('#include\"z3.h\"\n')
log_c.write('#include\"api_log_macros.h\"\n')
log_c.write('#include\"z3_logger.h\"\n')
##
exe_c.write('// Automatically generated file\n')
exe_c.write('#include\"z3.h\"\n')
exe_c.write('#include\"z3_replayer.h\"\n')
##
log_h.write('extern std::ostream * g_z3_log;\n')
log_h.write('extern bool g_z3_log_enabled;\n')
log_h.write('class z3_log_ctx { bool m_prev; public: z3_log_ctx():m_prev(g_z3_log_enabled) { g_z3_log_enabled = false; } ~z3_log_ctx() { g_z3_log_enabled = m_prev; } bool enabled() const { return m_prev; } };\n')
log_h.write('inline void SetR(void * obj) { *g_z3_log << "= " << obj << "\\n"; }\ninline void SetO(void * obj, unsigned pos) { *g_z3_log << "* " << obj << " " << pos << "\\n"; } \ninline void SetAO(void * obj, unsigned pos, unsigned idx) { *g_z3_log << "@ " << obj << " " << pos << " " << idx << "\\n"; }\n')
log_h.write('#define RETURN_Z3(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); } return Z3RES\n')
log_h.write('void _Z3_append_log(char const * msg);\n')
##
exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n')
##
core_py.write('# Automatically generated file\n')
core_py.write('import sys, os\n')
core_py.write('import ctypes\n')
core_py.write('from z3types import *\n')
core_py.write('from z3consts import *\n')
core_py.write("""
_lib = None
def lib():
global _lib
if _lib == None:
_dir = os.path.dirname(os.path.abspath(__file__))
for ext in ['dll', 'so', 'dylib']:
try:
init('libz3.%s' % ext)
break
except:
pass
try:
init(os.path.join(_dir, 'libz3.%s' % ext))
break
except:
pass
if _lib == None:
raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python")
return _lib
def _to_ascii(s):
if isinstance(s, str):
return s.encode('ascii')
else:
return s
if sys.version < '3':
def _to_pystr(s):
return s
else:
def _to_pystr(s):
if s != None:
enc = sys.stdout.encoding
if enc != None: return s.decode(enc)
else: return s.decode('ascii')
else:
return ""
def init(PATH):
global _lib
_lib = ctypes.CDLL(PATH)
""")
IN = 0
OUT = 1
INOUT = 2
@ -176,10 +99,9 @@ def def_Type(var, c_type, py_type):
Type2PyStr[next_type_id] = py_type
next_type_id = next_type_id + 1
def def_Types():
import re
def def_Types(api_files):
pat1 = re.compile(" *def_Type\(\'(.*)\',[^\']*\'(.*)\',[^\']*\'(.*)\'\)[ \t]*")
for api_file in API_FILES:
for api_file in api_files:
api = open(api_file, 'r')
for line in api:
m = pat1.match(line)
@ -422,10 +344,8 @@ def reg_dotnet(name, result, params):
global _dotnet_decls
_dotnet_decls.append((name, result, params))
def mk_dotnet():
def mk_dotnet(dotnet):
global Type2Str
global dotnet_fileout
dotnet = open(dotnet_fileout, 'w')
dotnet.write('// Automatically generated file\n')
dotnet.write('using System;\n')
dotnet.write('using System.Collections.Generic;\n')
@ -472,10 +392,8 @@ def mk_dotnet():
NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc', 'Z3_mk_interpolation_context' ]
Unwrapped = [ 'Z3_del_context', 'Z3_get_error_code' ]
def mk_dotnet_wrappers():
def mk_dotnet_wrappers(dotnet):
global Type2Str
global dotnet_fileout
dotnet = open(dotnet_fileout, 'a')
dotnet.write("\n")
dotnet.write(" public static void Z3_set_error_handler(Z3_context a0, Z3_error_handler a1) {\n")
dotnet.write(" LIB.Z3_set_error_handler(a0, a1);\n")
@ -560,16 +478,13 @@ def java_array_element_type(p):
else:
return 'jlong'
def mk_java():
if not is_java_enabled():
return
java_dir = get_component('java').src_dir
def mk_java(java_dir, package_name):
java_nativef = os.path.join(java_dir, 'Native.java')
java_wrapperf = os.path.join(java_dir, 'Native.cpp')
java_native = open(java_nativef, 'w')
java_native.write('// Automatically generated file\n')
java_native.write('package %s;\n' % get_component('java').package_name)
java_native.write('import %s.enumerations.*;\n' % get_component('java').package_name)
java_native.write('package %s;\n' % package_name)
java_native.write('import %s.enumerations.*;\n' % package_name)
java_native.write('public final class Native {\n')
java_native.write(' public static class IntPtr { public int value; }\n')
java_native.write(' public static class LongPtr { public long value; }\n')
@ -642,7 +557,7 @@ def mk_java():
java_native.write(' }\n\n')
java_native.write('}\n')
java_wrapper = open(java_wrapperf, 'w')
pkg_str = get_component('java').package_name.replace('.', '_')
pkg_str = package_name.replace('.', '_')
java_wrapper.write('// Automatically generated file\n')
java_wrapper.write('#ifdef _CYGWIN\n')
java_wrapper.write('typedef long long __int64;\n')
@ -805,7 +720,7 @@ def mk_java():
java_wrapper.write('#ifdef __cplusplus\n')
java_wrapper.write('}\n')
java_wrapper.write('#endif\n')
if is_verbose():
if mk_util.is_verbose():
print("Generated '%s'" % java_nativef)
def mk_log_header(file, name, params):
@ -1080,7 +995,7 @@ def def_API(name, result, params):
mk_log_result_macro(log_h, name, result, params)
next_id = next_id + 1
def mk_bindings():
def mk_bindings(exe_c):
exe_c.write("void register_z3_replayer_cmds(z3_replayer & in) {\n")
for key, val in API2Id.items():
exe_c.write(" in.register_cmd(%s, exec_%s, \"%s\");\n" % (key, val, val))
@ -1271,7 +1186,8 @@ def ml_set_wrap(t, d, n):
pts = ml_plus_type(type2str(t))
return '*(' + pts + '*)Data_custom_val(' + d + ') = ' + n + ';'
def mk_z3native_ml(ml_dir):
def mk_ml(ml_dir):
global Type2Str
ml_nativef = os.path.join(ml_dir, 'z3native.ml')
ml_native = open(ml_nativef, 'w')
ml_native.write('(* Automatically generated file *)\n\n')
@ -1574,24 +1490,15 @@ def mk_z3native_stubs_c(ml_dir): # C interface
ml_wrapper.write('#ifdef __cplusplus\n')
ml_wrapper.write('}\n')
ml_wrapper.write('#endif\n')
if is_verbose():
print ('Generated "%s"' % ml_wrapperf)
def mk_ml():
global Type2Str
if not is_ml_enabled():
return
ml_dir = get_component('ml').src_dir
mk_z3native_ml(ml_dir)
mk_z3native_stubs_c(ml_dir)
if mk_util.is_verbose():
print ('Generated "%s"' % ml_nativef)
# Collect API(...) commands from
def def_APIs():
def def_APIs(api_files):
pat1 = re.compile(" *def_API.*")
pat2 = re.compile(" *extra_API.*")
for api_file in API_FILES:
for api_file in api_files:
api = open(api_file, 'r')
for line in api:
line = line.strip('\r\n\t ')
@ -1603,24 +1510,200 @@ def def_APIs():
if m:
eval(line)
except Exception:
raise MKException("Failed to process API definition: %s" % line)
def_Types()
def_APIs()
mk_bindings()
mk_py_wrappers()
mk_dotnet()
mk_dotnet_wrappers()
mk_java()
mk_ml()
raise mk_exec_header.MKException("Failed to process API definition: %s" % line)
log_h.close()
log_c.close()
exe_c.close()
core_py.close()
def write_log_h_preamble(log_h):
log_h.write('// Automatically generated file\n')
log_h.write('#include\"z3.h\"\n')
log_h.write('#ifdef __GNUC__\n')
log_h.write('#define _Z3_UNUSED __attribute__((unused))\n')
log_h.write('#else\n')
log_h.write('#define _Z3_UNUSED\n')
log_h.write('#endif\n')
#
log_h.write('extern std::ostream * g_z3_log;\n')
log_h.write('extern bool g_z3_log_enabled;\n')
log_h.write('class z3_log_ctx { bool m_prev; public: z3_log_ctx():m_prev(g_z3_log_enabled) { g_z3_log_enabled = false; } ~z3_log_ctx() { g_z3_log_enabled = m_prev; } bool enabled() const { return m_prev; } };\n')
log_h.write('inline void SetR(void * obj) { *g_z3_log << "= " << obj << "\\n"; }\ninline void SetO(void * obj, unsigned pos) { *g_z3_log << "* " << obj << " " << pos << "\\n"; } \ninline void SetAO(void * obj, unsigned pos, unsigned idx) { *g_z3_log << "@ " << obj << " " << pos << " " << idx << "\\n"; }\n')
log_h.write('#define RETURN_Z3(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); } return Z3RES\n')
log_h.write('void _Z3_append_log(char const * msg);\n')
if is_verbose():
print("Generated '%s'" % os.path.join(api_dir, 'api_log_macros.h'))
print("Generated '%s'" % os.path.join(api_dir, 'api_log_macros.cpp'))
print("Generated '%s'" % os.path.join(api_dir, 'api_commands.cpp'))
print("Generated '%s'" % os.path.join(get_z3py_dir(), 'z3core.py'))
print("Generated '%s'" % os.path.join(dotnet_dir, 'Native.cs'))
def write_log_c_preamble(log_c):
log_c.write('// Automatically generated file\n')
log_c.write('#include<iostream>\n')
log_c.write('#include\"z3.h\"\n')
log_c.write('#include\"api_log_macros.h\"\n')
log_c.write('#include\"z3_logger.h\"\n')
def write_exe_c_preamble(exe_c):
exe_c.write('// Automatically generated file\n')
exe_c.write('#include\"z3.h\"\n')
exe_c.write('#include\"z3_replayer.h\"\n')
#
exe_c.write('void Z3_replayer_error_handler(Z3_context ctx, Z3_error_code c) { printf("[REPLAYER ERROR HANDLER]: %s\\n", Z3_get_error_msg(ctx, c)); }\n')
def write_core_py_preamble(core_py):
core_py.write('# Automatically generated file\n')
core_py.write('import sys, os\n')
core_py.write('import ctypes\n')
core_py.write('from z3types import *\n')
core_py.write('from z3consts import *\n')
core_py.write(
"""
_lib = None
def lib():
global _lib
if _lib == None:
_dir = os.path.dirname(os.path.abspath(__file__))
for ext in ['dll', 'so', 'dylib']:
try:
init('libz3.%s' % ext)
break
except:
pass
try:
init(os.path.join(_dir, 'libz3.%s' % ext))
break
except:
pass
if _lib == None:
raise Z3Exception("init(Z3_LIBRARY_PATH) must be invoked before using Z3-python")
return _lib
def _to_ascii(s):
if isinstance(s, str):
return s.encode('ascii')
else:
return s
if sys.version < '3':
def _to_pystr(s):
return s
else:
def _to_pystr(s):
if s != None:
enc = sys.stdout.encoding
if enc != None: return s.decode(enc)
else: return s.decode('ascii')
else:
return ""
def init(PATH):
global _lib
_lib = ctypes.CDLL(PATH)
"""
)
log_h = None
log_c = None
exe_c = None
core_py = None
# FIXME: This can only be called once from this module
# due to its use of global state!
def generate_files(api_files,
api_output_dir=None,
z3py_output_dir=None,
dotnet_output_dir=None,
java_output_dir=None,
java_package_name=None,
ml_output_dir=None):
"""
Scan the api files in ``api_files`` and emit
the relevant ``api_*.h`` and ``api_*.cpp`` files
for the api modules into the ``api_output_dir``
directory.
For the remaining arguments, if said argument is
not ``None`` the relevant files for that language
binding will be emitted to the specified directory.
"""
# FIXME: These should not be global
global log_h, log_c, exe_c, core_py
assert isinstance(api_files, list)
# Hack: Avoid emitting files when we don't want them
# by writing to temporary files that get deleted when
# closed. This allows us to work around the fact that
# existing code is designed to always emit these files.
def mk_file_or_temp(output_dir, file_name, mode='w'):
if output_dir != None:
assert os.path.exists(output_dir) and os.path.isdir(output_dir)
return open(os.path.join(output_dir, file_name), mode)
else:
# Return a file that we can write to without caring
print("Faking emission of '{}'".format(file_name))
import tempfile
return tempfile.TemporaryFile(mode=mode)
with mk_file_or_temp(api_output_dir, 'api_log_macros.h') as log_h:
with mk_file_or_temp(api_output_dir, 'api_log_macros.cpp') as log_c:
with mk_file_or_temp(api_output_dir, 'api_commands.cpp') as exe_c:
with mk_file_or_temp(z3py_output_dir, 'z3core.py') as core_py:
# Write preambles
write_log_h_preamble(log_h)
write_log_c_preamble(log_c)
write_exe_c_preamble(exe_c)
write_core_py_preamble(core_py)
# FIXME: these functions are awful
def_Types(api_files)
def_APIs(api_files)
mk_bindings(exe_c)
mk_py_wrappers()
if mk_util.is_verbose():
print("Generated '{}'".format(log_h.name))
print("Generated '{}'".format(log_c.name))
print("Generated '{}'".format(exe_c.name))
print("Generated '{}'".format(core_py.name))
if dotnet_output_dir:
with open(os.path.join(dotnet_output_dir, 'Native.cs'), 'w') as dotnet_file:
mk_dotnet(dotnet_file)
mk_dotnet_wrappers(dotnet_file)
if mk_util.is_verbose():
print("Generated '{}'".format(dotnet_file.name))
if java_output_dir:
mk_java(java_output_dir, java_package_name)
if ml_output_dir:
mk_ml(ml_output_dir)
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("api_files", nargs="+",
help="API header files to generate files from")
parser.add_argument("--api_output_dir",
help="Directory to emit files for api module",
default=None)
parser.add_argument("--z3py-output-dir", dest="z3py_output_dir", default=None)
parser.add_argument("--dotnet-output-dir", dest="dotnet_output_dir", default=None)
parser.add_argument("--java-output-dir", dest="java_output_dir", default=None)
parser.add_argument("--java-package-name", dest="java_package_name", default=None)
parser.add_argument("--ml-output-dir", dest="ml_output_dir", default=None)
pargs = parser.parse_args(args)
if pargs.java_output_dir:
if pargs.java_package_name == None:
logging.error('--java-package-name must be specified')
return 1
for api_file in pargs.api_files:
if not os.path.exists(api_file):
logging.error('"{}" does not exist'.format(api_file))
return 1
generate_files(api_files=pargs.api_files,
api_output_dir=pargs.api_output_dir,
z3py_output_dir=pargs.z3py_output_dir,
dotnet_output_dir=pargs.dotnet_output_dir,
java_output_dir=pargs.java_output_dir,
java_package_name=pargs.java_package_name,
ml_output_dir=pargs.ml_output_dir)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))