Issue
I have authored a library with address sanitizer and "treating warnings as errors" configured in my CMakeLists.txt file
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.1 AND NOT WIN32) # sanitizer
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined")
# target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=all)
# target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined)
endif ()
if (CMAKE_COMPILER_IS_GNUCC AND NOT WIN32) # werror
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -ansi")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -ansi -pedantic")
# target_compile_options(${PROJECT_NAME} PRIVATE -Werror -Wall -ansi)
# target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -ansi -pedantic)
endif ()
option(BUILD_TESTS "Build Tests" ON) # Tests
if (BUILD_TESTS)
enable_testing()
include(CTest)
add_subdirectory(test)
end if()
If you build your lib as a static lib with asan you need to build everything downstream with asan or at least link the asan libs.
As a result, the consumers of the library are also forced to link sanitizer with their builds.
Question:
As a user I don't want to be enforced the compilation flags but then at the same time I need my library to be perfect and sanitized.
An idea occurred, how can I install the debug the version with sanitization but then release version without.
Attempt 1
# Enable AddressSanitizer for Debug builds
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT WIN32) # sanitizer
message(STATUS "Applying AddressSanitizer for Debug build")
target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=all)
target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined)
endif ()
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_COMPILER_IS_GNUCC AND NOT WIN32) # werror
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -ansi")
# target_compile_options(${PROJECT_NAME} PRIVATE -Werror -Wall -ansi)
# target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -ansi -pedantic)
endif ()
Issue
As I consumed this library, and of course applying address sanitizer to my debug build in the consumer (reusing the same code block in my consumer), I still get asan errors. (implying both debug and release versions are applied address sanitizer)
Undefined symbols for architecture x86_64:
"___asan_init", referenced from:
Solution
Based on the comments I have moved my sanitization under the test blocks.
option(BUILD_TESTS "Build Tests" ON) # Tests
if (BUILD_TESTS)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.1 AND NOT WIN32) # sanitizer
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address,undefined -fno-sanitize-recover=all")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address,undefined")
# target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined -fno-sanitize-recover=all)
# target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=address,undefined)
endif ()
if (CMAKE_COMPILER_IS_GNUCC AND NOT WIN32) # werror
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -ansi")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -ansi -pedantic")
# target_compile_options(${PROJECT_NAME} PRIVATE -Werror -Wall -ansi)
# target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -ansi -pedantic)
endif ()
enable_testing()
include(CTest)
add_subdirectory(test)
end if()
This way both release and debug builds are lightweight free to any dependencies while I can assure quality in my local tests before making it available for delivery via VCPKG etc.
Answered By - AppDeveloper Answer Checked By - Gilberto Lyons (WPSolving Admin)