Ошибка в cmake, программа компилируется без нужных флагов
cmake_minimum_required(VERSION 3.0.0)
project(Tanks VERSION 0.1.0)
option(ENABLE_UNIT_TESTS "Enable unittest" ON)
message(STATUS "Enable testing: ${ENABLE_UNIT_TESTS}")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
if(NOT SDL2_IMAGE_FOUND)
message(FATAL_ERROR "SDL2_IMAGE NOT FOUND")
return()
endif()
if(NOT SDL2_FOUND)
message(FATAL_ERROR "SDL2 NOT FOUND")
return()
else()
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} headers/)
file(GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
add_executable(main ${SOURCES})
set_target_properties(main
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
CMAKE_CXX_STANDARD_REQUIRED ON
CMAKE_CXX_STANDARD 17
CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -std=c++17"
CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -g -fsanitize=address -fsanitize=leak" #<-- Нужный мне флаг!
CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O2"
) #<--Мотни скролбар снизу вправо, коммент выше не помещается
target_compile_options(main PUBLIC ${CMAKE_CXX_FLAGS_DEBUG}) #<-- Добавляю флаг!
target_link_libraries(main
${SDL2_LIBRARIES}
${SDL2_IMAGE_LIBRARIES})
message(STATUS "Copy sprites folder")
file(COPY Sprites DESTINATION .)
if(ENABLE_UNIT_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
endif()
Мне нужно собрать программу с флагом санитайзера, прочитал, добавил флаги в cmake, но 0 реакции, хочу разобраться, что же я делаю неверно. Если запустить cmake командой:
cmake .. -DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=leak"
То все работает, я вижу вывод санитайзера, но что я прописал в cmake не так - понять не могу
Ответы (1 шт):
Различные ошибки, неточности и плохие практики
cmake_minimum_required(VERSION 3.0.0)
3.0.0 — это довольно древняя версия и, если нет особых причин придерживаться какой-либо более старой версии, хорошей практикой будет указывать версию CMake своей системы. В любом случае не стоит указывать ту версию, на которой сборка не тестировалась.
if(NOT SDL2_IMAGE_FOUND)
т.к. find_package вызван с параметром REQUIRED, то эта проверка излишняя.
file(GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
Использовать GLOB для получения списка исходников — плохая практика. См. примечание к file(GLOB ...).
set_target_properties(main PROPERTIES ... CMAKE_CXX_STANDARD_REQUIRED ON ...
Свойства с именем CMAKE_CXX_STANDARD_REQUIRED и подобные не существуют. Есть одноимённые переменные СMake, но через set_target_properties их установить нельзя. Список свойств можно посмотреть в man 7 cmake-properties.
Мне бы по дефолту собирать с санитайзером
ИМХО это плохая практика. Санитайзер — тяжёлая и накладная штука и сборка с ним по умолчанию — неожиданный результат обычных действий.
Как бы я это сделал
cmake_minimum_required(VERSION 3.18.5)
project(Tanks VERSION 0.1.0)
option(ENABLE_UNIT_TESTS "Enable unittest" ON)
option(ENABLE_SANITIZER "Pass -fsanitize=address and -fsanitize=leak to compiller" OFF)
message(STATUS "Enable testing: ${ENABLE_UNIT_TESTS}")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} headers/)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -pedantic")
if(ENABLE_SANITIZER)
string(APPEND CMAKE_CXX_FLAGS " -fsanitize=address -fsanitize=leak")
string(APPEND CMAKE_LINKER_FLAGS " -fsanitize=address -fsanitize=leak")
endif()
string(APPEND CMAKE_CXX_FLAGS " -Wall -Wextra -pedantic")
# Нет смысла задавать все эти переменные для каждой отдельной цели;
# если они нужны, то лучше сделать их общими
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(SOURCES src/foo.cpp src/bar.cpp
... # и другие исходники
)
add_executable(main ${SOURCES})
target_link_libraries(main
${SDL2_LIBRARIES}
${SDL2_IMAGE_LIBRARIES})
message(STATUS "Copy sprites folder")
file(COPY Sprites DESTINATION .)
if(ENABLE_UNIT_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
Соответственно сборка с санитайзером будет выглядеть как
cmake /path/to/build -DENABLE_SANITIZER=ON
Если уж очень хочется включить сборку с санитайзаером по умолчанию, то можно поменять OFF на ON в объяввлении опции ENABLE_SANITIZER.