diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ddf030caf..d1f44d4913 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,13 @@ if (NOT PHASAR_IN_TREE) set(CMAKE_PROJECT_NAME "phasar") endif () +# NOTE: When we require cmake >= 3.21, we can use PROJECT_IS_TOP_LEVEL instead +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT ON) +else() + set(PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT OFF) +endif() + option(PHASAR_EXPERIMENTAL_CXX20 "Build phasar in C++20 mode. This is an experimental feature" OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS YES) @@ -131,40 +138,44 @@ if (PHASAR_ENABLE_SANITIZERS) endif() # LTO -if (GENERATOR_IS_MULTI_CONFIG OR CMAKE_BUILD_TYPE STREQUAL "Release") - include(CheckIPOSupported) - check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_SUPPORT_ERROR) - - if(LTO_SUPPORTED) - message(STATUS "IPO/LTO enabled in Release mode") - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) # LTO - else() - message(STATUS "IPO/LTO not supported: ${LTO_SUPPORT_ERROR}") +option(PHASAR_ALLOW_LTO_IN_RELEASE_BUILD "Use link-time-optimization (LTO) in Release builds, if possible (default is ON)" ON) +if(PHASAR_ALLOW_LTO_IN_RELEASE_BUILD) + if (GENERATOR_IS_MULTI_CONFIG OR CMAKE_BUILD_TYPE STREQUAL "Release") + include(CheckIPOSupported) + check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_SUPPORT_ERROR) + + if(LTO_SUPPORTED) + message(STATUS "IPO/LTO enabled in Release mode") + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) # LTO + else() + message(STATUS "IPO/LTO not supported: ${LTO_SUPPORT_ERROR}") + endif() endif() endif() -# Enable testing -enable_testing() - -option(PHASAR_BUILD_UNITTESTS "Build all tests (default is ON)" ON) +option(PHASAR_BUILD_UNITTESTS "Build all tests (default is ON)" ${PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT}) option(PHASAR_BUILD_OPENSSL_TS_UNITTESTS "Build OPENSSL typestate tests (require OpenSSL, default is OFF)" OFF) option(PHASAR_USE_Z3 "Build the phasar_llvm_pathsensitivity library with Z3 support for constraint solving (default is OFF)" OFF) -option(PHASAR_BUILD_IR "Build IR test code (default is ON)" ON) +option(PHASAR_BUILD_IR "Build IR test code (default is ON)" ${PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT}) option(PHASAR_ENABLE_CLANG_TIDY_DURING_BUILD "Run clang-tidy during build (default is OFF)" OFF) option(PHASAR_BUILD_DOC "Build documentation" OFF) +option(PHASAR_DEBUG_LIBDEPS "Debug internal library dependencies (private linkage)" OFF) + +option(PHASAR_BUILD_TOOLS "Build PhASAR-based tools (default is ON)" ${PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT}) + +#option(BUILD_SHARED_LIBS "Build shared libraries (default is ON)" ON) option(PHASAR_BUILD_DYNLIB "Build one fat shared library. Requires BUILD_SHARED_LIBS to be turned OFF (default is OFF)" OFF) if(PHASAR_BUILD_DYNLIB AND BUILD_SHARED_LIBS) message(FATAL_ERROR "PHASAR_BUILD_DYNLIB is incompatible with BUILD_SHARED_LIBS") endif() -option(PHASAR_DEBUG_LIBDEPS "Debug internal library dependencies (private linkage)" OFF) if (PHASAR_DEBUG_LIBDEPS) if (NOT BUILD_SHARED_LIBS) set(BUILD_SHARED_LIBS ON) @@ -198,7 +209,7 @@ else() endif() # Logger -option(PHASAR_ENABLE_DYNAMIC_LOG "Makes it possible to switch the logger on and off at runtime (default is ON)" ON) +option(PHASAR_ENABLE_DYNAMIC_LOG "Makes it possible to switch the logger on and off at runtime; otherwise, it is turned off at compile-time (default is ON)" ON) if (PHASAR_ENABLE_DYNAMIC_LOG) message(STATUS "Dynamic log enabled") @@ -259,7 +270,8 @@ set(CMAKE_CXX_CLANG_TIDY "") # Nlohmann JSON set(JSON_BuildTests OFF) set(JSON_Install ON) -add_subdirectory(external/json) +set(JSON_SystemInclude ON) +add_subdirectory(external/json EXCLUDE_FROM_ALL) # We need to work around the behavior of nlohmann_json_schema_validator and nlohmann_json here # The validator needs the json part, but if you include it, the library of nlohmann_json_schema_validator @@ -280,14 +292,20 @@ endif() # Json Schema Validator set(JSON_VALIDATOR_INSTALL ON) -add_subdirectory(external/json-schema-validator) +add_subdirectory(external/json-schema-validator EXCLUDE_FROM_ALL) # Googletest if (NOT PHASAR_IN_TREE) - set(BUILD_GMOCK OFF) - set(INSTALL_GTEST OFF) - add_subdirectory(external/googletest EXCLUDE_FROM_ALL) - set(GTEST_INCLUDE_DIR "external/googletest/googletest/include") + if(PHASAR_BUILD_UNITTESTS AND NOT TARGET gtest) + include(FetchContent) + + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG v1.13.0 + ) + FetchContent_MakeAvailable(googletest) + endif() else() # Set llvm distributed includes for gtest header set(GTEST_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include") @@ -431,7 +449,7 @@ endif() configure_file(config.h.in include/phasar/Config/phasar-config.h @ONLY) # Warnings -option(PHASAR_ENABLE_WARNINGS "Enable warnings" ON) +option(PHASAR_ENABLE_WARNINGS "Enable warnings" ${PHASAR_BUILD_OPTIONAL_TARGETS_DEFAULT}) if (PHASAR_ENABLE_WARNINGS) if (MSVC) string(APPEND CMAKE_CXX_FLAGS " /W4") @@ -448,7 +466,9 @@ add_cxx_compile_definitions(PHASAR_BUILD_DIR="${CMAKE_BINARY_DIR}") add_subdirectory(lib) # phasar-based binaries -add_subdirectory(tools) +if(PHASAR_BUILD_TOOLS) + add_subdirectory(tools) +endif() # Swift tests option(BUILD_SWIFT_TESTS "Builds the Swift tests (Swift compiler has to be installed manually beforehand!)" OFF) @@ -461,6 +481,8 @@ endif(BUILD_SWIFT_TESTS) # Add Phasar unittests and build all IR test code if (PHASAR_BUILD_UNITTESTS) message("Phasar unittests") + + enable_testing() add_subdirectory(unittests) if(NOT PHASAR_BUILD_IR) message(WARNING "Set PHASAR_BUILD_IR=ON, because PHASAR_BUILD_UNITTESTS is ON") diff --git a/README.md b/README.md index 44ea59d4d7..2d213e6c52 100644 --- a/README.md +++ b/README.md @@ -13,16 +13,14 @@ PhASAR is primarily developed and maintained by the Secure Software Engineering Lead developers of PhASAR are: Fabian Schiebel (@fabianbs96)(), Martin Mory (@MMory)(), Philipp Dominik Schubert (@pdschubert)() and others. - - -## Required version of the C++ standard +## Required Version of the C++ Standard PhASAR requires C++-17. However, building in C++20 mode is supported as an experimental feature. You may enable this by turning the cmake option `PHASAR_EXPERIMENTAL_CXX20` on. Although phasar currently does not make use of C++20 features (except for some `concept`s behind an #ifdef border), your client application that just *uses* phasar as a library may want to use C++20 ealier. -## Currently supported version of LLVM +## Currently Supported Version of LLVM PhASAR is currently set up to support LLVM-14.0.* @@ -68,41 +66,7 @@ The bootstrap script may ask for superuser permissions (to install the dependenc For subsequent builds, see [Compiling PhASAR](#compiling-phasar-if-not-already-done-using-the-installation-scripts). -## Please help us to improve PhASAR - -You are using PhASAR and would like to help us in the future? Then please -support us by filling out this [web form](https://goo.gl/forms/YG6m3M7sxeUJmKyi1). - -By giving us feedback you help to decide in what direction PhASAR should stride in -the future and give us clues about our user base. Thank you very much! - -## Installation - -PhASAR can be installed using the installer scripts as explained in the following. - -### Installing PhASAR on an Ubuntu system - -In the following, we would like to give an complete example of how to install -PhASAR using an Ubuntu or Unix-like system. - -Therefore, we provide an installation script. To install PhASAR, just navigate to the top-level -directory of PhASAR and use the following command: - -```bash -./bootstrap.sh --install -``` - -The bootstrap script may ask for superuser permissions. - -Done! - -### Installing PhASAR a MacOS system - -Due to unfortunate updates to MacOS and the handling of C++, especially on the newer M1 processors, we can't support native development on Mac. -The easiest solution to develop PhASAR on a Mac right now is to use [dockers development environments](https://docs.docker.com/desktop/dev-environments/). Clone this repository as described in their documentation. Afterwards, you have to login once manually, as a root user by running `docker exec -it -u root /bin/bash` to complete the rest of the install process as described in this readme (install submodules, run bootstrap.sh, ...). -Now you can just attach your docker container to VS Code or any other IDE, which supports remote development. - -### Compiling PhASAR (if not already done using the installation scripts) +### Compiling PhASAR (if not already done using the bootstrap script) Set the system's variables for the C and C++ compiler to clang: @@ -141,12 +105,6 @@ After compilation using cmake the following two binaries can be found in the bui + `phasar-cli` - the PhASAR command-line tool (previously called `phasar-llvm`) that provides access to analyses that are already implemented within PhASAR. Use this if you don't want to build an own tool on top of PhASAR. + `myphasartool` - an example tool that shows how tools can be build on top of PhASAR -Use the command: - -`$ ./phasar-cli --help` - -in order to display the manual and help message. - Please be careful and check if errors occur during the compilation. When using CMake to compile PhASAR the following optional parameters can be used: @@ -170,18 +128,52 @@ When using CMake to compile PhASAR the following optional parameters can be used You can use these parameters either directly or modify the installer-script `bootstrap.sh` -#### A remark on compile time +#### A Remark on Compile Time C++'s long compile times are always a pain. As shown in the above, when using cmake the compilation can easily be run in parallel, resulting in shorter compilation times. Make use of it! -### Running a test solver +### Running a Test Solver To test if everything works as expected please run the following command: `$ phasar-cli -m test/llvm_test_code/basic/module_cpp.ll -D ifds-solvertest` +You can find the `phasar-cli` tool in the build-tree under `tools/phasar-cli`. + If you obtain output other than a segmentation fault or an exception terminating the program abnormally everything works as expected. +### Building PhASAR on a MacOS System + +Due to unfortunate updates to MacOS and the handling of C++, especially on the newer M1 processors, we can't support native development on Mac. +The easiest solution to develop PhASAR on a Mac right now is to use [dockers development environments](https://docs.docker.com/desktop/dev-environments/). Clone this repository as described in their documentation. Afterwards, you have to login once manually, as a root user by running `docker exec -it -u root /bin/bash` to complete the rest of the build process as described in this readme (install submodules, run bootstrap.sh, ...). +Now you can just attach your docker container to VS Code or any other IDE, which supports remote development. + +## Installation + +PhASAR can be installed using the installer scripts as explained in the following. +However, you do not need to install PhASAR in order to use it. + +### Installing PhASAR on an Ubuntu System + +In the following, we would like to give an complete example of how to install +PhASAR using an Ubuntu or Unix-like system. + +Therefore, we provide an installation script. To install PhASAR, just navigate to the top-level +directory of PhASAR and use the following command: + +```bash +./bootstrap.sh --install +``` + +The bootstrap script may ask for superuser permissions. + +Done! + +If You have already built phasar, you can just invoke +```bash +sudo ninja install +``` + ## How to use PhASAR? We recomment using phasar as a library with `cmake`. @@ -189,16 +181,12 @@ We recomment using phasar as a library with `cmake`. If you already have installed phasar, [Use-PhASAR-as-a-library](https://github.com/secure-software-engineering/phasar/wiki/Using-Phasar-as-a-Library) may be a good start. Otherwise, we recommend adding PhASAR as a git submodule to your repository. -In this case, just `add_subdirectory` the phasar submodule directory and add phasar's include folder to your `include_directories` within your `CMakeLists.txt`. +In this case, just `add_subdirectory` the phasar submodule directory within your `CMakeLists.txt`. Assuming you have checked out phasar in `external/phasar`, the phasar-related cmake commands may look like this: ```cmake -set(PHASAR_BUILD_UNITTESTS OFF) # -- Don't build PhASAR's unittests with *your* tool -set(PHASAR_BUILD_IR OFF) # -- -add_subdirectory(external/phasar) # Build phasar with your tool -include_directories(external/phasar/include) # To find PhASAR's headers -link_libraries(nlohmann_json::nlohmann:json) # To find the json headers +add_subdirectory(external/phasar EXCLUDE_FROM_ALL) # Build phasar with your tool ... @@ -212,6 +200,15 @@ Depending on your use of PhASAR you also may need to add LLVM to your build. For more information please consult our [PhASAR wiki pages](https://github.com/secure-software-engineering/phasar/wiki). + +## Please help us to improve PhASAR + +You are using PhASAR and would like to help us in the future? Then please +support us by filling out this [web form](https://goo.gl/forms/YG6m3M7sxeUJmKyi1). + +By giving us feedback you help to decide in what direction PhASAR should stride in +the future and give us clues about our user base. Thank you very much! + ### Installing PhASAR's Git pre-commit hook You are very much welcome to contribute to the PhASAR project. diff --git a/examples/use-phasar-with-fetch-content/CMakeLists.txt b/examples/use-phasar-with-fetch-content/CMakeLists.txt new file mode 100644 index 0000000000..15033beade --- /dev/null +++ b/examples/use-phasar-with-fetch-content/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 3.12) + +project(PhasarExttoolTest) + +set(CMAKE_EXPORT_COMPILE_COMMANDS YES) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +include(FetchContent) + +FetchContent_Declare( + phasar + GIT_REPOSITORY https://github.com/secure-software-engineering/phasar.git + GIT_TAG development + EXCLUDE_FROM_ALL + OVERRIDE_FIND_PACKAGE +) + +find_package(phasar REQUIRED) + +# Build a small test tool to show how phasar may be used +add_executable(myphasartool_fc + myphasartool.cpp +) + +# Old way using phasar_config: +# phasar_config(myphasartool) + +# New way using target_link_libraries: +target_link_libraries(myphasartool_fc phasar::llvm_ifdside) + +# If find_package did not specify components: +# target_link_libraries(myphasartool phasar::phasar) +# alternatively using the default target: +# target_link_libraries(myphasartool phasar) + +install(TARGETS myphasartool_fc + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/examples/use-phasar-with-fetch-content/README.md b/examples/use-phasar-with-fetch-content/README.md new file mode 100644 index 0000000000..46ea387b0d --- /dev/null +++ b/examples/use-phasar-with-fetch-content/README.md @@ -0,0 +1,5 @@ +# Use PhASAR as a Library via FetchContent + +This small example shows how you can setup a CMake project that uses PhASAR as a library. +This guide does not assume that you have installed PhASAR already. +Instead it will download PhASAR at configure-time and build the necessary parts together with your project as-if it was a sub-module. diff --git a/examples/use-phasar-with-fetch-content/myphasartool.cpp b/examples/use-phasar-with-fetch-content/myphasartool.cpp new file mode 120000 index 0000000000..f1171d5dcc --- /dev/null +++ b/examples/use-phasar-with-fetch-content/myphasartool.cpp @@ -0,0 +1 @@ +../../tools/example-tool/myphasartool.cpp \ No newline at end of file diff --git a/external/googletest b/external/googletest deleted file mode 160000 index b796f7d446..0000000000 --- a/external/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b796f7d44681514f58a683a3a71ff17c94edb0c1 diff --git a/tools/example-tool/CMakeLists.txt b/tools/example-tool/CMakeLists.txt index e4d397e702..2a2d547661 100644 --- a/tools/example-tool/CMakeLists.txt +++ b/tools/example-tool/CMakeLists.txt @@ -16,7 +16,3 @@ target_link_libraries(myphasartool phasar ${PHASAR_STD_FILESYSTEM} ) - -install(TARGETS myphasartool - RUNTIME DESTINATION bin -)