Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further CMake Improvements #1460

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Conversation

Johanmyst
Copy link
Contributor

@Johanmyst Johanmyst commented May 12, 2024

Hi!

A while back I opened a pull request containing some changes/improvements to the CMake build system. This pull request contains some additional changes to further improve this, as well as address some issues.

Most notably, the build system has been made fully consistent and now adheres to standard practices (like placing public headers in a project-specific subdirectory), the exported package properly defines the targets to link to and its transient dependencies so linking to SVF through its CMake package can be done as normal, as well as some additional changes/improvements. Please let me know what you think!

I've also updated the example repository to include much more detailed examples & descriptions, also showcasing how to use these changes (see this pull request (#68)). I also thought I could update the build/usage instructions, but wasn't exactly sure where best to push those changes (as the main README.md doesn't contain these instructions). I'll put them at the end of this PR; if you'd like to include them in SVF's documentation, please let me know where to push it!

Summary of changes in this PR:

  • Running cmake --install <build_dir> now installs a more correct CMake package
    • Absolute paths have been fixed to be relative to wherever this config file is installed
    • Config file now defines transitive dependencies so manually linking to dependencies like Z3 is no longer necessary
  • Public header files are now installed into <prefix>/include/SVF rather than directly into <prefix>/include
  • Made CMakeLists.txt clearer & more consistent; separated different functions into scripts (e.g. generating extapi.bc)
  • Definitions of public, private, and interface directories are now set up more correctly so that IDEs and what not can also nicely locate relevant headers (much easier debugging when using SVF as a library)
  • Allow configuring more options (e.g. enabling/disabling opaque pointers)
  • Generated libraries versioning is explicitly defined; shared libraries generate versioned binaries/symlinks
  • No longer overwriting rpath to z3 include location
  • Minor layout improvements/changes

Possible Installation/Usage Instructions:

Building SVF

SVF can be built using the included build script (./build.sh), which will configure a simple default build to get started. The build script will --- by default --- not compile shared dynamic libraries, nor install SVF. If you'd like to customise the SVF build, or install the included CMake packages to use SVF conveniently in your own projects, please see Manual Build and/or Manual Installation.

Default Build Script

This script will try to find pre-existing instances of LLVM and Z3 (pointed to by the environment variables $LLVM_DIR and $Z3_DIR respectively). If these variables are unset, the build script attempts to downloaded pre-compiled binary releases of these packages and install them locally (i.e. in a subdirectory of where SVF was cloned).

**Note: ** in certain cases these packages will be built from sources (e.g. on unsupported platforms), which can be slow/cumbersome.

The build script will also source setup.sh. Please remember to source this script to make SVF accessible in your environment, or configure SVF's locations in your local environment (e.g. through ~/.zshenv or ~/.profile).

Manual Build

Building and installing SVF manually allows you modify the default build and to install SVF anywhere on your system and use it as any other library directly from CMake. The following commands will build the default release build of SVF with the compilation of shared dynamic libraries enabled and install it into your local user directory:

cmake -G "Ninja" -B Release-build --install-prefix $HOME/.local -DCMAKE_BUILD_TYPE=Release -DDBUILD_SHARED_LIBS=ON
cmake --build Release-build --parallel 16 --verbose

The top-level CMakeLists.txt defines the following parameters to adjust the SVF build:

  • SVF_SANITIZE: Allows building a sanitised build of SVF; accepts the following string values:
    • address: Will build SVF with address sanitiser enabled
    • thread: Will build SVF with thread sanitiser enabled
    • Any other sanitiser types are currently not supported out of the box
  • SVF_COVERAGE: If enabled, adds the compiler & linker flags -fprofile-arcs and -ftest-coverage to generate coverage information when running SVF
  • SVF_WARN_AS_ERROR: If enabled, compiler/linker warnings while building SVF will be treated as errors
  • SVF_EXPORT_DYNAMIC: If enabled, will export all dynamic symbols to the dynamic symbol table (not just the used ones)
  • SVF_ENABLE_ASSERTIONS: If enabled, assertions are enabled regardless of the build type (by default, debug builds will enable assertions while release builds will have them disabled)
  • SVF_ENABLE_OPAQUE_POINTERS: On by default, if disabled, will add compiler/linker flags to disable opaque pointers being used when generating extapi.bc. If your project relies on typed pointers, you can disable this flag to ensure there is no mismatch between the modules you're analysing and the extapi.bc module loaded by SVF

Default CMake flags (e.g. -DCMAKE_INSTALL_PREFIX or -DBUILD_SHARED_LIBS are respected.

Manual Installation

The top-level CMakeLists.txt script exports and installs SVF into the configured installation prefix. The default installation target includes a CMake module to easily link to SVF in your projects. The following will install a release build of SVF into the previously configured installation prefix (see Manual Build):

cmake --install Release-build

Note that not all environments/systems will by default include installation directories such as $HOME/.local/bin into environment variables like $PATH. While the CMake module will take care of most of these dependencies, depending on where you installed SVF or your configuration, you might need or want to modify some of the following variables:

  • $PATH: should include <prefix>/bin to make the tools from svf-llvm/tools accessible from the command line
  • $LD_LIBRARY_PATH: should include <prefix>/lib to make libSvfCore.[a|so] and/or libSvfLLVM.[a|so] accessible to your linker (note: possibly also $LD_RUN_PATH)
  • $[C|CPLUS]_INCLUDE_PATH: could optionally include <prefix>/include to let your IDE and compiler find these directories by default
  • $CMAKE_PREFIX_PATH: should point to <prefix>/lib (or <prefix>/lib/cmake or <prefix>/lib/cmake/SVF) to allow CMake to find the SVF module/package

Using an SVF Installation

The example repository contains some examples of how to use SVF from your own projects. Assuming your environment is correctly configured, using SVF can be as adding the following to your CMakeLists.txt scripts:

add_library(some_lib)
...
find_package(SVF CONFIG REQUIRED)
...
target_link_library(some_lib PRIVATE SVF::SvfCore SVF::SvfLLVM)

@yuleisui
Copy link
Collaborator

Thanks for the contribution. This is a big patch and I will need some time to review it.

@yuleisui
Copy link
Collaborator

@Johanmyst I was quite busy the last two weeks. It looks to me that your pull request also involves some others' commitments, could you please fix the conflicts to syn with the latest repo? Thanks

@Johanmyst Johanmyst force-pushed the cmake branch 3 times, most recently from af66690 to 5ab1c31 Compare June 3, 2024 10:41
@yuleisui
Copy link
Collaborator

yuleisui commented Jun 3, 2024

It looks that there is still a file conflict.

…tools; defined CMake package so that SVF can be imported with find_package(SVF); fixed definition of install directory to not be hardcoded but based on location of CMake package; miscellaneous improvements
…they don't use install() yet; ensure extapi.bc is compiled to the right place to support this
…ee (i.e. so that libraries and such compiled in svf-llvm are in build_dir/lib, and not in build_dir/svf-llvm/lib)
…e for SVF; correctly defined transitive dependencies on Z3 and LLVM in the exported config
…directories and that dependent builds find transitive dependencies correctly; enabled LTO; enabled more debugging information to make errors when using SVF much clearer; minor tweaks
…can't find the Z3 package in the default way; add backwards compatibility for this older installation method
… definitions) s.t. inheriting classes can't extend them
@Johanmyst
Copy link
Contributor Author

Sorry, should be resolved now. Had to figure out how to partially undo a commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants