From 70111547dfeb9c74ff081711d7ad87c0c99851f2 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 14 Apr 2022 12:16:41 -0400 Subject: [PATCH] Add instructions for use with Rust --- README.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++- build_deps.sh | 11 +++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1c22f6328..04dde20ec 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ $ ./build_deps.sh $buildtype $extra_cmake_flags ``` $ mkdir /path/to/souper-build $ cd /path/to/souper-build -$ cmake -DCMAKE_BUILD_TYPE=$buildtype /path/to/souper +$ CXX=clang++ cmake -DCMAKE_BUILD_TYPE=$buildtype /path/to/souper ``` Again, the build type is optional and defaults to Release. In any case it must match the build type used when compiling the dependencies. @@ -99,6 +99,52 @@ SOUPER_NO_EXTERNAL_CACHE environment variable. Souper's Redis cache does not yet have any support for versioning; you should stop Redis and delete its dump file any time Souper is upgraded. +# Using Souper with Rust/Cargo + +To use souper with Cargo, you need to build your own Rust compiler, specially +configured to use souper's LLVM toolchain. ANd when building souper, we need to +enable dynamic linking both of libLLVM and all the other LLVM libraries: +``` +$ ./build_deps.sh Release -DLLVM_BUILD_LLVM_DYLIB=ON -DBUILD_SHARED_LIBS=ON +``` + +By default, rustc is statically linked with its own fork of LLVM. To change this, +after you've cloned from https://github.com/rust-lang/rust, copy +`config.toml.example` to `config.toml` (or run `./x.py setup`) and set +``` +[target.x86_64-unknown-linux-gnu] # Or whatever your host is +llvm-config = "/path/to/souper/third_party/llvm-Release-install/bin/llvm-config" +``` +and +``` +[llvm] +link-shared = true +``` +Then build Rust with +``` +$ LD_LIBRARY_PATH=/path/to/souper/third_party/llvm-Release-install/lib/ ./x.py build +``` +Once it is built, you can create a souper-powered rustup toolchain with +``` +$ rustup toolchain link souper build/x86_64-unknown-linux-gnu/stage1 +``` + +Passing souper's command line arguments via the `RUSTFLAGS` environment variable +or `cargo rustc` is difficult/impossible because `-Cllvm-args` is +space-delimited. Instead of fighting with a shell, you can place a +`.cargo/config` file, probably in your home directory or in the root of whatever +crate you want to use souper with, which contains this: +``` +[build] +rustflags = ["-Z", "llvm-plugins=/path/to/souper-build/libsouperPass.so", + "-C", "llvm-args=-souper-static-profile=true -souper-external-cache=true"] +``` + +Then you should be able to build a Rust project with souper by: +``` +$ LD_LIBRARY_PATH=/path/to/souper/third_party/llvm-Release-install/lib/ cargo +souper build --release +``` + # Disclaimer Please note that although some of the authors are employed by Google, this diff --git a/build_deps.sh b/build_deps.sh index b8c770d3c..23f6150c7 100755 --- a/build_deps.sh +++ b/build_deps.sh @@ -91,8 +91,15 @@ fi # we want these but they don't get installed by default cp $llvm_builddir/bin/llvm-lit $llvm_installdir/bin cp $llvm_builddir/bin/FileCheck $llvm_installdir/bin -cp $llvm_builddir/lib/libgtest_main.a $llvm_installdir/lib -cp $llvm_builddir/lib/libgtest.a $llvm_installdir/lib +# try to handle both build of static and dynamic libraries +if [ -f $llvm_builddir/lib/libgtest_main.a ] ; then + cp $llvm_builddir/lib/libgtest_main.a $llvm_installdir/lib + cp $llvm_builddir/lib/libgtest.a $llvm_installdir/lib +fi +if [ -f $llvm_builddir/lib/libgtest_main.so ] ; then + cp $llvm_builddir/lib/libgtest_main.so $llvm_installdir/lib + cp $llvm_builddir/lib/libgtest.so $llvm_installdir/lib +fi kleedir=$(pwd)/third_party/klee