From 3587baaf24e001e3d88d49395357a826f743a189 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 28 Jul 2016 18:06:02 +0100 Subject: [PATCH 1/3] Added full version strings and associated API functions. --- examples/dotnet/Program.cs | 2 ++ examples/java/JavaExample.java | 2 ++ examples/ml/ml_example.ml | 1 + scripts/mk_util.py | 20 +++++++++++++++++++- src/api/api_context.cpp | 5 +++++ src/api/dotnet/Version.cs | 11 +++++++++++ src/api/java/Version.java | 8 ++++++++ src/api/ml/z3.ml | 2 ++ src/api/ml/z3.mli | 3 +++ src/api/python/z3.py | 3 +++ src/api/z3_api.h | 7 +++++++ src/util/version.h.in | 2 ++ 12 files changed, 65 insertions(+), 1 deletion(-) diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index 26c081ee2..5b10dadd0 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -2159,6 +2159,8 @@ namespace test_mapi Console.WriteLine(Microsoft.Z3.Version.Major.ToString()); Console.Write("Z3 Full Version: "); Console.WriteLine(Microsoft.Z3.Version.ToString()); + Console.Write("Z3 Full Version String: "); + Console.WriteLine(Microsoft.Z3.Version.FullVersion); SimpleExample(); diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java index 5c8a7508f..5810dab37 100644 --- a/examples/java/JavaExample.java +++ b/examples/java/JavaExample.java @@ -2291,6 +2291,8 @@ class JavaExample System.out.println(Version.getMajor()); System.out.print("Z3 Full Version: "); System.out.println(Version.getString()); + System.out.print("Z3 Full Version String: "); + System.out.println(Version.getFullVersion()); p.simpleExample(); diff --git a/examples/ml/ml_example.ml b/examples/ml/ml_example.ml index bab0ba2fc..eb64f8ee8 100644 --- a/examples/ml/ml_example.ml +++ b/examples/ml/ml_example.ml @@ -323,6 +323,7 @@ let _ = else ( Printf.printf "Running Z3 version %s\n" Version.to_string ; + Printf.printf "Z3 full version string: %s\n" Version.full_version ; let cfg = [("model", "true"); ("proof", "false")] in let ctx = (mk_context cfg) in let is = (Symbol.mk_int ctx 42) in diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 591f748ec..4b5383b76 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -99,6 +99,7 @@ VS_PAR=False VS_PAR_NUM=8 GPROF=False GIT_HASH=False +GIT_DESCRIBE=False SLOW_OPTIMIZE=False USE_OMP=True @@ -534,11 +535,14 @@ def find_c_compiler(): raise MKException('C compiler was not found. Try to set the environment variable CC with the C compiler available in your system.') def set_version(major, minor, build, revision): - global VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION + global VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION, GIT_DESCRIBE VER_MAJOR = major VER_MINOR = minor VER_BUILD = build VER_REVISION = revision + if GIT_DESCRIBE: + branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) + VER_REVISION = int(check_output(['git', 'rev-list', '--count', 'HEAD'])) def get_version(): return (VER_MAJOR, VER_MINOR, VER_BUILD, VER_REVISION) @@ -621,6 +625,7 @@ def display_help(exit_code): print(" --pypkgdir= Force a particular Python package directory (default %s)" % PYTHON_PACKAGE_DIR) print(" -b , --build= subdirectory where Z3 will be built (default: %s)." % BUILD_DIR) print(" --githash=hash include the given hash in the binaries.") + print(" --git-describe include the output of 'git describe' in the version information.") print(" -d, --debug compile Z3 in debug mode.") print(" -t, --trace enable tracing in release mode.") if IS_WINDOWS: @@ -732,6 +737,8 @@ def parse_options(): GPROF = True elif opt == '--githash': GIT_HASH=arg + elif opt == '--git-describe': + GIT_DESCRIBE = True elif opt in ('', '--ml'): ML_ENABLED = True elif opt in ('', '--noomp'): @@ -2593,6 +2600,16 @@ def update_version(): mk_all_assembly_infos(major, minor, build, revision) mk_def_files() +def get_full_version_string(major, minor, build, revision): + global GIT_HASH, GIT_DESCRIBE + res = "Z3 %s.%s.%s.%s" % (major, minor, build, revision) + if GIT_HASH: + res += " " + GIT_HASH + if GIT_DESCRIBE: + 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) @@ -2606,6 +2623,7 @@ def mk_version_dot_h(major, minor, build, revision): 'Z3_VERSION_MINOR': str(minor), 'Z3_VERSION_PATCH': str(build), 'Z3_VERSION_TWEAK': str(revision), + 'Z3_FULL_VERSION': get_full_version_string(major, minor, build, revision) } ) if VERBOSE: diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index a5804bd45..418ccc58c 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -430,6 +430,11 @@ extern "C" { *revision_number = Z3_REVISION_NUMBER; } + Z3_string Z3_API Z3_get_full_version(void) { + LOG_Z3_get_full_version(); + return Z3_FULL_VERSION; + } + void Z3_API Z3_enable_trace(Z3_string tag) { memory::initialize(UINT_MAX); LOG_Z3_enable_trace(tag); diff --git a/src/api/dotnet/Version.cs b/src/api/dotnet/Version.cs index 6c22ce7fe..364ada781 100644 --- a/src/api/dotnet/Version.cs +++ b/src/api/dotnet/Version.cs @@ -83,6 +83,17 @@ namespace Microsoft.Z3 } } + /// + /// A full version string + /// + public static string FullVersion + { + get + { + return Native.Z3_get_full_version(); + } + } + /// /// A string representation of the version information. /// diff --git a/src/api/java/Version.java b/src/api/java/Version.java index 939a3ca5c..0579e2b05 100644 --- a/src/api/java/Version.java +++ b/src/api/java/Version.java @@ -63,6 +63,14 @@ public class Version return revision.value; } + /** + * A full version string + **/ + public static String getFullVersion() + { + return Native.getFullVersion(); + } + /** * A string representation of the version information. **/ diff --git a/src/api/ml/z3.ml b/src/api/ml/z3.ml index bbbb9e74b..b7016c4c8 100644 --- a/src/api/ml/z3.ml +++ b/src/api/ml/z3.ml @@ -25,6 +25,8 @@ module Version = struct let (major, minor, build, revision) = Z3native.get_version () + let full_version : string = Z3native.get_full_version() + let to_string = string_of_int major ^ "." ^ string_of_int minor ^ "." ^ diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 9104b3080..1c91b28aa 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -80,6 +80,9 @@ sig (** The revision. *) val revision : int + (** A full version string. *) + val full_version : string + (** A string representation of the version information. *) val to_string : string end diff --git a/src/api/python/z3.py b/src/api/python/z3.py index ca02975f1..62a2e2467 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -79,6 +79,9 @@ def get_version(): Z3_get_version(major, minor, build, rev) return (major.value, minor.value, build.value, rev.value) +def get_full_version(): + return Z3_get_full_version() + # We use _z3_assert instead of the assert command because we want to # produce nice error messages in Z3Py at rise4fun.com def _z3_assert(cond, msg): diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 41ca923bb..59c424be8 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -5139,6 +5139,13 @@ extern "C" { */ void Z3_API Z3_get_version(unsigned * major, unsigned * minor, unsigned * build_number, unsigned * revision_number); + /** + \brief Return a string that fully describes the version of Z3 in use. + + def_API('Z3_get_full_version', STRING, ()) + */ + Z3_string Z3_API Z3_get_full_version(void); + /** \brief Enable tracing messages tagged as \c tag when Z3 is compiled in debug mode. It is a NOOP otherwise diff --git a/src/util/version.h.in b/src/util/version.h.in index 05b619f2d..daf568a29 100644 --- a/src/util/version.h.in +++ b/src/util/version.h.in @@ -3,3 +3,5 @@ #define Z3_MINOR_VERSION @Z3_VERSION_MINOR@ #define Z3_BUILD_NUMBER @Z3_VERSION_PATCH@ #define Z3_REVISION_NUMBER @Z3_VERSION_TWEAK@ + +#define Z3_FULL_VERSION @Z3_FULL_VERSION@ From 0d83f99d8df7f30306bbec37b403fdfc513d1aa4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 28 Jul 2016 18:06:26 +0100 Subject: [PATCH 2/3] Fixed comment --- src/api/dotnet/InterpolationContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/dotnet/InterpolationContext.cs b/src/api/dotnet/InterpolationContext.cs index 17e92a40e..3f2feb5a6 100644 --- a/src/api/dotnet/InterpolationContext.cs +++ b/src/api/dotnet/InterpolationContext.cs @@ -30,7 +30,7 @@ namespace Microsoft.Z3 /// /// Constructor. /// - /// + /// public InterpolationContext(Dictionary settings) : base(settings) { } #region Terms From 7fefe40f210300dc073c93b2889be274bd92da62 Mon Sep 17 00:00:00 2001 From: "Christoph M. Wintersteiger" Date: Thu, 28 Jul 2016 18:07:34 +0100 Subject: [PATCH 3/3] Added/improved facilities for strong name signing of the .NET assembly. --- scripts/mk_project.py | 2 +- scripts/mk_util.py | 49 ++++++++++++------ ...Microsoft.Z3.mono.snk => Microsoft.Z3.snk} | Bin 3 files changed, 33 insertions(+), 18 deletions(-) rename src/api/dotnet/{Microsoft.Z3.mono.snk => Microsoft.Z3.snk} (100%) diff --git a/scripts/mk_project.py b/scripts/mk_project.py index f7b832bb9..78bc290f8 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -88,7 +88,7 @@ def init_project_def(): dll_name='libz3', static=build_static_lib(), export_files=API_files) - add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') + add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties', default_key_file='src/api/dotnet/Microsoft.Z3.snk') add_java_dll('java', ['api_dll'], 'api/java', dll_name='libz3java', package_name="com.microsoft.z3", manifest_file='manifest') add_ml_lib('ml', ['api_dll'], 'api/ml', lib_name='libz3ml') add_hlib('cpp', 'api/c++', includes2install=['z3++.h']) diff --git a/scripts/mk_util.py b/scripts/mk_util.py index 4b5383b76..66191e160 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -82,6 +82,7 @@ Z3PY_SRC_DIR=None VS_PROJ = False TRACE = False DOTNET_ENABLED=False +DOTNET_KEY_FILE=None JAVA_ENABLED=False ML_ENABLED=False PYTHON_INSTALL_ENABLED=False @@ -638,6 +639,7 @@ def display_help(exit_code): if IS_WINDOWS: print(" --optimize generate optimized code during linking.") print(" --dotnet generate .NET bindings.") + print(" --dotnet-key= sign the .NET assembly using the private key in .") print(" --java generate Java bindings.") print(" --ml generate OCaml bindings.") print(" --python generate Python bindings.") @@ -673,14 +675,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, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, PYTHON_INSTALL_ENABLED + global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, FOCI2, FOCI2LIB, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, 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', 'staticbin']) + 'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'foci2=', 'java', 'parallel=', 'gprof', + 'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin']) except: print("ERROR: Invalid command line option") display_help(1) @@ -713,6 +715,8 @@ def parse_options(): TRACE = True elif opt in ('-.net', '--dotnet'): DOTNET_ENABLED = True + elif opt in ('--dotnet-key'): + DOTNET_KEY_FILE = arg elif opt in ('--staticlib'): STATIC_LIB = True elif opt in ('--staticbin'): @@ -1498,7 +1502,7 @@ class PythonInstallComponent(Component): return class DotNetDLLComponent(Component): - def __init__(self, name, dll_name, path, deps, assembly_info_dir): + def __init__(self, name, dll_name, path, deps, assembly_info_dir, default_key_file): Component.__init__(self, name, path, deps) if dll_name is None: dll_name = name @@ -1506,6 +1510,7 @@ class DotNetDLLComponent(Component): assembly_info_dir = "." self.dll_name = dll_name self.assembly_info_dir = assembly_info_dir + self.key_file = default_key_file def mk_pkg_config_file(self): """ @@ -1531,6 +1536,8 @@ class DotNetDLLComponent(Component): configure_file(pkg_config_template, pkg_config_output, substitutions) def mk_makefile(self, out): + global DOTNET_KEY_FILE + if not is_dotnet_enabled(): return cs_fp_files = [] @@ -1561,17 +1568,24 @@ class DotNetDLLComponent(Component): '/linkresource:{}.dll'.format(get_component(Z3_DLL_COMPONENT).dll_name), ] ) - pathToSnk = os.path.join(self.to_src_dir, 'z3.snk') - snkFile = os.path.join(self.src_dir, 'z3.snk') - else: - # We need to give the assembly a strong name so that it - # can be installed into the GAC with ``make install`` - pathToSnk = os.path.join(self.to_src_dir, 'Microsoft.Z3.mono.snk') - snkFile = os.path.join(self.src_dir, 'Microsoft.Z3.mono.snk') - if os.path.isfile(snkFile): - cscCmdLine.append('/keyfile:{}'.format(pathToSnk)) - else: - print("Keyfile is not configured: %s" % snkFile) + + # We need to give the assembly a strong name so that it + # can be installed into the GAC with ``make install`` + if not DOTNET_KEY_FILE is None: + self.key_file = DOTNET_KEY_FILE + + if not self.key_file is None: + if os.path.isfile(self.key_file): + self.key_file = os.path.abspath(self.key_file) + elif os.path.isfile(os.path.join(self.src_dir, self.key_file)): + self.key_file = os.path.abspath(os.path.join(self.src_dir, self.key_file)) + else: + print("Keyfile '%s' could not be found; %s.dll will be unsigned." % (self.dll_name, self.key_file)) + 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)) cscCmdLine.extend( ['/unsafe+', '/nowarn:1701,1702', @@ -1595,6 +1609,7 @@ class DotNetDLLComponent(Component): ) else: cscCmdLine.extend(['/optimize+']) + if IS_WINDOWS: if VS_X64: cscCmdLine.extend(['/platform:x64']) @@ -2179,8 +2194,8 @@ def add_dll(name, deps=[], path=None, dll_name=None, export_files=[], reexports= reg_component(name, c) return c -def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=None): - c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir) +def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=None, default_key_file=None): + c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir, default_key_file) reg_component(name, c) def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, manifest_file=None): diff --git a/src/api/dotnet/Microsoft.Z3.mono.snk b/src/api/dotnet/Microsoft.Z3.snk similarity index 100% rename from src/api/dotnet/Microsoft.Z3.mono.snk rename to src/api/dotnet/Microsoft.Z3.snk