mirror of
https://github.com/Z3Prover/z3
synced 2025-06-07 06:33:23 +00:00
Teach the build system to generate and install a pkg-config file for the
".NET" bindings. This file is required for Monodevelop to find the bindings because Monodevelop uses pkg-config to find packages (it doesn't use the GAC). For lack of a better name the GAC (and pkg-config) package name is now ``Microsoft.Z3.Sharp``. I don't want to call it ``Microsoft.Z3`` because someone may want to create a ``Microsoft.Z3.pc`` file in the future for the native Z3 library (i.e. C++ or C bindings). In addition there is a new utility function ``configure_file()`` which reads a template file, applies some substitutions and writes the result to another file. This very similar to what CMake does. There is a new environment variable ``Z3_INSTALL_PKGCONFIG_DIR`` which allows pkgconfig directory to be controlled for the install.
This commit is contained in:
parent
61d1cd524e
commit
c8a2b6645a
2 changed files with 81 additions and 1 deletions
|
@ -40,6 +40,7 @@ GACUTIL=getenv("GACUTIL", None)
|
||||||
INSTALL_BIN_DIR=getenv("Z3_INSTALL_BIN_DIR", "bin")
|
INSTALL_BIN_DIR=getenv("Z3_INSTALL_BIN_DIR", "bin")
|
||||||
INSTALL_LIB_DIR=getenv("Z3_INSTALL_LIB_DIR", "lib")
|
INSTALL_LIB_DIR=getenv("Z3_INSTALL_LIB_DIR", "lib")
|
||||||
INSTALL_INCLUDE_DIR=getenv("Z3_INSTALL_INCLUDE_DIR", "include")
|
INSTALL_INCLUDE_DIR=getenv("Z3_INSTALL_INCLUDE_DIR", "include")
|
||||||
|
INSTALL_PKGCONFIG_DIR=getenv("Z3_INSTALL_PKGCONFIG_DIR", os.path.join(INSTALL_LIB_DIR, 'pkgconfig'))
|
||||||
|
|
||||||
CXX_COMPILERS=['g++', 'clang++']
|
CXX_COMPILERS=['g++', 'clang++']
|
||||||
C_COMPILERS=['gcc', 'clang']
|
C_COMPILERS=['gcc', 'clang']
|
||||||
|
@ -633,6 +634,7 @@ def display_help(exit_code):
|
||||||
print(" Z3_INSTALL_BIN_DIR Install directory for binaries relative to install prefix")
|
print(" Z3_INSTALL_BIN_DIR Install directory for binaries relative to install prefix")
|
||||||
print(" Z3_INSTALL_LIB_DIR Install directory for libraries relative to install prefix")
|
print(" Z3_INSTALL_LIB_DIR Install directory for libraries relative to install prefix")
|
||||||
print(" Z3_INSTALL_INCLUDE_DIR Install directory for header files relative to install prefix")
|
print(" Z3_INSTALL_INCLUDE_DIR Install directory for header files relative to install prefix")
|
||||||
|
print(" Z3_INSTALL_PKGCONFIG_DIR Install directory for pkgconfig files relative to install prefix")
|
||||||
exit(exit_code)
|
exit(exit_code)
|
||||||
|
|
||||||
# Parse configuration option for mk_make script
|
# Parse configuration option for mk_make script
|
||||||
|
@ -1336,6 +1338,29 @@ class DotNetDLLComponent(Component):
|
||||||
self.dll_name = dll_name
|
self.dll_name = dll_name
|
||||||
self.assembly_info_dir = assembly_info_dir
|
self.assembly_info_dir = assembly_info_dir
|
||||||
|
|
||||||
|
def mk_pkg_config_file(self):
|
||||||
|
"""
|
||||||
|
Create pkgconfig file for the dot net bindings. These
|
||||||
|
are needed by Monodevelop.
|
||||||
|
"""
|
||||||
|
pkg_config_template = os.path.join(self.src_dir, '{}.pc.in'.format(self.gac_pkg_name()))
|
||||||
|
substitutions = { 'PREFIX': PREFIX,
|
||||||
|
'GAC_PKG_NAME': self.gac_pkg_name(),
|
||||||
|
'VERSION': "{}.{}.{}.{}".format(
|
||||||
|
VER_MAJOR,
|
||||||
|
VER_MINOR,
|
||||||
|
VER_BUILD,
|
||||||
|
VER_REVISION)
|
||||||
|
}
|
||||||
|
pkg_config_output = os.path.join(BUILD_DIR,
|
||||||
|
self.build_dir,
|
||||||
|
'{}.pc'.format(self.gac_pkg_name()))
|
||||||
|
|
||||||
|
# FIXME: Why isn't the build directory available?
|
||||||
|
mk_dir(os.path.dirname(pkg_config_output))
|
||||||
|
# Configure file that will be installed by ``make install``.
|
||||||
|
configure_file(pkg_config_template, pkg_config_output, substitutions)
|
||||||
|
|
||||||
def mk_makefile(self, out):
|
def mk_makefile(self, out):
|
||||||
if not DOTNET_ENABLED:
|
if not DOTNET_ENABLED:
|
||||||
return
|
return
|
||||||
|
@ -1416,6 +1441,9 @@ class DotNetDLLComponent(Component):
|
||||||
# dll we just created the build rule for
|
# dll we just created the build rule for
|
||||||
out.write('\n')
|
out.write('\n')
|
||||||
out.write('%s: %s\n\n' % (self.name, dllfile))
|
out.write('%s: %s\n\n' % (self.name, dllfile))
|
||||||
|
|
||||||
|
# Create pkg-config file
|
||||||
|
self.mk_pkg_config_file()
|
||||||
return
|
return
|
||||||
|
|
||||||
def main_component(self):
|
def main_component(self):
|
||||||
|
@ -1447,8 +1475,11 @@ class DotNetDLLComponent(Component):
|
||||||
return
|
return
|
||||||
out.write('%s' % self.name)
|
out.write('%s' % self.name)
|
||||||
|
|
||||||
|
def gac_pkg_name(self):
|
||||||
|
return "{}.Sharp".format(self.dll_name)
|
||||||
|
|
||||||
def _install_or_uninstall_to_gac(self, out, install):
|
def _install_or_uninstall_to_gac(self, out, install):
|
||||||
gacUtilFlags = ['/package {}'.format(self.dll_name),
|
gacUtilFlags = ['/package {}'.format(self.gac_pkg_name()),
|
||||||
'/root',
|
'/root',
|
||||||
'{}{}'.format(MakeRuleCmd.install_root(), INSTALL_LIB_DIR)
|
'{}{}'.format(MakeRuleCmd.install_root(), INSTALL_LIB_DIR)
|
||||||
]
|
]
|
||||||
|
@ -1470,11 +1501,18 @@ class DotNetDLLComponent(Component):
|
||||||
return
|
return
|
||||||
self._install_or_uninstall_to_gac(out, install=True)
|
self._install_or_uninstall_to_gac(out, install=True)
|
||||||
|
|
||||||
|
# Install pkg-config file. Monodevelop needs this to find Z3
|
||||||
|
pkg_config_output = os.path.join(self.build_dir,
|
||||||
|
'{}.pc'.format(self.gac_pkg_name()))
|
||||||
|
MakeRuleCmd.make_install_directory(out, INSTALL_PKGCONFIG_DIR)
|
||||||
|
MakeRuleCmd.install_files(out, pkg_config_output, INSTALL_PKGCONFIG_DIR)
|
||||||
|
|
||||||
def mk_uninstall(self, out):
|
def mk_uninstall(self, out):
|
||||||
if not DOTNET_ENABLED or IS_WINDOWS:
|
if not DOTNET_ENABLED or IS_WINDOWS:
|
||||||
return
|
return
|
||||||
self._install_or_uninstall_to_gac(out, install=False)
|
self._install_or_uninstall_to_gac(out, install=False)
|
||||||
|
pkg_config_file = os.path.join('lib','pkgconfig','{}.pc'.format(self.gac_pkg_name()))
|
||||||
|
MakeRuleCmd.remove_installed_files(out, pkg_config_file)
|
||||||
|
|
||||||
class JavaDLLComponent(Component):
|
class JavaDLLComponent(Component):
|
||||||
def __init__(self, name, dll_name, package_name, manifest_file, path, deps):
|
def __init__(self, name, dll_name, package_name, manifest_file, path, deps):
|
||||||
|
@ -3494,6 +3532,41 @@ def strip_path_prefix(path, prefix):
|
||||||
assert not os.path.isabs(stripped_path)
|
assert not os.path.isabs(stripped_path)
|
||||||
return stripped_path
|
return stripped_path
|
||||||
|
|
||||||
|
def configure_file(template_file_path, output_file_path, substitutions):
|
||||||
|
"""
|
||||||
|
Read a template file ``template_file_path``, perform substitutions
|
||||||
|
found in the ``substitutions`` dictionary and write the result to
|
||||||
|
the output file ``output_file_path``.
|
||||||
|
|
||||||
|
The template file should contain zero or more template strings of the
|
||||||
|
form ``@NAME@``.
|
||||||
|
|
||||||
|
The substitutions dictionary maps old strings (without the ``@``
|
||||||
|
symbols) to their replacements.
|
||||||
|
"""
|
||||||
|
assert isinstance(template_file_path, str)
|
||||||
|
assert isinstance(output_file_path, str)
|
||||||
|
assert isinstance(substitutions, dict)
|
||||||
|
assert len(template_file_path) > 0
|
||||||
|
assert len(output_file_path) > 0
|
||||||
|
print("Generating {} from {}".format(output_file_path, template_file_path))
|
||||||
|
|
||||||
|
if not os.path.exists(template_file_path):
|
||||||
|
raise MKException('Could not find template file "{}"'.format(template_file_path))
|
||||||
|
|
||||||
|
# Read whole template file into string
|
||||||
|
template_string = None
|
||||||
|
with open(template_file_path, 'r') as f:
|
||||||
|
template_string = f.read()
|
||||||
|
|
||||||
|
# Do replacements
|
||||||
|
for (old_string, replacement) in substitutions.items():
|
||||||
|
template_string = template_string.replace('@{}@'.format(old_string), replacement)
|
||||||
|
|
||||||
|
# Write the string to the file
|
||||||
|
with open(output_file_path, 'w') as f:
|
||||||
|
f.write(template_string)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import doctest
|
import doctest
|
||||||
doctest.testmod()
|
doctest.testmod()
|
||||||
|
|
7
src/api/dotnet/Microsoft.Z3.Sharp.pc.in
Normal file
7
src/api/dotnet/Microsoft.Z3.Sharp.pc.in
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
prefix=@PREFIX@
|
||||||
|
assemblies_dir=${prefix}/lib/mono/@GAC_PKG_NAME@
|
||||||
|
|
||||||
|
Name: @GAC_PKG_NAME@
|
||||||
|
Description: .NET bindings for The Microsoft Z3 SMT solver
|
||||||
|
Version: @VERSION@
|
||||||
|
Libs: -r:${assemblies_dir}/Microsoft.Z3.dll
|
Loading…
Add table
Add a link
Reference in a new issue