Skip to content

Commit

Permalink
Merge pull request #1305 from Johanmyst/cmake_modernisation
Browse files Browse the repository at this point in the history
Modernise CMake script
  • Loading branch information
yuleisui authored Jan 16, 2024
2 parents 5ba90ce + 9de179f commit 520a08f
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 134 deletions.
24 changes: 24 additions & 0 deletions .config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@PACKAGE_INIT@

set_and_check(SVF_INSTALL_ROOT "@PACKAGE_SVF_INSTALL_ROOT@")
set_and_check(SVF_INSTALL_BIN_DIR "@PACKAGE_SVF_INSTALL_BIN_DIR@")
set_and_check(SVF_INSTALL_LIB_DIR "@PACKAGE_SVF_INSTALL_LIB_DIR@")
set_and_check(SVF_INSTALL_INCLUDE_DIR "@PACKAGE_SVF_INSTALL_INCLUDE_DIR@")

set_and_check(SVF_INSTALL_EXTAPI_DIR "@PACKAGE_SVF_INSTALL_EXTAPI_DIR@")
set_and_check(SVF_INSTALL_EXTAPI_FILE "@PACKAGE_SVF_INSTALL_EXTAPI_FILE@")

set(SVF_SANITIZE "@SVF_SANITIZE@")

set(SVF_COVERAGE "@SVF_COVERAGE@")
set(SVF_WARN_AS_ERROR "@SVF_WARN_AS_ERROR@")
set(SVF_EXPORT_DYNAMIC "@SVF_EXPORT_DYNAMIC@")
set(SVF_ENABLE_ASSERTIONS "@SVF_ENABLE_ASSERTIONS@")

set(SVF_BUILD_TYPE "@CMAKE_BUILD_TYPE@")
set(SVF_CXX_STANDARD "@CMAKE_CXX_STANDARD@")

set(SVF_ENABLE_RTTI "@SVF_ENABLE_RTTI@")
set(SVF_ENABLE_EXCEPTIONS "@SVF_ENABLE_EXCEPTIONS@")

include("${CMAKE_CURRENT_LIST_DIR}/SVFTargets.cmake")
25 changes: 15 additions & 10 deletions .config.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
// Directory structure of SVF build
#define SVF_ROOT "@CMAKE_CURRENT_SOURCE_DIR@"
#define SVF_BUILD_DIR "@CMAKE_CURRENT_BINARY_DIR@"
#define SVF_INSTALL_DIR "@CMAKE_INSTALL_PREFIX@"
#define SVF_BIN_DIR SVF_INSTALL_DIR "/bin"
#define SVF_LIB_DIR SVF_INSTALL_DIR "/lib"
#define SVF_INCLUDE_DIR SVF_INSTALL_DIR "/include"
#define SVF_EXTAPI_DIR SVF_INCLUDE_DIR "/SVF-LLVM"
#define SVF_EXTAPI_BC SVF_EXTAPI_DIR "/extapi.bc"
#define SVF_INSTALL_DIR "@SVF_INSTALL_ROOT@"
#define SVF_BIN_DIR "@SVF_INSTALL_BIN_DIR@"
#define SVF_LIB_DIR "@SVF_INSTALL_LIB_DIR@"
#define SVF_INCLUDE_DIR "@SVF_INSTALL_INCLUDE_DIR@"
#define SVF_EXTAPI_DIR "@SVF_INSTALL_EXTAPI_DIR@"
#define SVF_EXTAPI_BC "@SVF_INSTALL_EXTAPI_FILE@"

// Build properties of current SVF build
// Build mode used to build SVF
#define SVF_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#cmakedefine SVF_ASSERT_MODE
#cmakedefine SVF_COVERAGE

// Sanitiser mode used for building SVF
#cmakedefine SVF_SANITIZE "@SVF_SANITIZE@"

// Build options used when building SVF
#cmakedefine SVF_COVERAGE
#cmakedefine SVF_WARN_AS_ERROR
#cmakedefine SVF_EXPORT_DYNAMIC
#cmakedefine SVF_ENABLE_ASSERTIONS

#endif
#endif // CONFIG_H_IN
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ autoconf/
tests/result/
doxygen/
.*
!.config.in
!.config.cmake.in
!.gitignore
*~
*.o
Expand Down
185 changes: 138 additions & 47 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,38 +1,95 @@
cmake_minimum_required(VERSION 3.13.4)

project("SVF")
project(SVF
VERSION 2.7.1
DESCRIPTION "SVF is a static value-flow analysis tool for LLVM-based languages"
HOMEPAGE_URL "https://github.com/SVF-tools/SVF"
LANGUAGES C CXX
)

# Ensure installation directories like ${CMAKE_INSTALL_LIBDIR} are available
include(GNUInstallDirs)

message(STATUS "Using CMake with generator: ${CMAKE_GENERATOR}")
# Configurable (string) options for building SVF
set(SVF_SANITIZE "" CACHE STRING "Create sanitizer build (address)")

# Configurable (boolean) options for building SVF
option(SVF_COVERAGE "Create coverage build")
option(SVF_WARN_AS_ERROR "Treat warnings as errors when building SVF (default: on)" ON)
option(SVF_EXPORT_DYNAMIC "Export all (not only used) dynamic symbols to dynamic symbol table")
option(SVF_ENABLE_ASSERTIONS "Always enable assertions")

configure_file(${PROJECT_SOURCE_DIR}/.config.in ${PROJECT_BINARY_DIR}/include/Util/config.h)
# Configure top-level SVF variables (used by CMake for configuring installed SVF package)
set(SVF_INSTALL_ROOT ${CMAKE_INSTALL_PREFIX})
set(SVF_INSTALL_BIN_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR})
set(SVF_INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
set(SVF_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/svf)

# Set where extapi.bc is exported to in the installed CMake package
set(SVF_INSTALL_EXTAPI_DIR ${SVF_INSTALL_INCLUDE_DIR}/SVF-LLVM)
set(SVF_INSTALL_EXTAPI_FILE ${SVF_INSTALL_EXTAPI_DIR}/extapi.bc)

message(STATUS "Building ${PROJECT_NAME} with configuration:
SVF version: ${SVF_VERSION}
SVF root directory: ${SVF_SOURCE_DIR}
SVF binary directory: ${SVF_BINARY_DIR}
SVF option - create sanitiser build (str): ${SVF_SANITIZE}
SVF option - coverage build: ${SVF_COVERAGE}
SVF option - warnings as errors: ${SVF_WARN_AS_ERROR}
SVF option - unused dynamic symbols: ${SVF_EXPORT_DYNAMIC}
SVF option - enable build assertions: ${SVF_ENABLE_ASSERTIONS}")

message(STATUS "Using CMake build configuration:
CMake generator: ${CMAKE_GENERATOR}
CMake C compiler: ${CMAKE_C_COMPILER_ID}
CMake C++ compiler: ${CMAKE_CXX_COMPILER_ID}
CMake current list directory: ${CMAKE_CURRENT_LIST_DIR}
CMake current source directory: ${CMAKE_CURRENT_SOURCE_DIR}
CMake current binary directory: ${CMAKE_CURRENT_BINARY_DIR}")

# Create config.h based on config.in
configure_file(${SVF_SOURCE_DIR}/.config.in ${SVF_BINARY_DIR}/include/Util/config.h)

# Include the directory where the configuration header is exported for all targets
include_directories(${SVF_BINARY_DIR}/include)

# Treat compiler warnings as errors
add_compile_options("-Werror" "-Wall" "-Wno-deprecated-declarations")
# Install generated configuration header (see `configure_file()`) to top-level include dir of SVF
install(
FILES ${SVF_BINARY_DIR}/include/Util/config.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf/Util
)

# Build SVF with C++ standard C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)

# By default, build SVF and its targets treating all compiler warnings as errors (except deprecations)
add_compile_options(
"$<$<BOOL:${SVF_WARN_AS_ERROR}>:-Wall>"
"$<$<BOOL:${SVF_WARN_AS_ERROR}>:-Werror>"
"$<$<BOOL:${SVF_WARN_AS_ERROR}>:-Wno-deprecated-declarations>"
)

# Keep assertions enabled if requested
option(SVF_ENABLE_ASSERTIONS "Always enable assertions")
if(SVF_ENABLE_ASSERTIONS)
add_compile_options("-UNDEBUG")
endif()
add_compile_options("$<$<BOOL:${SVF_ENABLE_ASSERTIONS}>:-UNDEBUG>")

# Turn this on if you need symbols (e.g., use them for backtrace debugging)
# add_link_options("-rdynamic")
# Export dynamic symbols if requested (adds "-export-dynamic" to linkers that support it to enable backtraces)
add_compile_options("$<$<BOOL:${SVF_EXPORT_DYNAMIC}>:-rdynamic>")

option(SVF_COVERAGE "Create coverage build")
if(SVF_COVERAGE OR DEFINED ENV{SVF_COVERAGE})
add_compile_options("-fprofile-arcs" "-ftest-coverage")
add_link_options("-fprofile-arcs" "-ftest-coverage")
message(STATUS "Enable coverage")
endif()
# Configure whether a coverage build should be created for SVF (i.e. add runtime instrumentation)
add_compile_options(
"$<$<OR:$<BOOL:${SVF_COVERAGE}>,$<BOOL:$ENV{SVF_COVERAGE}>>:-fprofile-arcs>"
"$<$<OR:$<BOOL:${SVF_COVERAGE}>,$<BOOL:$ENV{SVF_COVERAGE}>>:-ftest-coverage>"
)
add_link_options(
"$<$<OR:$<BOOL:${SVF_COVERAGE}>,$<BOOL:$ENV{SVF_COVERAGE}>>:-fprofile-arcs>"
"$<$<OR:$<BOOL:${SVF_COVERAGE}>,$<BOOL:$ENV{SVF_COVERAGE}>>:-ftest-coverage>"
)

set(SVF_SANITIZE
""
CACHE STRING "Create sanitizer build (address)")
# If building with sanitiser, load the given sanitiser mode
if(SVF_SANITIZE STREQUAL "address")
add_compile_options("-fno-omit-frame-pointer" "-fsanitize=address")
add_link_options("-fsanitize=address")
Expand All @@ -42,54 +99,88 @@ elseif(SVF_SANITIZE STREQUAL "thread")
add_link_options("-fsanitize=thread")
message(STATUS "Sanitizer build: ${SVF_SANITIZE}")
elseif(NOT SVF_SANITIZE STREQUAL "")
message(ERROR "Unknown sanitizer type: ${SVF_SANITIZE}")
message(FATAL_ERROR "Unknown sanitizer type: ${SVF_SANITIZE}")
endif()

# Check if the test-suite is present, if it is then build bc files and add testing to cmake build
if(EXISTS "${PROJECT_SOURCE_DIR}/Test-Suite")
include_directories(${PROJECT_SOURCE_DIR}/Test-Suite)
enable_testing()
add_subdirectory(Test-Suite)
include(CTest)
endif()

# Find Z3 and its include directory from the top-level include file
find_library(
Z3_LIBRARIES
REQUIRED
NAMES z3
HINTS ${Z3_DIR} ENV Z3_DIR
PATH_SUFFIXES bin lib)
find_path(
Z3_INCLUDES
REQUIRED
NAMES z3++.h
HINTS ${Z3_DIR} ENV Z3_DIR
PATH_SUFFIXES include z3)
if(NOT Z3_LIBRARIES OR NOT Z3_INCLUDES)
message(FATAL_ERROR "Z3 not found!")
endif()
message(STATUS "Found Z3: ${Z3_LIBRARIES}")
message(STATUS "Z3 include dir: ${Z3_INCLUDES}")
message(STATUS "Z3 STATUS:
Z3 library file: ${Z3_LIBRARIES}
Z3 include directory: ${Z3_INCLUDES}")

include_directories(${PROJECT_SOURCE_DIR}/svf/include
${PROJECT_BINARY_DIR}/include ${Z3_INCLUDES})

# checks if the test-suite is present, if it is then build bc files and add
# testing to cmake build
if(EXISTS "${PROJECT_SOURCE_DIR}/Test-Suite")
include_directories(${PROJECT_SOURCE_DIR}/Test-Suite)
enable_testing()
add_subdirectory(Test-Suite)
include(CTest)
endif()
# Add the Z3 include directory and link the Z3 library to all targets of SVF
link_libraries(${Z3_LIBRARIES})
include_directories(SYSTEM ${Z3_INCLUDES})

# Add the actual SVF and SVF-LLVM targets
add_subdirectory(svf)
add_subdirectory(svf-llvm)

# Whether RTTI/Exceptions are enabled currently depends on whether the LLVM instance used to build
# SVF had them enabled; since the LLVM instance is found in the "svf-llvm" subdirectory, it sets the
# below variables in its parent directory (i.e. for this CMakeLists.txt) so check them here
if(SVF_NO_RTTI)
add_compile_options("-fno-rtti")
endif()
add_compile_definitions(
$<IF:$<BOOL:${SVF_ENABLE_RTTI}>,,-fno-rtti>
$<IF:$<BOOL:${SVF_ENABLE_EXCEPTIONS}>,,-fno-exceptions>
)

if(SVF_NO_EH)
add_compile_options("-fno-exceptions")
endif()
# Export the SVF target for including SVF from CMake using find_package(SVF)
include(CMakePackageConfigHelpers)

# Generate SVFConfig.cmake
configure_package_config_file(
.config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/SVFConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SVF
PATH_VARS
SVF_INSTALL_ROOT
SVF_INSTALL_BIN_DIR
SVF_INSTALL_LIB_DIR
SVF_INSTALL_INCLUDE_DIR
SVF_INSTALL_EXTAPI_DIR
SVF_INSTALL_EXTAPI_FILE
)

# Install generated configuration header (see `configure_file()`) to top-level include dir of SVF
include(GNUInstallDirs)
# Generate SVFConfigVersion.cmake
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/SVFConfigVersion.cmake"
VERSION "${SVF_VERSION_MAJOR}.${SVF_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion
)

# Install above CMake files as part of installation
install(
FILES ${PROJECT_BINARY_DIR}/include/Util/config.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/svf/Util
FILES
${CMAKE_CURRENT_BINARY_DIR}/SVFConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/SVFConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SVF
)

# Install CMake targets from different SVF subprojects so they can be found by find_package(SVF)
install(
EXPORT SVFTargets
FILE SVFTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/SVF
)

# Export targets added to SVFTargets (set by install() command)
export(EXPORT SVFTargets FILE "${CMAKE_CURRENT_BINARY_DIR}/SVFTargets.cmake")
Loading

0 comments on commit 520a08f

Please sign in to comment.