Reputation: 4453
I'm trying to use the Address Sanitizer in Xcode, but I'm also using ccache to accelerate my builds. To do this, I've set the CC
flag at the Xcode-project-level to point to a script I'm storing at ~/projects/support/cmake/ccache-clang
. The script reads
#!/bin/sh
if type -p /usr/local/bin/ccache >/dev/null 2>&1; then
export CCACHE_CPP2=true
exec /usr/local/bin/ccache "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" "$@"
else
exec "${DEVELOPER_DIR}/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" "$@"
fi
so the desired effect is achieved (ccache is used if installed on the dev's system). This is working well.
Now the problem comes when we turn on the Address Sanitizer for a given scheme. The build completes successfully, but then we finally see this error when we try to run:
Error: Check dependencies
Could not determine version of clang to find its Address Sanitizer library: ~/projects/support/cmake/ccache-clang
Perhaps this is due to some hacky implementation in Xcode where it tries to parse the compiler's path to determine the version?
Wondering how I can modify my script to allow Address Sanitizer to work. The current work around is to remove the overridden CC
flag when we need to do sanitizer work.
Using Xcode 8.3.1
Upvotes: 6
Views: 1681
Reputation: 91
I was able to make it work. Tested with Xcode 14.2 and 15.3
ccache-clang
must be renamed to clang
and clang++
(i.e. clang++
is copy of clang
). It seems that Xcode first of all tries to detect compiler's name: clang, gcc, etc., so naming the script like this makes Xcode to decide that this is clang. Also I use CMAKE_XCODE_ATTRIBUTE_
properties to set CC
, CXX
, etc.:set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/clang")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/clang++")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/clang")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/clang++")
set (_toolchain_root "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
# Following libraries are for iOS/Simulator.
# For MacOS it should be libclang_rt.*an_osx*_dynamic.dylib
file (GLOB_RECURSE _asan_libs
"${_toolchain_root}/*/libclang_rt.*an_ios*_dynamic.dylib")
foreach (_asan_lib IN LISTS _asan_libs)
file (RELATIVE_PATH _asan_relative_to_toolchain
"${_toolchain_root}/usr/" "${_asan_lib}")
configure_file ("${_asan_lib}"
"${CMAKE_BINARY_DIR}/../${_asan_relative_to_toolchain}"
COPYONLY)
endforeach ()
After this I was able to enable sanitisers from Xcode, compile and run the app.
UPD: The demo project for iOS and MacOS is here https://github.com/Hsilgos/xcode-ccache-demo
Upvotes: 2
Reputation:
Link the Asan library directly instead of the checking the box in the scheme.
The linker and compiler flags should contain the following.
-fsanitize=address -fno-omit-frame-pointer
If it cannot find the library, find the path to the asan dynamic library which is usually in
${CMAKE_LINKER}/../../lib/clang/version/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
and add it to linker flags.
Upvotes: 2