3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-11-06 14:26:03 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2022-01-07 12:57:39 -08:00
commit ec1a04bbb5
145 changed files with 1703 additions and 1141 deletions

View file

@ -65,7 +65,7 @@ def unpack(packages, symbols):
mk_dir(f"out/runtimes/{dst}/native")
replace(f"{tmp}/{package_dir}/bin/libz3.{ext}", f"out/runtimes/{dst}/native/libz3.{ext}")
if "x64-win" in f:
mk_dir("out/lib/netstandard1.4/")
mk_dir("out/lib/netstandard2.0/")
if symbols:
zip_ref.extract(f"{package_dir}/bin/libz3.pdb", f"{tmp}")
replace(f"{tmp}/{package_dir}/bin/libz3.pdb", f"out/runtimes/{dst}/native/libz3.pdb")
@ -74,7 +74,7 @@ def unpack(packages, symbols):
files += ["Microsoft.Z3.pdb", "Microsoft.Z3.xml"]
for b in files:
zip_ref.extract(f"{package_dir}/bin/{b}", f"{tmp}")
replace(f"{tmp}/{package_dir}/bin/{b}", f"out/lib/netstandard1.4/{b}")
replace(f"{tmp}/{package_dir}/bin/{b}", f"out/lib/netstandard2.0/{b}")
def mk_targets(source_root):
mk_dir("out/build")
@ -107,7 +107,7 @@ Linux Dependencies:
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<language>en</language>
<dependencies>
<group targetFramework=".NETStandard1.4" />
<group targetFramework=".netstandard2.0" />
</dependencies>
</metadata>
</package>""".format(version, repo, branch, commit)

View file

@ -8,7 +8,7 @@
from mk_util import *
def init_version():
set_version(4, 8, 14, 0)
set_version(4, 8, 15, 0)
# Z3 Project definition
def init_project_def():

View file

@ -15,7 +15,7 @@ import shutil
from mk_exception import *
import mk_genfile_common
from fnmatch import fnmatch
import distutils.sysconfig
import sysconfig
import compileall
import subprocess
@ -48,7 +48,7 @@ CXX_COMPILERS=['g++', 'clang++']
C_COMPILERS=['gcc', 'clang']
JAVAC=None
JAR=None
PYTHON_PACKAGE_DIR=distutils.sysconfig.get_python_lib(prefix=getenv("PREFIX", None))
PYTHON_PACKAGE_DIR=sysconfig.get_path('purelib')
BUILD_DIR='build'
REV_BUILD_DIR='..'
SRC_DIR='src'
@ -92,7 +92,6 @@ DOTNET_CORE_ENABLED=False
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
JAVA_ENABLED=False
ML_ENABLED=False
JS_ENABLED=False
PYTHON_INSTALL_ENABLED=False
STATIC_LIB=False
STATIC_BIN=False
@ -681,7 +680,7 @@ 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_CORE_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, JS_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
global DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
global LINUX_X64, SLOW_OPTIMIZE, LOG_SYNC, SINGLE_THREADED
global GUARD_CF, ALWAYS_DYNAMIC_BASE
try:
@ -749,8 +748,6 @@ def parse_options():
GIT_DESCRIBE = True
elif opt in ('', '--ml'):
ML_ENABLED = True
elif opt == "--js":
JS_ENABLED = True
elif opt in ('', '--log-sync'):
LOG_SYNC = True
elif opt == '--single-threaded':
@ -813,16 +810,6 @@ def set_build_dir(d):
BUILD_DIR = norm_path(d)
REV_BUILD_DIR = reverse_path(d)
def set_z3js_dir(p):
global SRC_DIR, Z3JS_SRC_DIR
p = norm_path(p)
full = os.path.join(SRC_DIR, p)
if not os.path.exists(full):
raise MKException("Python bindings directory '%s' does not exist" % full)
Z3JS_SRC_DIR = full
if VERBOSE:
print("Js bindings directory was detected.")
def set_z3py_dir(p):
global SRC_DIR, Z3PY_SRC_DIR
p = norm_path(p)
@ -858,9 +845,6 @@ def get_components():
def get_z3py_dir():
return Z3PY_SRC_DIR
# Return directory where the js bindings are located
def get_z3js_dir():
return Z3JS_SRC_DIR
# Return true if in verbose mode
def is_verbose():
@ -872,9 +856,6 @@ def is_java_enabled():
def is_ml_enabled():
return ML_ENABLED
def is_js_enabled():
return JS_ENABLED
def is_dotnet_core_enabled():
return DOTNET_CORE_ENABLED
@ -1611,7 +1592,7 @@ class PythonInstallComponent(Component):
os.path.join(self.pythonPkgDir,'z3'),
in_prefix=self.in_prefix_install)
if PYTHON_PACKAGE_DIR != distutils.sysconfig.get_python_lib():
if PYTHON_PACKAGE_DIR != sysconfig.get_path('purelib'):
out.write('\t@echo Z3Py was installed at \'%s\', make sure this directory is in your PYTHONPATH environment variable.' % PYTHON_PACKAGE_DIR)
def mk_uninstall(self, out):
@ -2692,7 +2673,7 @@ def mk_config():
print("Python pkg dir: %s" % PYTHON_PACKAGE_DIR)
if GPROF:
print('gprof: enabled')
print('Python version: %s' % distutils.sysconfig.get_python_version())
print('Python version: %s' % sysconfig.get_python_version())
if is_java_enabled():
print('JNI Bindings: %s' % JNI_HOME)
print('Java Compiler: %s' % JAVAC)
@ -3025,17 +3006,14 @@ def mk_bindings(api_files):
ml_output_dir = None
if is_ml_enabled():
ml_output_dir = get_component('ml').src_dir
if is_js_enabled():
set_z3js_dir("api/js")
js_output_dir = get_component('js').src_dir
# Get the update_api module to do the work for us
update_api.VERBOSE = is_verbose()
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,
js_output_dir=get_z3js_dir(),
ml_output_dir=ml_output_dir,
ml_src_dir=ml_output_dir
)

View file

@ -171,6 +171,7 @@ stages:
inputs:
artifact: 'WindowsBuild-x64'
path: $(Agent.TempDirectory)\package
- task: DownloadPipelineArtifact@2
displayName: 'Download Win32 Build'
inputs:
artifact: 'WindowsBuild-x86'
@ -313,7 +314,7 @@ stages:
jobs:
- job: GitHubPublish
condition: eq(0,1)
condition: eq(1,1)
displayName: "Publish to GitHub"
pool:
vmImage: "windows-latest"

View file

@ -15,7 +15,7 @@ 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
@ -23,6 +23,10 @@ import re
import os
import sys
VERBOSE = True
def is_verbose():
return VERBOSE
##########################################################
# TODO: rewrite this file without using global variables.
# This file is a big HACK.
@ -78,42 +82,44 @@ Type2Dotnet = { VOID : 'void', VOID_PTR : 'IntPtr', INT : 'int', UINT : 'uint',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'byte**', BOOL : 'byte', SYMBOL : 'IntPtr',
PRINT_MODE : 'uint', ERROR_CODE : 'uint', CHAR : 'char', CHAR_PTR : 'IntPtr' }
# Mapping to Java types
Type2Java = { VOID : 'void', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double',
FLOAT : 'float', STRING : 'String', STRING_PTR : 'StringPtr',
BOOL : 'boolean', SYMBOL : 'long', PRINT_MODE : 'int', ERROR_CODE : 'int', CHAR : 'char', CHAR_PTR : 'long' }
Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', INT64 : 'jlong', UINT64 : 'jlong', DOUBLE : 'jdouble',
FLOAT : 'jfloat', STRING : 'jstring', STRING_PTR : 'jobject',
BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint', CHAR : 'jchar', CHAR_PTR : 'jlong'}
# Mapping to ML types
Type2ML = { VOID : 'unit', VOID_PTR : 'VOIDP', INT : 'int', UINT : 'int', INT64 : 'int', UINT64 : 'int', DOUBLE : 'float',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'char**',
BOOL : 'bool', SYMBOL : 'z3_symbol', PRINT_MODE : 'int', ERROR_CODE : 'int', CHAR : 'char', CHAR_PTR : 'string' }
next_type_id = FIRST_OBJ_ID
class APITypes:
def __init__(self):
self.next_type_id = FIRST_OBJ_ID
def def_Type(var, c_type, py_type):
global next_type_id
exec('%s = %s' % (var, next_type_id), globals())
Type2Str[next_type_id] = c_type
Type2PyStr[next_type_id] = py_type
next_type_id = next_type_id + 1
def def_Types(api_files):
pat1 = re.compile(" *def_Type\(\'(.*)\',[^\']*\'(.*)\',[^\']*\'(.*)\'\)[ \t]*")
for api_file in api_files:
api = open(api_file, 'r')
for line in api:
m = pat1.match(line)
if m:
def_Type(m.group(1), m.group(2), m.group(3))
for k in Type2Str:
v = Type2Str[k]
if is_obj(k):
Type2Dotnet[k] = v
Type2ML[k] = v.lower()
def def_Type(self, var, c_type, py_type):
"""Process type definitions of the form def_Type(var, c_type, py_type)
The variable 'var' is set to a unique number and recorded globally using exec
It is used by 'def_APIs' to that uses the unique numbers to access the
corresponding C and Python types.
"""
id = self.next_type_id
exec('%s = %s' % (var, id), globals())
Type2Str[id] = c_type
Type2PyStr[id] = py_type
self.next_type_id += 1
def def_Types(self, api_files):
pat1 = re.compile(" *def_Type\(\'(.*)\',[^\']*\'(.*)\',[^\']*\'(.*)\'\)[ \t]*")
for api_file in api_files:
with open(api_file, 'r') as api:
for line in api:
m = pat1.match(line)
if m:
self.def_Type(m.group(1), m.group(2), m.group(3))
#
# Populate object type entries in dotnet and ML bindings.
#
for k in Type2Str:
v = Type2Str[k]
if is_obj(k):
Type2Dotnet[k] = v
Type2ML[k] = v.lower()
def type2str(ty):
global Type2Str
@ -127,20 +133,6 @@ def type2dotnet(ty):
global Type2Dotnet
return Type2Dotnet[ty]
def type2java(ty):
global Type2Java
if (ty >= FIRST_OBJ_ID):
return 'long'
else:
return Type2Java[ty]
def type2javaw(ty):
global Type2JavaW
if (ty >= FIRST_OBJ_ID):
return 'jlong'
else:
return Type2JavaW[ty]
def type2ml(ty):
global Type2ML
q = Type2ML[ty]
@ -214,42 +206,8 @@ def param2dotnet(p):
else:
return type2dotnet(param_type(p))
def param2java(p):
k = param_kind(p)
if k == OUT:
if param_type(p) == INT or param_type(p) == UINT:
return "IntPtr"
elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) == VOID_PTR or param_type(p) >= FIRST_OBJ_ID:
return "LongPtr"
elif param_type(p) == STRING:
return "StringPtr"
else:
print("ERROR: unreachable code")
assert(False)
exit(1)
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
return "%s[]" % type2java(param_type(p))
elif k == OUT_MANAGED_ARRAY:
if param_type(p) == UINT:
return "UIntArrayPtr"
else:
return "ObjArrayPtr"
else:
return type2java(param_type(p))
def param2javaw(p):
k = param_kind(p)
if k == OUT:
return "jobject"
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == BOOL:
return "jintArray"
else:
return "jlongArray"
elif k == OUT_MANAGED_ARRAY:
return "jlong"
else:
return type2javaw(param_type(p))
# --------------
def param2pystr(p):
if param_kind(p) == IN_ARRAY or param_kind(p) == OUT_ARRAY or param_kind(p) == IN_ARRAY or param_kind(p) == INOUT_ARRAY or param_kind(p) == OUT:
@ -257,6 +215,9 @@ def param2pystr(p):
else:
return type2pystr(param_type(p))
# --------------
# ML
def param2ml(p):
k = param_kind(p)
if k == OUT:
@ -507,6 +468,68 @@ def mk_dotnet_wrappers(dotnet):
dotnet.write(" }\n\n")
dotnet.write("}\n\n")
# ----------------------
# Java
Type2Java = { VOID : 'void', VOID_PTR : 'long', INT : 'int', UINT : 'int', INT64 : 'long', UINT64 : 'long', DOUBLE : 'double',
FLOAT : 'float', STRING : 'String', STRING_PTR : 'StringPtr',
BOOL : 'boolean', SYMBOL : 'long', PRINT_MODE : 'int', ERROR_CODE : 'int', CHAR : 'char', CHAR_PTR : 'long' }
Type2JavaW = { VOID : 'void', VOID_PTR : 'jlong', INT : 'jint', UINT : 'jint', INT64 : 'jlong', UINT64 : 'jlong', DOUBLE : 'jdouble',
FLOAT : 'jfloat', STRING : 'jstring', STRING_PTR : 'jobject',
BOOL : 'jboolean', SYMBOL : 'jlong', PRINT_MODE : 'jint', ERROR_CODE : 'jint', CHAR : 'jchar', CHAR_PTR : 'jlong'}
def type2java(ty):
global Type2Java
if (ty >= FIRST_OBJ_ID):
return 'long'
else:
return Type2Java[ty]
def type2javaw(ty):
global Type2JavaW
if (ty >= FIRST_OBJ_ID):
return 'jlong'
else:
return Type2JavaW[ty]
def param2java(p):
k = param_kind(p)
if k == OUT:
if param_type(p) == INT or param_type(p) == UINT:
return "IntPtr"
elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) == VOID_PTR or param_type(p) >= FIRST_OBJ_ID:
return "LongPtr"
elif param_type(p) == STRING:
return "StringPtr"
else:
print("ERROR: unreachable code")
assert(False)
exit(1)
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
return "%s[]" % type2java(param_type(p))
elif k == OUT_MANAGED_ARRAY:
if param_type(p) == UINT:
return "UIntArrayPtr"
else:
return "ObjArrayPtr"
else:
return type2java(param_type(p))
def param2javaw(p):
k = param_kind(p)
if k == OUT:
return "jobject"
elif k == IN_ARRAY or k == INOUT_ARRAY or k == OUT_ARRAY:
if param_type(p) == INT or param_type(p) == UINT or param_type(p) == BOOL:
return "jintArray"
else:
return "jlongArray"
elif k == OUT_MANAGED_ARRAY:
return "jlong"
else:
return type2javaw(param_type(p))
def java_method_name(name):
result = ''
name = name[3:] # Remove Z3_
@ -776,62 +799,9 @@ def mk_java(java_dir, package_name):
java_wrapper.write('#ifdef __cplusplus\n')
java_wrapper.write('}\n')
java_wrapper.write('#endif\n')
if mk_util.is_verbose():
if is_verbose():
print("Generated '%s'" % java_nativef)
Type2Napi = { VOID : '', VOID_PTR : '', INT : 'number', UINT : 'number', INT64 : 'number', UINT64 : 'number', DOUBLE : 'number',
FLOAT : 'number', STRING : 'string', STRING_PTR : 'array',
BOOL : 'number', SYMBOL : 'external', PRINT_MODE : 'number', ERROR_CODE : 'number', CHAR : 'number' }
def type2napi(t):
try:
return Type2Napi[t]
except:
return "external"
Type2NapiBuilder = { VOID : '', VOID_PTR : '', INT : 'int32', UINT : 'uint32', INT64 : 'int64', UINT64 : 'uint64', DOUBLE : 'double',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'array',
BOOL : 'bool', SYMBOL : 'external', PRINT_MODE : 'int32', ERROR_CODE : 'int32', CHAR : 'char' }
def type2napibuilder(t):
try:
return Type2NapiBuilder[t]
except:
return "external"
def mk_js(js_output_dir):
with open(os.path.join(js_output_dir, "z3.json"), 'w') as ous:
ous.write("{\n")
ous.write(" \"api\": [\n")
for name, result, params in _dotnet_decls:
ous.write(" {\n")
ous.write(" \"name\": \"%s\",\n" % name)
ous.write(" \"c_type\": \"%s\",\n" % Type2Str[result])
ous.write(" \"napi_type\": \"%s\",\n" % type2napi(result))
ous.write(" \"arg_list\": [")
first = True
for p in params:
if first:
first = False
ous.write("\n {\n")
else:
ous.write(",\n {\n")
t = param_type(p)
k = t
ous.write(" \"name\": \"%s\",\n" % "") # TBD
ous.write(" \"c_type\": \"%s\",\n" % type2str(t))
ous.write(" \"napi_type\": \"%s\",\n" % type2napi(t))
ous.write(" \"napi_builder\": \"%s\"\n" % type2napibuilder(t))
ous.write( " }")
ous.write("],\n")
ous.write(" \"napi_builder\": \"%s\"\n" % type2napibuilder(result))
ous.write(" },\n")
ous.write(" ]\n")
ous.write("}\n")
def mk_log_header(file, name, params):
file.write("void log_%s(" % name)
i = 0
@ -842,6 +812,10 @@ def mk_log_header(file, name, params):
i = i + 1
file.write(")")
# ---------------------------------
# Logging
def log_param(p):
kind = param_kind(p)
ty = param_type(p)
@ -1364,7 +1338,7 @@ def mk_ml(ml_src_dir, ml_output_dir):
ml_native.write('(**/**)\n')
ml_native.close()
if mk_util.is_verbose():
if is_verbose():
print ('Generated "%s"' % ml_nativef)
mk_z3native_stubs_c(ml_src_dir, ml_output_dir)
@ -1689,7 +1663,7 @@ def mk_z3native_stubs_c(ml_src_dir, ml_output_dir): # C interface
ml_wrapper.write('}\n')
ml_wrapper.write('#endif\n')
if mk_util.is_verbose():
if is_verbose():
print ('Generated "%s"' % ml_wrapperf)
# Collect API(...) commands from
@ -1889,7 +1863,6 @@ def generate_files(api_files,
dotnet_output_dir=None,
java_output_dir=None,
java_package_name=None,
js_output_dir=None,
ml_output_dir=None,
ml_src_dir=None):
"""
@ -1933,6 +1906,7 @@ def generate_files(api_files,
import tempfile
return tempfile.TemporaryFile(mode=mode)
apiTypes = APITypes()
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:
@ -1944,13 +1918,13 @@ def generate_files(api_files,
write_core_py_preamble(core_py)
# FIXME: these functions are awful
def_Types(api_files)
apiTypes.def_Types(api_files)
def_APIs(api_files)
mk_bindings(exe_c)
mk_py_wrappers()
write_core_py_post(core_py)
if mk_util.is_verbose():
if is_verbose():
print("Generated '{}'".format(log_h.name))
print("Generated '{}'".format(log_c.name))
print("Generated '{}'".format(exe_c.name))
@ -1960,7 +1934,7 @@ def generate_files(api_files,
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():
if is_verbose():
print("Generated '{}'".format(dotnet_file.name))
if java_output_dir:
@ -1970,8 +1944,6 @@ def generate_files(api_files,
assert not ml_src_dir is None
mk_ml(ml_src_dir, ml_output_dir)
if js_output_dir:
mk_js(js_output_dir)
def main(args):
logging.basicConfig(level=logging.INFO)
@ -2006,10 +1978,6 @@ def main(args):
dest="ml_output_dir",
default=None,
help="Directory to emit OCaml files. If not specified no files are emitted.")
parser.add_argument("--js_output_dir",
dest="js_output_dir",
default=None,
help="Directory to emit js bindings. If not specified no files are emitted.")
pargs = parser.parse_args(args)
if pargs.java_output_dir:
@ -2033,7 +2001,6 @@ def main(args):
dotnet_output_dir=pargs.dotnet_output_dir,
java_output_dir=pargs.java_output_dir,
java_package_name=pargs.java_package_name,
js_output_dir=pargs.js_output_dir,
ml_output_dir=pargs.ml_output_dir,
ml_src_dir=pargs.ml_src_dir)
return 0