Halide
Halide copied to clipboard
Add ASAN support to CMake via toolchain file
Perhaps a cleaner approach for ASAN in CMake, this uses a toolchain file to drive clang to run asan -- the point here being that everything participating in the ASAN Party has to use the same version of the same compiler (including the bitcode in our runtime), so this means we pretty much have to use the LLVM-provided clang.
Note that (as written) it will only work on Linux, though it could probably be adapted to work on any posixy system without much work. Since we'd probably only run sanitizer coverage on our Linux bots anyway, this is likely fine.
Note also that it requires building some C++ runtime code in LLVM that we currently don't do by default.
Note also that it currently doesn't test any Python code under ASAN; to make that work, we'd need to use -shared-asan
(vs Clang's default of -static-asan
); in theory that can be made to work, but it requires setting an LD_PRELOAD env var in lots of places across CMake, which is uglier than I'd like, so I have just skipped it for now. (Maybe there's a cleaner way?)
Anyway, if this approach works, we'd probably add more toolchain files for other sanitizers.
Are those exact settings necessary
It didn't work at all until I added those, so, apparently :-)
I have moved the sanitizer environment variables to presets for a few reasons:
- They were complicating our build rules considerably and necessitated hacks in custom commands.
- As environment variables, they can be set externally.
- The build itself succeeds without those variables set.
- We should probably know if the build starts to fail without those set.
Using the preset is easy and should be how we implement this in the buildbots:
$ cmake --preset linux-x64-asan -DLLVM_ROOT=/path/to/llvm
$ cmake --build --preset linux-x64-asan
$ ctest --preset linux-x64-asan
Where /path/to/llvm
is the folder containing bin/clang++
. This sequence of commands works for me on Google infra.
LGTM
With the newest commit, the apps have a corresponding preset. From the apps directory, run:
$ cmake --preset linux-x64-asan -DLLVM_ROOT=/path/to/llvm -DHalide_ROOT=/path/to/halide-install
$ cmake --build --preset linux-x64-asan
$ ctest --preset linux-x64-asan
I note that the apps require the ASAN options set during the build, too. This is also working for me on gLinux.
$ cmake --build --preset linux-x64-asan
grumble, it really doesn't matter, but I am grumpy about not being able to just use ninja
directly here
$ cmake --preset linux-x64-asan -DLLVM_ROOT=/path/to/llvm
Why do we need to set LLVM_ROOT here? The buildbots have set only LLVM_DIR for ~ever.
I am grumpy about not being able to just use
ninja
directly here
For compiling Halide, which doesn't require any env vars to be set, you can just call ninja
. For the apps, you'd need to ASAN_OPTIONS
some other way (have you ever used direnv?)
(have you ever used direnv?)
Yikes, no, magic hidden things that set env vars based on my location is (to me) an indication of a system gone wrong
Yikes, no, magic hidden things that set env vars based on my location is (to me) an indication of a system gone wrong
Eh, I like it for setting some common options locally, but to each their own.
Why do we need to set LLVM_ROOT here? The buildbots have set only LLVM_DIR for ~ever.
To be more on point: it seems suboptimal to have to set two LLVM related config vars here (esp when one can generally be inferred from the other); since LLVM_DIR is already set, is there a compelling reason we can't assume LLVM_ROOT is something like ${LLVM_DIR}/../../.. ?
cmake --build --preset linux-x64-asan
On gLinux, this fails for me with CMake Error: Could not read presets from /usr/local/google/home/srj/GitHub/Halide/build-asan: File not found
is there a compelling reason we can't assume LLVM_ROOT is something like ${LLVM_DIR}/../../.. ?
On Ubuntu, there are two copies of LLVMConfig.cmake
, one in LLVM_ROOT/cmake
and another in LLVM_ROOT/lib/cmake/llvm
. You don't need to set LLVM_DIR
if you set LLVM_ROOT
.
On gLinux, this fails for me with
CMake Error: Could not read presets from /usr/local/google/home/srj/GitHub/Halide/build-asan: File not found
Don't change directory, run all three commands from the root Halide dir.
LGTM
Windows failure is unrelated