#cmake
#cmake
Вопрос:
У меня есть небольшой проект с cmake. Я создаю библиотеку и исполняемый файл. на компьютере разработки я также хочу исполняемый файл, который нельзя создать на других машинах / средах.
например:
<my-lib>
| -- CMakeLists.txt
|
-- src/ -> build the lib/archive
| |-- lib.c
| |-- lib.h
| |-- CMakeLists.txt
|
-- tool -> build the tool
| |-- tool.c
| |-- CMakeLists.txt
|
-- tests -> build the unit tests
| |-- tests.c
| |-- CMakeLists.txt
Я добавил CMakeLists.txt
во все каталоги. Также add_executable
к тестам. Теперь исполняемый файл модульного теста создается по умолчанию. Но я хочу исключить его из целевого объекта по умолчанию.
CMakeLists.txt
в tests
:
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
Есть ли у кого-нибудь подсказка, как с этим справиться? Я не хочу всегда создавать модульный тест!
Комментарии:
1. Не используйте
PROJECT_SOURCE_DIR
для включения. Если кто-нибудь добавит ваш проект в качестве подкаталога, он будет иметь значение, которого вы не ожидаете. Лучше использовать явное имя<name>_SOURCE_DIR
или CMAKE_CURRENT_LIST_DIR2.
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
если пользователь захочет определить пользовательские флаги компилятора, он будет потерян. Чтобы исправить это, используйте:set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -Wall -Werror")
Ответ №1:
Для такой задачи есть свойство EXCLUDE_FROM_ALL.
Вы можете написать:
set_target_properties(unit-test PROPERTIES EXCLUDE_FROM_ALL TRUE)
Ответ №2:
Это очень просто: защитите создание исполняемого файла, введя параметр / переменную.
if (DEFINED WITH_UNIT_TEST)
find_library (CUNIT_LIB cunit)
include_directories (${Cunit_INCLUDE_DIRS} "${PROJECT_SOURCE_DIR}/src")
set (CMAKE_C_FLAGS "-O2 -Wall -Werror")
add_executable (unit-test tests.c)
target_link_libraries (unit-test my-lib cunit)
endif ()
Теперь при вызове CMake нужно было бы явно указать, -DWITH_UNIT_TEST
чтобы unit-test
цель была собрана, в то время как по умолчанию она никогда не будет собрана. Альтернативный подход см. В комментариях.
Комментарии:
1. И для тех, кто любит графический интерфейс: рассмотрите возможность добавления опции для удобного переключения без необходимости запоминать точный переключатель командной строки.
2. Я добавил
option (WITH_UNIT_TEST "enable building unit test executable" OFF)
, как указано, на верхний уровень CMakeLists.txt . В этом случае я должен изменить проверкуif (DEFINED WITH_UNIT_TEST)
наif (WITH_UNIT_TEST)
, потому что значение всегда определяется и инициализируется с помощьюOFF
.3. Да, конечно, если вы используете
option
то, что предлагает @ComicSansMS, тогда вам придется проверять это безDEFINED
, тем не менее логика решения абсолютно такая же.4. Также вы можете сделать
add_executable (unit-test EXCLUDE_FROM_ALL tests.c)