3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

initial integration of opt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-04-27 19:13:00 -07:00
commit 8205b45839
114 changed files with 3680 additions and 1370 deletions

View file

@ -0,0 +1,30 @@
################################################################################
# @AUTO_GEN_MSG@
#
# This file is intended to be consumed by clients who wish to use Z3 from CMake.
# It can be use by doing `find_package(Z3 config)` from within a
# `CMakeLists.txt` file. If CMake doesn't find this package automatically you
# can give it a hint by passing `-DZ3_DIR=<path>` to the CMake invocation where
# `<path>` is the path to the directory containing this file.
#
# This file was built for the @CONFIG_FILE_TYPE@.
################################################################################
# Exported targets
include("${CMAKE_CURRENT_LIST_DIR}/Z3Targets.cmake")
@PACKAGE_INIT@
# Version information
set(Z3_VERSION_MAJOR @Z3_VERSION_MAJOR@)
set(Z3_VERSION_MINOR @Z3_VERSION_MINOR@)
set(Z3_VERSION_PATCH @Z3_VERSION_PATCH@)
set(Z3_VERSION_TWEAK @Z3_VERSION_TWEAK@)
set(Z3_VERSION_STRING "${Z3_VERSION_MAJOR}.${Z3_VERSION_MINOR}.${Z3_VERSION_PATCH}.${Z3_VERSION_TWEAK}")
# NOTE: We can't use `set_and_check()` here because this a list of paths.
# List of include directories
set(Z3_C_INCLUDE_DIRS @PACKAGE_Z3_FIRST_PACKAGE_INCLUDE_DIR@ @PACKAGE_Z3_SECOND_PACKAGE_INCLUDE_DIR@)
set(Z3_CXX_INCLUDE_DIRS @PACKAGE_Z3_CXX_PACKAGE_INCLUDE_DIR@ ${Z3_C_INCLUDE_DIRS})
# List of libraries to link against
set(Z3_LIBRARIES "z3::libz3")

View file

@ -0,0 +1,173 @@
# add_git_dir_dependency(GIT_DIR SUCCESS_VAR)
#
# Adds a configure time dependency on the git directory such that if the HEAD
# of the git directory changes CMake will be forced to re-run. This useful
# for fetching the current git hash and including it in the build.
#
# `GIT_DIR` is the path to the git directory (i.e. the `.git` directory)
# `SUCCESS_VAR` is the name of the variable to set. It will be set to TRUE
# if the dependency was successfully added and FALSE otherwise.
function(add_git_dir_dependency GIT_DIR SUCCESS_VAR)
if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number (${ARGC}) of arguments")
endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}")
message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not an absolute path")
endif()
if (NOT IS_DIRECTORY "${GIT_DIR}")
message(FATAL_ERROR "GIT_DIR (\"${GIT_DIR}\") is not a directory")
endif()
set(GIT_HEAD_FILE "${GIT_DIR}/HEAD")
if (NOT EXISTS "${GIT_HEAD_FILE}")
message(AUTHOR_WARNING "Git head file \"${GIT_HEAD_FILE}\" cannot be found")
set(${SUCCESS_VAR} FALSE PARENT_SCOPE)
return()
endif()
# List of files in the git tree that CMake configuration should depend on
set(GIT_FILE_DEPS "${GIT_HEAD_FILE}")
# Examine the HEAD and workout what additional dependencies there are.
file(READ "${GIT_HEAD_FILE}" GIT_HEAD_DATA LIMIT 128)
string(STRIP "${GIT_HEAD_DATA}" GIT_HEAD_DATA_STRIPPED)
if ("${GIT_HEAD_DATA_STRIPPED}" MATCHES "^ref:[ ]*(.+)$")
# HEAD points at a reference.
set(GIT_REF "${CMAKE_MATCH_1}")
if (EXISTS "${GIT_DIR}/${GIT_REF}")
# Unpacked reference. The file contains the commit hash
# so add a dependency on this file so that if we stay on this
# reference (i.e. branch) but change commit CMake will be forced
# to reconfigure.
list(APPEND GIT_FILE_DEPS "${GIT_DIR}/${GIT_REF}")
elseif(EXISTS "${GIT_DIR}/packed-refs")
# The ref must be packed (see `man git-pack-refs`).
list(APPEND GIT_FILE_DEPS "${GIT_DIR}/packed-refs")
else()
# Fail
message(AUTHOR_WARNING "Unhandled git reference")
set(${SUCCESS_VAR} FALSE PARENT_SCOPE)
return()
endif()
else()
# Detached HEAD.
# No other dependencies needed
endif()
# FIXME:
# This is the directory we will copy (via `configure_file()`) git files
# into. This is a hack. It would be better to use the
# `CMAKE_CONFIGURE_DEPENDS` directory property but that feature is not
# available in CMake 2.8.12. So we use `configure_file()` to effectively
# do the same thing. When the source file to `configure_file()` changes
# it will trigger a re-run of CMake.
set(GIT_CMAKE_FILES_DIR "${CMAKE_CURRENT_BINARY_DIR}/git_cmake_files")
file(MAKE_DIRECTORY "${GIT_CMAKE_FILES_DIR}")
foreach (git_dependency ${GIT_FILE_DEPS})
message(STATUS "Adding git dependency \"${git_dependency}\"")
configure_file(
"${git_dependency}"
"${GIT_CMAKE_FILES_DIR}"
COPYONLY
)
endforeach()
set(${SUCCESS_VAR} TRUE PARENT_SCOPE)
endfunction()
# get_git_head_hash(GIT_DIR OUTPUT_VAR)
#
# Retrieve the current commit hash for a git working directory where `GIT_DIR`
# is the `.git` directory in the root of the git working directory.
#
# `OUTPUT_VAR` should be the name of the variable to put the result in. If this
# function fails then either a fatal error will be raised or `OUTPUT_VAR` will
# contain a string with the suffix `NOTFOUND` which can be used in CMake `if()`
# commands.
function(get_git_head_hash GIT_DIR OUTPUT_VAR)
if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number of arguments")
endif()
if (NOT IS_DIRECTORY "${GIT_DIR}")
message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory")
endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}")
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path")
endif()
find_package(Git)
if (NOT Git_FOUND)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY)
execute_process(
COMMAND
"${GIT_EXECUTABLE}"
"rev-parse"
"-q" # Quiet
"HEAD"
WORKING_DIRECTORY
"${GIT_WORKING_DIR}"
RESULT_VARIABLE
GIT_EXIT_CODE
OUTPUT_VARIABLE
Z3_GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (NOT "${GIT_EXIT_CODE}" EQUAL 0)
message(WARNING "Failed to execute git")
set(${OUTPUT_VAR} NOTFOUND PARENT_SCOPE)
return()
endif()
set(${OUTPUT_VAR} "${Z3_GIT_HASH}" PARENT_SCOPE)
endfunction()
# get_git_head_describe(GIT_DIR OUTPUT_VAR)
#
# Retrieve the output of `git describe` for a git working directory where
# `GIT_DIR` is the `.git` directory in the root of the git working directory.
#
# `OUTPUT_VAR` should be the name of the variable to put the result in. If this
# function fails then either a fatal error will be raised or `OUTPUT_VAR` will
# contain a string with the suffix `NOTFOUND` which can be used in CMake `if()`
# commands.
function(get_git_head_describe GIT_DIR OUTPUT_VAR)
if (NOT "${ARGC}" EQUAL 2)
message(FATAL_ERROR "Invalid number of arguments")
endif()
if (NOT IS_DIRECTORY "${GIT_DIR}")
message(FATAL_ERROR "\"${GIT_DIR}\" is not a directory")
endif()
if (NOT IS_ABSOLUTE "${GIT_DIR}")
message(FATAL_ERROR \""${GIT_DIR}\" is not an absolute path")
endif()
find_package(Git)
if (NOT Git_FOUND)
set(${OUTPUT_VAR} "GIT-NOTFOUND" PARENT_SCOPE)
return()
endif()
get_filename_component(GIT_WORKING_DIR "${GIT_DIR}" DIRECTORY)
execute_process(
COMMAND
"${GIT_EXECUTABLE}"
"describe"
"--long"
WORKING_DIRECTORY
"${GIT_WORKING_DIR}"
RESULT_VARIABLE
GIT_EXIT_CODE
OUTPUT_VARIABLE
Z3_GIT_DESCRIPTION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (NOT "${GIT_EXIT_CODE}" EQUAL 0)
message(WARNING "Failed to execute git")
set(${OUTPUT_VAR} NOTFOUND PARENT_SCOPE)
return()
endif()
set(${OUTPUT_VAR} "${Z3_GIT_DESCRIPTION}" PARENT_SCOPE)
endfunction()

View file

@ -0,0 +1,93 @@
find_package(Doxygen REQUIRED)
message(STATUS "DOXYGEN_EXECUTABLE: \"${DOXYGEN_EXECUTABLE}\"")
message(STATUS "DOXYGEN_VERSION: \"${DOXYGEN_VERSION}\"")
set(DOC_DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/api")
set(DOC_TEMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/temp")
set(MK_API_DOC_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/mk_api_doc.py")
set(PYTHON_API_OPTIONS "")
set(DOTNET_API_OPTIONS "")
set(JAVA_API_OPTIONS "")
SET(DOC_EXTRA_DEPENDS "")
if (BUILD_PYTHON_BINDINGS)
# FIXME: Don't hard code this path
list(APPEND PYTHON_API_OPTIONS "--z3py-package-path" "${CMAKE_BINARY_DIR}/python/z3")
list(APPEND DOC_EXTRA_DEPENDS "build_z3_python_bindings")
else()
list(APPEND PYTHON_API_OPTIONS "--no-z3py")
endif()
if (BUILD_DOTNET_BINDINGS)
# FIXME: Don't hard code these paths
list(APPEND DOTNET_API_OPTIONS "--dotnet-search-paths"
"${CMAKE_SOURCE_DIR}/src/api/dotnet"
"${CMAKE_BINARY_DIR}/src/api/dotnet"
)
list(APPEND DOC_EXTRA_DEPENDS "build_z3_dotnet_bindings")
else()
list(APPEND DOTNET_API_OPTIONS "--no-dotnet")
endif()
if (BUILD_JAVA_BINDINGS)
# FIXME: Don't hard code these paths
list(APPEND JAVA_API_OPTIONS "--java-search-paths"
"${CMAKE_SOURCE_DIR}/src/api/java"
"${CMAKE_BINARY_DIR}/src/api/java"
)
list(APPEND DOC_EXTRA_DEPENDS "build_z3_java_bindings")
else()
list(APPEND JAVA_API_OPTIONS "--no-java")
endif()
option(ALWAYS_BUILD_DOCS "Always build documentation for API bindings" ON)
if (ALWAYS_BUILD_DOCS)
set(ALWAYS_BUILD_DOCS_ARG "ALL")
else()
set(ALWAYS_BUILD_DOCS_ARG "")
# FIXME: This sucks but there doesn't seem to be a way to make the top level
# install target depend on the `api_docs` target.
message(WARNING "Building documentation for API bindings is not part of the"
" all target. This may result in stale files being installed when running"
" the install target. You should run the api_docs target before running"
" the install target. Alternatively Set ALWAYS_BUILD_DOCS to ON to"
" automatically build documentation when running the install target."
)
endif()
add_custom_target(api_docs ${ALWAYS_BUILD_DOCS_ARG}
COMMAND
"${PYTHON_EXECUTABLE}" "${MK_API_DOC_SCRIPT}"
--doxygen-executable "${DOXYGEN_EXECUTABLE}"
--output-dir "${DOC_DEST_DIR}"
--temp-dir "${DOC_TEMP_DIR}"
${PYTHON_API_OPTIONS}
${DOTNET_API_OPTIONS}
${JAVA_API_OPTIONS}
DEPENDS
${DOC_EXTRA_DEPENDS}
BYPRODUCTS "${DOC_DEST_DIR}"
COMMENT "Generating documentation"
${ADD_CUSTOM_TARGET_USES_TERMINAL_ARG}
)
# Remove generated documentation when running `clean` target.
set_property(DIRECTORY APPEND PROPERTY
ADDITIONAL_MAKE_CLEAN_FILES
"${DOC_DEST_DIR}"
)
option(INSTALL_API_BINDINGS_DOCUMENTATION "Install documentation for API bindings" ON)
set(CMAKE_INSTALL_API_BINDINGS_DOC
"${CMAKE_INSTALL_DOCDIR}"
CACHE
PATH
"Path to install documentation for API bindings"
)
if (INSTALL_API_BINDINGS_DOCUMENTATION)
install(
DIRECTORY "${DOC_DEST_DIR}"
DESTINATION "${CMAKE_INSTALL_API_BINDINGS_DOC}"
)
endif()

View file

@ -1,4 +1,64 @@
add_subdirectory(c)
add_subdirectory(c++)
add_subdirectory(tptp)
add_subdirectory(python)
include(ExternalProject)
# Unfortunately `BUILD_ALWAYS` only seems to be supported with the version of ExternalProject
# that shipped with CMake >= 3.1.
if (("${CMAKE_VERSION}" VERSION_EQUAL "3.1") OR ("${CMAKE_VERSION}" VERSION_GREATER "3.1"))
set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG BUILD_ALWAYS 1)
else()
set(EXTERNAL_PROJECT_BUILD_ALWAYS_ARG "")
endif()
################################################################################
# Build example project using libz3's C API as an external project
################################################################################
ExternalProject_Add(c_example
DEPENDS libz3
# Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
# Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/c_example_build_dir"
# Install Step
INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "" # Dummy command
)
set_target_properties(c_example PROPERTIES EXCLUDE_FROM_ALL TRUE)
################################################################################
# Build example project using libz3's C++ API as an external project
################################################################################
ExternalProject_Add(cpp_example
DEPENDS libz3
# Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c++"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
# Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/cpp_example_build_dir"
# Install Step
INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "" # Dummy command
)
set_target_properties(cpp_example PROPERTIES EXCLUDE_FROM_ALL TRUE)
################################################################################
# Build example tptp5 project using libz3's C++ API as an external project
################################################################################
ExternalProject_Add(z3_tptp5
DEPENDS libz3
# Configure step
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tptp"
CMAKE_ARGS "-DZ3_DIR=${CMAKE_BINARY_DIR}"
# Build step
${EXTERNAL_PROJECT_BUILD_ALWAYS_ARG}
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/tptp_build_dir"
# Install Step
INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "" # Dummy command
)
set_target_properties(z3_tptp5 PROPERTIES EXCLUDE_FROM_ALL TRUE)
################################################################################
# Build Python examples
################################################################################
if (BUILD_PYTHON_BINDINGS)
add_subdirectory(python)
endif()

View file

@ -1,9 +1,38 @@
# FIXME: We should build this as an external project and consume
# Z3 as `find_package(z3 CONFIG)`.
add_executable(cpp_example EXCLUDE_FROM_ALL example.cpp)
target_link_libraries(cpp_example PRIVATE libz3)
target_include_directories(cpp_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
target_include_directories(cpp_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api/c++")
if (NOT BUILD_LIBZ3_SHARED)
z3_append_linker_flag_list_to_target(cpp_example ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
################################################################################
# Example C++ project
################################################################################
project(Z3_C_EXAMPLE CXX)
cmake_minimum_required(VERSION 2.8.12)
find_package(Z3
REQUIRED
CONFIG
# `NO_DEFAULT_PATH` is set so that -DZ3_DIR has to be passed to find Z3.
# This should prevent us from accidently picking up an installed
# copy of Z3. This is here to benefit Z3's build sytem when building
# this project. When making your own project you probably shouldn't
# use this option.
NO_DEFAULT_PATH
)
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}")
add_executable(cpp_example example.cpp)
target_include_directories(cpp_example PRIVATE ${Z3_CXX_INCLUDE_DIRS})
target_link_libraries(cpp_example PRIVATE ${Z3_LIBRARIES})
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
# On Windows we need to copy the Z3 libraries
# into the same directory as the executable
# so that they can be found.
foreach (z3_lib ${Z3_LIBRARIES})
message(STATUS "Adding copy rule for ${z3_lib}")
add_custom_command(TARGET cpp_example
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:${z3_lib}>
$<TARGET_FILE_DIR:cpp_example>
)
endforeach()
endif()

View file

@ -1,9 +1,42 @@
# FIXME: We should build this as an external project and consume
# Z3 as `find_package(z3 CONFIG)`.
add_executable(c_example EXCLUDE_FROM_ALL test_capi.c)
target_link_libraries(c_example PRIVATE libz3)
target_include_directories(c_example PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
# This is needed for when libz3 is built as a static library
if (NOT BUILD_LIBZ3_SHARED)
z3_append_linker_flag_list_to_target(c_example ${Z3_DEPENDENT_EXTRA_C_LINK_FLAGS})
################################################################################
# Example C project
################################################################################
# NOTE: Even though this is a C project, libz3 uses C++. When using libz3
# as a static library if we don't configure this project to also support
# C++ we will use the C linker rather than the C++ linker and will not link
# the C++ standard library in resulting in a link failure.
project(Z3_C_EXAMPLE C CXX)
cmake_minimum_required(VERSION 2.8.12)
find_package(Z3
REQUIRED
CONFIG
# `NO_DEFAULT_PATH` is set so that -DZ3_DIR has to be passed to find Z3.
# This should prevent us from accidently picking up an installed
# copy of Z3. This is here to benefit Z3's build sytem when building
# this project. When making your own project you probably shouldn't
# use this option.
NO_DEFAULT_PATH
)
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}")
add_executable(c_example test_capi.c)
target_include_directories(c_example PRIVATE ${Z3_C_INCLUDE_DIRS})
target_link_libraries(c_example PRIVATE ${Z3_LIBRARIES})
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
# On Windows we need to copy the Z3 libraries
# into the same directory as the executable
# so that they can be found.
foreach (z3_lib ${Z3_LIBRARIES})
message(STATUS "Adding copy rule for ${z3_lib}")
add_custom_command(TARGET c_example
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:${z3_lib}>
$<TARGET_FILE_DIR:c_example>
)
endforeach()
endif()

View file

@ -1,4 +1,39 @@
add_executable(z3_tptp5 EXCLUDE_FROM_ALL tptp5.cpp tptp5.lex.cpp)
target_link_libraries(z3_tptp5 PRIVATE libz3)
target_include_directories(z3_tptp5 PRIVATE "${CMAKE_SOURCE_DIR}/src/api")
target_include_directories(z3_tptp5 PRIVATE "${CMAKE_SOURCE_DIR}/src/api/c++")
################################################################################
# TPTP example
################################################################################
project(Z3_TPTP5 CXX)
cmake_minimum_required(VERSION 2.8.12)
find_package(Z3
REQUIRED
CONFIG
# `NO_DEFAULT_PATH` is set so that -DZ3_DIR has to be passed to find Z3.
# This should prevent us from accidently picking up an installed
# copy of Z3. This is here to benefit Z3's build sytem when building
# this project. When making your own project you probably shouldn't
# use this option.
NO_DEFAULT_PATH
)
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
message(STATUS "Found Z3 ${Z3_VERSION_STRING}")
message(STATUS "Z3_DIR: ${Z3_DIR}")
add_executable(z3_tptp5 tptp5.cpp tptp5.lex.cpp)
target_include_directories(z3_tptp5 PRIVATE ${Z3_CXX_INCLUDE_DIRS})
target_link_libraries(z3_tptp5 PRIVATE ${Z3_LIBRARIES})
if ("${CMAKE_SYSTEM_NAME}" MATCHES "[Ww]indows")
# On Windows we need to copy the Z3 libraries
# into the same directory as the executable
# so that they can be found.
foreach (z3_lib ${Z3_LIBRARIES})
message(STATUS "Adding copy rule for ${z3_lib}")
add_custom_command(TARGET z3_tptp5
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:${z3_lib}>
$<TARGET_FILE_DIR:z3_tptp5>
)
endforeach()
endif()

View file

@ -143,7 +143,13 @@ endif()
# so that if those are also shared libraries they are referenced by `libz3.so`.
target_link_libraries(libz3 PRIVATE ${Z3_DEPENDENT_LIBS})
z3_append_linker_flag_list_to_target(libz3 ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
# This is currently only for the OpenMP flags. It needs to be set
# via `target_link_libraries()` rather than `z3_append_linker_flag_list_to_target()`
# because when building the `libz3` as a static library when the target is exported
# the link dependencies need to be exported too.
foreach (flag_name ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
target_link_libraries(libz3 PRIVATE ${flag_name})
endforeach()
# Declare which header file are the public header files of libz3
# these will automatically installed when the libz3 target is installed
@ -168,6 +174,7 @@ foreach (header ${libz3_public_headers})
endforeach()
install(TARGETS libz3
EXPORT Z3_EXPORTED_TARGETS
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" # On Windows this installs ``libz3.lib`` which CMake calls the "corresponding import library". Do we want this installed?
RUNTIME DESTINATION "${CMAKE_INSTALL_LIBDIR}" # For Windows. DLLs are runtime targets for CMake

View file

@ -44,7 +44,6 @@ target_link_libraries(z3java PRIVATE libz3)
# Z3's components to build ``Native.cpp`` lets do the same for now.
target_compile_options(z3java PRIVATE ${Z3_COMPONENT_CXX_FLAGS})
target_compile_definitions(z3java PRIVATE ${Z3_COMPONENT_CXX_DEFINES})
z3_append_linker_flag_list_to_target(z3java ${Z3_DEPENDENT_EXTRA_CXX_LINK_FLAGS})
target_include_directories(z3java PRIVATE
"${CMAKE_SOURCE_DIR}/src/api"
"${CMAKE_BINARY_DIR}/src/api"

View file

@ -23,6 +23,7 @@ add_executable(test-z3
bv_simplifier_plugin.cpp
chashtable.cpp
check_assumptions.cpp
cnf_backbones.cpp
datalog_parser.cpp
ddnf.cpp
diff_logic.cpp

View file

@ -3,7 +3,9 @@ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/version.h")
${z3_polluted_tree_msg}
)
endif()
configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
set(Z3_FULL_VERSION "\"${Z3_FULL_VERSION_STR}\"")
configure_file(version.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/version.h)
z3_add_component(util
SOURCES

View file

@ -0,0 +1,7 @@
qprofdiff: main.cpp
$(CXX) $(CXXFLAGS) main.cpp -o qprofdiff
all: qprofdiff
clean:
rm -f qprofdiff

284
contrib/qprofdiff/main.cpp Normal file
View file

@ -0,0 +1,284 @@
/*++
Copyright (c) 2017 Microsoft Corporation
Module Name:
main.cpp
Abstract:
Main file for qprofdiff.
Author:
Christoph M. Wintersteiger (cwinter)
Revision History:
--*/
#include<errno.h>
#include<limits.h>
#include<string>
#include<iostream>
#include<fstream>
#include<map>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
set<string> options;
// Profile format:
// [quantifier_instances] qname : num_instances : max_generation : max_cost_s
const string prefix = "[quantifier_instances]";
unsigned prefix_len = prefix.length();
typedef struct { unsigned num_instances, max_generation, max_cost; } map_entry;
string trim(string str) {
size_t linx = str.find_first_not_of(' ');
size_t rinx = str.find_last_not_of(' ');
return str.substr(linx, rinx-linx+1);
}
int parse(string const & filename, map<string, map_entry> & data) {
ifstream fs(filename.c_str());
if (!fs.is_open()) {
cout << "Can't open file '" << filename << "'" << endl;
return ENOENT;
}
string qid;
string tokens[4];
unsigned cur_token = 0;
while (!fs.eof()) {
string line;
getline(fs, line);
if (line.substr(0, prefix_len) == prefix) {
line = trim(line.substr(prefix_len));
size_t from = 0, ti = 0;
for (size_t inx = line.find(':', from);
inx != string::npos;
inx = line.find(':', from)) {
tokens[ti] = trim(line.substr(from, inx-from));
from = inx+1;
ti++;
}
if (from != line.length() && ti < 4)
tokens[ti] = trim(line.substr(from));
qid = tokens[0];
if (data.find(qid) == data.end()) {
map_entry & entry = data[qid];
entry.num_instances = entry.max_generation = entry.max_cost = 0;
}
map_entry & entry = data[qid];
entry.num_instances = atoi(tokens[1].c_str());
entry.max_generation = (unsigned)atoi(tokens[2].c_str());
entry.max_cost = (unsigned)atoi(tokens[3].c_str());
}
}
fs.close();
return 0;
}
void display_data(map<string, map_entry> & data) {
for (map<string, map_entry>::iterator it = data.begin();
it != data.end();
it++)
cout << it->first << ": " << it->second.num_instances <<
", " << it->second.max_generation <<
", " << it->second.max_cost << endl;
}
typedef struct {
int d_num_instances, d_max_generation, d_max_cost;
bool left_only, right_only;
} diff_entry;
typedef struct { string qid; diff_entry e; } diff_item;
#define DIFF_LT(X) bool diff_item_lt_ ## X (diff_item const & l, diff_item const & r) { \
int l_lt_r = l.e.d_ ## X < r.e.d_ ## X; \
int l_eq_r = l.e.d_ ## X == r.e.d_ ## X; \
return \
l.e.left_only ? (r.e.left_only ? ((l_eq_r) ? l.qid < r.qid : l_lt_r) : false) : \
l.e.right_only ? (r.e.right_only ? ((l_eq_r) ? l.qid < r.qid : l_lt_r) : true) : \
r.e.right_only ? false : \
r.e.left_only ? true : \
l_lt_r; \
}
DIFF_LT(num_instances)
DIFF_LT(max_generation)
DIFF_LT(max_cost)
int indicate(diff_entry const & e, bool suppress_unchanged) {
if (e.left_only) {
cout << "< ";
return INT_MIN;
}
else if (e.right_only) {
cout << "> ";
return INT_MAX;
}
else {
int const & delta =
(options.find("-si") != options.end()) ? e.d_num_instances :
(options.find("-sg") != options.end()) ? e.d_max_generation :
(options.find("-sc") != options.end()) ? e.d_max_cost :
e.d_num_instances;
if (delta < 0)
cout << "+ ";
else if (delta > 0)
cout << "- ";
else if (delta == 0 && !suppress_unchanged)
cout << "= ";
return delta;
}
}
void diff(map<string, map_entry> & left, map<string, map_entry> & right) {
map<string, diff_entry> diff_data;
for (map<string, map_entry>::const_iterator lit = left.begin();
lit != left.end();
lit++) {
string const & qid = lit->first;
map_entry const & lentry = lit->second;
map<string, map_entry>::const_iterator rit = right.find(qid);
if (rit != right.end()) {
map_entry const & rentry = rit->second;
diff_entry & de = diff_data[qid];
de.left_only = de.right_only = false;
de.d_num_instances = lentry.num_instances - rentry.num_instances;
de.d_max_generation = lentry.max_generation - rentry.max_generation;
de.d_max_cost = lentry.max_cost - rentry.max_cost;
}
else {
diff_entry & de = diff_data[qid];
de.left_only = true;
de.right_only = false;
de.d_num_instances = lentry.num_instances;
de.d_max_generation = lentry.max_generation;
de.d_max_cost = lentry.max_cost;
}
}
for (map<string, map_entry>::const_iterator rit = right.begin();
rit != right.end();
rit++) {
string const & qid = rit->first;
map_entry const & rentry = rit->second;
map<string, map_entry>::const_iterator lit = left.find(qid);
if (lit == left.end()) {
diff_entry & de = diff_data[qid];
de.left_only = false;
de.right_only = true;
de.d_num_instances = -(int)rentry.num_instances;
de.d_max_generation = -(int)rentry.max_generation;
de.d_max_cost = -(int)rentry.max_cost;
}
}
vector<diff_item> flat_data;
for (map<string, diff_entry>::const_iterator it = diff_data.begin();
it != diff_data.end();
it++) {
flat_data.push_back(diff_item());
flat_data.back().qid = it->first;
flat_data.back().e = it->second;
}
stable_sort(flat_data.begin(), flat_data.end(),
options.find("-si") != options.end() ? diff_item_lt_num_instances:
options.find("-sg") != options.end() ? diff_item_lt_max_generation :
options.find("-sc") != options.end() ? diff_item_lt_max_cost :
diff_item_lt_num_instances);
bool suppress_unchanged = options.find("-n") != options.end();
for (vector<diff_item>::const_iterator it = flat_data.begin();
it != flat_data.end();
it++) {
diff_item const & d = *it;
string const & qid = d.qid;
diff_entry const & e = d.e;
int delta = indicate(e, suppress_unchanged);
if (!(delta == 0 && suppress_unchanged))
cout << qid << " (" <<
(e.d_num_instances > 0 ? "" : "+") << -e.d_num_instances << " inst., " <<
(e.d_max_generation > 0 ? "" : "+") << -e.d_max_generation << " max. gen., " <<
(e.d_max_cost > 0 ? "" : "+") << -e.d_max_cost << " max. cost)" <<
endl;
}
}
void display_usage() {
cout << "Usage: qprofdiff [options] <filename> <filename>" << endl;
cout << "Options:" << endl;
cout << " -n Suppress unchanged items" << endl;
cout << " -si Sort by difference in number of instances" << endl;
cout << " -sg Sort by difference in max. generation" << endl;
cout << " -sc Sort by difference in max. cost" << endl;
}
int main(int argc, char ** argv) {
char * filename1 = 0;
char * filename2 = 0;
for (int i = 1; i < argc; i++) {
int len = string(argv[i]).length();
if (len > 1 && argv[i][0] == '-') {
options.insert(string(argv[i]));
}
else if (filename1 == 0)
filename1 = argv[i];
else if (filename2 == 0)
filename2 = argv[i];
else {
cout << "Invalid argument: " << argv[i] << endl << endl;
display_usage();
return EINVAL;
}
}
if (filename1 == 0 || filename2 == 0) {
cout << "Two filenames required." << endl << endl;
display_usage();
return EINVAL;
}
cout << "Comparing " << filename1 << " to " << filename2 << endl;
map<string, map_entry> data1, data2;
int r = parse(filename1, data1);
if (r != 0) return r;
r = parse(filename2, data2);
if (r != 0) return r;
// display_data(data1);
// display_data(data2);
diff(data1, data2);
return 0;
}

View file

@ -0,0 +1,3 @@
# Maintainers
- Christoph M. Wintersteiger (@wintersteiger, cwinter@microsoft.com)

View file

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{96E7E3EF-4162-474D-BD32-C702632AAF2B}</ProjectGuid>
<RootNamespace>qprofdiff</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>
</MultiProcessorCompilation>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(LibraryPath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\src\util;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>