cmake vcpkg地址消毒剂的行业实践

unhi4e5o  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(164)

我编写了一个库,在CMakeLists.txt文件中配置了地址消毒器和“将警告视为错误”

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()

字符串
如果你用asan把你的库构建成静态库,你需要用asan构建下游的一切,或者至少链接asan库。
因此,图书馆的消费者也被迫将消毒剂与他们的构建联系起来。

提问:

作为一个用户,我不想强制执行编译标志,但同时我需要我的库是完美的和消毒。
一个想法出现了,我怎么能安装调试版本与消毒,但然后释放版本没有。

尝试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 ()


问题
当我使用这个库时,当然,在消费者中将地址消毒器应用于我的调试构建(在消费者中重用相同的代码块),我仍然得到一个错误。(这意味着调试和发布版本都应用了地址消毒器)

Undefined symbols for architecture x86_64:
  "___asan_init", referenced from:

kmbjn2e3

kmbjn2e31#

根据评论,我已将我的清理移至测试块下。

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()

字符串
通过这种方式,发布和调试构建都是轻量级的,不受任何依赖关系的影响,同时我可以在通过VCPKG等交付之前确保本地测试的质量。

相关问题