Skip to content

Commit

Permalink
Build Z3 from source for P4Tools.
Browse files Browse the repository at this point in the history
  • Loading branch information
fruffy committed May 31, 2024
1 parent 9aaa4bc commit 156b925
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-test-fedora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:

- name: Build p4c (Fedora Linux)
run: |
./bootstrap.sh -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_UNITY_BUILD=ON --build-generator "Ninja"
./bootstrap.sh -DCMAKE_BUILD_TYPE=Release -DCMAKE_UNITY_BUILD=ON --build-generator "Ninja"
cmake --build build -- -j $(nproc)
- name: Run p4c tests (Fedora Linux)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci-test-mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- name: Build (MacOS)
run: |
source ~/.bash_profile
./bootstrap.sh -DENABLE_GC=ON -DCMAKE_BUILD_TYPE=RELEASE \
./bootstrap.sh -DENABLE_GC=ON -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_UNITY_BUILD=ON -DENABLE_TEST_TOOLS=ON --build-generator "Ninja"
cmake --build build -- -j $(nproc)
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
- name: Build (MacOS)
run: |
source ~/.bash_profile
./bootstrap.sh -DENABLE_GC=ON -DCMAKE_BUILD_TYPE=RELEASE \
./bootstrap.sh -DENABLE_GC=ON -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_UNITY_BUILD=ON -DENABLE_TEST_TOOLS=ON --build-generator "Ninja"
cmake --build build -- -j $(nproc)
Expand Down
73 changes: 73 additions & 0 deletions backends/p4tools/cmake/Z3.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
macro(p4tools_obtain_z3)
option(TOOLS_USE_PREINSTALLED_Z3 "Look for a preinstalled version of Z3 instead of installing a prebuilt binary using FetchContent." OFF)

if(TOOLS_USE_PREINSTALLED_Z3)
# We need a fairly recent version of Z3.
set(Z3_MIN_VERSION "4.8.14")
# But 4.12+ is currently broken with libGC
set(Z3_MAX_VERSION_EXCL "4.12")
find_package(Z3 ${Z3_MIN_VERSION} REQUIRED)

if(NOT DEFINED Z3_VERSION_STRING OR ${Z3_VERSION_STRING} VERSION_LESS ${Z3_MIN_VERSION})
message(FATAL_ERROR "The minimum required Z3 version is ${Z3_MIN_VERSION}. Has ${Z3_VERSION_STRING}.")
endif()
if(${Z3_VERSION_STRING} VERSION_GREATER_EQUAL ${Z3_MAX_VERSION_EXCL})
message(FATAL_ERROR "The Z3 version has to be lower than ${Z3_MAX_VERSION_EXCL} (the latter currently does no work with libGC). Has ${Z3_VERSION_STRING}.")
endif()
# Set variables for later consumption.
set(P4TOOLS_Z3_LIB z3::z3)
set(P4TOOLS_Z3_INCLUDE_DIR ${Z3_INCLUDE_DIR})
else()
# Pull in a specific version of Z3 and link against it.
set(P4TOOLS_Z3_VERSION "4.13.0")
message(STATUS "Fetching Z3 version ${P4TOOLS_Z3_VERSION} for P4Tools...")

# Unity builds do not work for Protobuf...
set(CMAKE_UNITY_BUILD_PREV ${CMAKE_UNITY_BUILD})
set(CMAKE_UNITY_BUILD OFF)
# Print out download state while setting up Z3.
set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET})
set(FETCHCONTENT_QUIET OFF)

set(Z3_BUILD_LIBZ3_SHARED OFF CACHE BOOL "Build libz3 as a shared library if true, otherwise build a static library")
set(Z3_INCLUDE_GIT_HASH OFF CACHE BOOL "Include git hash in version output")
set(Z3_INCLUDE_GIT_DESCRIBE OFF CACHE BOOL "Include git describe output in version output")
fetchcontent_declare(
z3
GIT_REPOSITORY https://github.com/Z3Prover/z3.git
GIT_TAG z3-${P4TOOLS_Z3_VERSION} # 4.13.0
GIT_PROGRESS TRUE
GIT_SHALLOW TRUE
# We need to patch because the Z3 CMakeLists.txt also adds an uinstall target.
# This leads to a namespace clash.
PATCH_COMMAND
git apply ${P4TOOLS_SOURCE_DIR}/cmake/z3.patch || git apply
${P4TOOLS_SOURCE_DIR}/cmake/z3.patch -R --check && echo
"Patch does not apply because the patch was already applied."
)
fetchcontent_makeavailable_but_exclude_install(z3)

# Suppress warnings for all Z3 targets.
get_all_targets(Z3_BUILD_TARGETS ${z3_SOURCE_DIR})
foreach(target ${Z3_BUILD_TARGETS})
# Do not suppress warnings for Z3 library targets that are aliased.
get_target_property(target_type ${target} TYPE)
if (NOT ${target_type} STREQUAL "INTERFACE_LIBRARY")
target_compile_options(${target} PRIVATE "-Wno-error" "-w")
# Z3 does not add its own include directories for compilation, which can lead to conflicts.
target_include_directories(${target} BEFORE PRIVATE ${z3_SOURCE_DIR}/src)
endif()
endforeach()

# Reset temporary variable modifications.
set(CMAKE_UNITY_BUILD ${CMAKE_UNITY_BUILD_PREV})
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})

# Other projects may also pull in Z3.
# We have to make sure we only include our local version with P4Tools.
set(P4TOOLS_Z3_LIB libz3)
set(P4TOOLS_Z3_INCLUDE_DIR ${z3_SOURCE_DIR}/src/api ${z3_SOURCE_DIR}/src/api/c++)
endif()

message(STATUS "Done with setting up Z3 for P4Tools.")
endmacro(p4tools_obtain_z3)
68 changes: 0 additions & 68 deletions backends/p4tools/cmake/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,71 +13,3 @@ function(add_p4tools_executable target source)
install(TARGETS ${target} RUNTIME DESTINATION ${P4C_RUNTIME_OUTPUT_DIRECTORY})
endfunction(add_p4tools_executable)

macro(p4tools_obtain_z3)
option(TOOLS_USE_PREINSTALLED_Z3 "Look for a preinstalled version of Z3 instead of installing a prebuilt binary using FetchContent." OFF)

if(TOOLS_USE_PREINSTALLED_Z3)
# We need a fairly recent version of Z3.
set(Z3_MIN_VERSION "4.8.14")
# But 4.12+ is currently broken with libGC
set(Z3_MAX_VERSION_EXCL "4.12")
find_package(Z3 ${Z3_MIN_VERSION} REQUIRED)

if(NOT DEFINED Z3_VERSION_STRING OR ${Z3_VERSION_STRING} VERSION_LESS ${Z3_MIN_VERSION})
message(FATAL_ERROR "The minimum required Z3 version is ${Z3_MIN_VERSION}. Has ${Z3_VERSION_STRING}.")
endif()
if(${Z3_VERSION_STRING} VERSION_GREATER_EQUAL ${Z3_MAX_VERSION_EXCL})
message(FATAL_ERROR "The Z3 version has to be lower than ${Z3_MAX_VERSION_EXCL} (the latter currently does no work with libGC). Has ${Z3_VERSION_STRING}.")
endif()
# Set variables for later consumption.
set(P4TOOLS_Z3_LIB z3::z3)
set(P4TOOLS_Z3_INCLUDE_DIR ${Z3_INCLUDE_DIR})
else()
# Pull in a specific version of Z3 and link against it.
set(P4TOOLS_Z3_VERSION "4.11.2")
message("Fetching Z3 version ${P4TOOLS_Z3_VERSION} for P4Tools...")

# Determine platform to fetch pre-built Z3
if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
set(Z3_ARCH "x64")
if (APPLE)
set(Z3_PLATFORM_SUFFIX "osx-10.16")
set(Z3_ZIP_HASH "a56b6c40d9251a963aabe1f15731dd88ad1cb801d0e7b16e45f8b232175e165c")
elseif (UNIX)
set(Z3_PLATFORM_SUFFIX "glibc-2.31")
set(Z3_ZIP_HASH "9d0f70e61e82b321f35e6cad1343615d2dead6f2c54337a24293725de2900fb6")
else()
message(FATAL_ERROR "Unsupported system platform")
endif()
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
set(Z3_ARCH "arm64")
if (APPLE)
set(Z3_PLATFORM_SUFFIX "osx-11.0")
set(Z3_ZIP_HASH "c021f381fa3169b1f7fb3b4fae81a1d1caf0dd8aa4aa773f4ab9d5e28c6657a4")
else()
message(FATAL_ERROR "Unsupported system platform")
endif()
else()
message(FATAL_ERROR "Unsupported system processor")
endif()

# Print out download state while setting up Z3.
set(FETCHCONTENT_QUIET_PREV ${FETCHCONTENT_QUIET})
set(FETCHCONTENT_QUIET OFF)
fetchcontent_declare(
z3
URL https://github.com/Z3Prover/z3/releases/download/z3-${P4TOOLS_Z3_VERSION}/z3-${P4TOOLS_Z3_VERSION}-${Z3_ARCH}-${Z3_PLATFORM_SUFFIX}.zip
URL_HASH SHA256=${Z3_ZIP_HASH}
USES_TERMINAL_DOWNLOAD TRUE
GIT_PROGRESS TRUE
)
fetchcontent_makeavailable(z3)
set(FETCHCONTENT_QUIET ${FETCHCONTENT_QUIET_PREV})
message("Done with setting up Z3 for P4Tools.")

# Other projects may also pull in Z3.
# We have to make sure we only include our local version with P4Tools.
set(P4TOOLS_Z3_LIB ${z3_SOURCE_DIR}/bin/libz3${CMAKE_STATIC_LIBRARY_SUFFIX})
set(P4TOOLS_Z3_INCLUDE_DIR ${z3_SOURCE_DIR}/include)
endif()
endmacro(p4tools_obtain_z3)
77 changes: 77 additions & 0 deletions backends/p4tools/cmake/z3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ba3ec7bce..7ca1894fd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -446,13 +446,13 @@ configure_file(

# Target needs to be declared before the components so that they can add
# dependencies to this target so they can run their own custom uninstall rules.
-add_custom_target(uninstall
- COMMAND
- "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
- COMMENT "Uninstalling..."
- USES_TERMINAL
- VERBATIM
-)
+# add_custom_target(uninstall
+# COMMAND
+# "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+# COMMENT "Uninstalling..."
+# USES_TERMINAL
+# VERBATIM
+# )

################################################################################
# CMake build file locations
diff --git a/src/math/lp/column_info.h b/src/math/lp/column_info.h
index 1dc0c60c7..9cbeea66c 100644
--- a/src/math/lp/column_info.h
+++ b/src/math/lp/column_info.h
@@ -47,7 +47,7 @@ public:
m_lower_bound_is_strict == c.m_lower_bound_is_strict &&
m_upper_bound_is_set == c.m_upper_bound_is_set&&
m_upper_bound_is_strict == c.m_upper_bound_is_strict&&
- (!m_lower_bound_is_set || m_lower_bound == c.m_low_bound) &&
+ (!m_lower_bound_is_set || m_lower_bound == c.m_lower_bound) &&
(!m_upper_bound_is_set || m_upper_bound == c.m_upper_bound) &&
m_cost == c.m_cost &&
m_is_fixed == c.m_is_fixed &&
diff --git a/src/math/lp/static_matrix.h b/src/math/lp/static_matrix.h
index 9d6bb8599..42dd476b5 100644
--- a/src/math/lp/static_matrix.h
+++ b/src/math/lp/static_matrix.h
@@ -79,7 +79,7 @@ public:
ref(static_matrix & m, unsigned row, unsigned col):m_matrix(m), m_row(row), m_col(col) {}
ref & operator=(T const & v) { m_matrix.set( m_row, m_col, v); return *this; }

- ref operator=(ref & v) { m_matrix.set(m_row, m_col, v.m_matrix.get(v.m_row, v.m_col)); return *this; }
+ ref operator=(ref & v) { m_matrix.set(m_row, m_col, v.m_matrix.get_elem(v.m_row, v.m_col)); return *this; }

operator T () const { return m_matrix.get_elem(m_row, m_col); }
};
diff --git a/src/math/lp/static_matrix_def.h b/src/math/lp/static_matrix_def.h
index 0370ee899..514b48703 100644
--- a/src/math/lp/static_matrix_def.h
+++ b/src/math/lp/static_matrix_def.h
@@ -92,7 +92,7 @@ static_matrix<T, X>::static_matrix(static_matrix const &A, unsigned * /* basis *
init_row_columns(m, m);
for (; m-- > 0; )
for (auto & col : A.m_columns[m])
- set(col.var(), m, A.get_value_of_column_cell(col));
+ set(col.var(), m, A.get_val(col));
}

template <typename T, typename X> void static_matrix<T, X>::clear() {
diff --git a/src/util/memory_manager.cpp b/src/util/memory_manager.cpp
index 290881ba5..a3db94d7a 100644
--- a/src/util/memory_manager.cpp
+++ b/src/util/memory_manager.cpp
@@ -29,6 +29,8 @@ Copyright (c) 2015 Microsoft Corporation
# define malloc_usable_size _msize
#endif

+#undef HAS_MALLOC_USABLE_SIZE
+
// The following two function are automatically generated by the mk_make.py script.
// The script collects ADD_INITIALIZER and ADD_FINALIZER commands in the .h files.
// For example, rational.h contains
6 changes: 4 additions & 2 deletions backends/p4tools/common/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Handle the Z3 installation with this macro. Users have the option to supply their own Z3.
include(Z3)
p4tools_obtain_z3()

# Generate version information.
Expand Down Expand Up @@ -41,15 +42,16 @@ add_library(p4tools-common OBJECT ${P4C_TOOLS_COMMON_SOURCES})

target_link_libraries(
p4tools-common
# We export Z3' with the common library.
# We export Z3 with the common library.
PUBLIC ${P4TOOLS_Z3_LIB}
# For Abseil includes.
PRIVATE frontend
)

target_include_directories(
p4tools-common
# We export Z3's includes with the common library.
# We also export Z3's includes with the common library.
# This is necessary because the z3 target itself does not export its includes.
SYSTEM BEFORE PUBLIC ${P4TOOLS_Z3_INCLUDE_DIR}
)

Expand Down
3 changes: 0 additions & 3 deletions backends/p4tools/common/core/z3_solver.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#include "backends/p4tools/common/core/z3_solver.h"

#include <z3++.h>
#include <z3_api.h>

#include <algorithm>
#include <cstdint>
#include <exception>
Expand Down
1 change: 1 addition & 0 deletions backends/p4tools/common/core/z3_solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define BACKENDS_P4TOOLS_COMMON_CORE_Z3_SOLVER_H_

#include <z3++.h>
#include <z3.h>

#include <cstddef>
#include <iosfwd>
Expand Down
2 changes: 1 addition & 1 deletion tools/ci-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ CMAKE_FLAGS+="-DSTATIC_BUILD_WITH_DYNAMIC_STDLIB=${STATIC_BUILD_WITH_DYNAMIC_STD
# Toggle the installation of the tools back end.
CMAKE_FLAGS+="-DENABLE_TEST_TOOLS=${ENABLE_TEST_TOOLS} "
# RELEASE should be default, but we want to make sure.
CMAKE_FLAGS+="-DCMAKE_BUILD_TYPE=RELEASE "
CMAKE_FLAGS+="-DCMAKE_BUILD_TYPE=Release "
# Treat warnings as errors.
CMAKE_FLAGS+="-DENABLE_WERROR=${ENABLE_WERROR} "
# Enable sanitizers.
Expand Down
2 changes: 1 addition & 1 deletion tools/debian-build/packaging.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export CXXFLAGS="${CXXFLAGS} -O3"
# Enable unity compilation.
CONFOPT+="-DCMAKE_UNITY_BUILD=ON "
# RELEASE should be default, but we want to make sure.
CONFOPT+="-DCMAKE_BUILD_TYPE=RELEASE "
CONFOPT+="-DCMAKE_BUILD_TYPE=Release "
# The binaries we produce should not depend on system libraries.
CONFOPT+="-DSTATIC_BUILD_WITH_DYNAMIC_GLIBC=ON "
MAKE_DIST="cd ${P4C_DIR}/backends/ebpf && ./build_libbpf && mkdir -p ${P4C_DIR}/build && cd ${P4C_DIR}/build && cmake .. $CONFOPT && make && make dist"
Expand Down

0 comments on commit 156b925

Please sign in to comment.