Search code examples
c++ccmakeaddress-sanitizer

How to obtain the libasan.so path with Cmake?


I have a shared library in which the tests for a project are located. This is using Cgreen as a test framework. This allows one to run all the tests using the cgreen runner as this:

cgreen-runner my-tests.so

I can do this from CMake pretty easy:

add_test(NAME mytest COMMAND ${CGREEN_EXECUTABLE} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/my-tests.so)

The problem comes when I'm building my-tests.so with ASAN. Because it is a shared library built with ASAN loaded by an executable that's not built with ASAN I have to use LD_PRELOAD in order to load libasan.so (as covered by the ASAN FAQ).

This is easy to do from the command line without needing to know where libasan.so is located, as long as you know the compiler used to compile the tests:

LD_PRELOAD=`gcc -print-file-name=libasan.so` cgreen-runner my-tests.so

I can set LD_PRELOAD from CMake by using set_property:

set_property(TEST mytest PROPERTY ENVIRONMENT "LD_PRELOAD=/path/to/libasan.so")

Obviously, I don't want to have a hardcoded path there. Is there a way to obtain this path when configuring cmake?


Solution

  • You can simply call the command from CMake:

    execute_process(COMMAND gcc -print-file-name=libasan.so
                    OUTPUT_VARIABLE LIBASAN_PATH
                    OUTPUT_STRIP_TRAILING_WHITESPACE)
    

    To catch failures you can pass a RESULT_VARIABLE and check if its value is equal to 0.