#c #cmake #c 20 #header-only
#c #cmake #c 20 #только для заголовков
Вопрос:
Я создаю облегченную библиотеку только для заголовков для сопрограмм в C 20 под названием Conduit. Структура библиотеки выглядит следующим образом, и у нее нет зависимостей, отличных от стандартной библиотеки C :
conduit
|
|---CMakeLists.txt
|
|---tests/tests.cpp
|
|---include/conduit/
|---coroutine.hpp
|---future.hpp
|---[Other header files...]
Вопрос: Как мне написать CMakeLists.txt файл для моей библиотеки, чтобы другие проекты могли использовать Conduit, добавив его в качестве подкаталога через add_subdirectory
?
Хотя conduit предоставляет опцию установки, предполагаемый способ использования conduit — добавить его в качестве подкаталога внутри своего проекта. Внутри CMakeLists.txt папка для example_project, там была бы строка add_subdirectory(conduit)
, а структура каталогов example_project
выглядела бы примерно так:
example_project
|
|---CMakeLists.txt
|
|---src/...
|
|---include/...
|
|---conduit
|
|---CMakeLists.txt
|
|---tests/tests.cpp
|
|---include/conduit/
|---coroutine.hpp
|---future.hpp
|---[Other header files...]
Что у меня есть до сих пор: это то, что я в настоящее время использую в качестве CMakeLists.txt файл для канала. Он компилируется и запускается tests.cpp с множеством различных тестов, но когда я добавляю conduit в качестве подкаталога в другой проект (через подмодуль git add_subdirectory
в CMakeLists.txt ), CMake не добавляет conduit/ include/ в список включенных файлов.
cmake_minimum_required(VERSION 3.0.0)
project(conduit VERSION 0.3.0 LANGUAGES CXX)
option(CONDUIT_Install "Install CMake targets during install step." ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" )
add_compile_options("/std:c latest" "/await" "/EHsc")
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
add_compile_options("-std=c 20")
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
add_compile_options("-std=c 20" "-fcoroutines")
endif()
include_directories(include)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CONDUIT_TARGET_NAME ${PROJECT_NAME})
set(CONDUIT_INCLUDE_BUILD_DIR "${PROJECT_SOURCE_DIR}/include/")
add_library(${CONDUIT_TARGET_NAME} INTERFACE)
target_compile_definitions(
${CONDUIT_TARGET_NAME}
INTERFACE
)
target_include_directories(
${CONDUIT_TARGET_NAME}
INTERFACE
$<BUILD_INTERFACE:${CONDUIT_INCLUDE_BUILD_DIR}>
$<INSTALL_INTERFACE:include>
)
install(
DIRECTORY ${CONDUIT_INCLUDE_BUILD_DIR}
DESTINATION include
)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
endif()
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
add_executable(run_tests tests/tests.cpp)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(run_tests PRIVATE Threads::Threads)
foreach(X IN ITEMS
test_coroutine
test_destroy
test_exception_1
test_exception_2
test_future
test_generator
test_on_suspend
test_recursive_generator
test_resume_on_alternate_thread
test_source
test_suspend_invoke
test_task)
add_test(NAME "${X}" COMMAND run_tests "${X}")
endforeach()
endif()
Комментарии:
1. Вам вообще не нужно
include_directories
, поскольку вы используетеtarget_include_directories
. Добавляются ли какие-либо включаемые каталоги при использовании conduit?2. Когда другой проект использует conduit через add_subdirectory, он не добавляет conduit / include в список включенных каталогов этого проекта, как предполагалось. Это то, что я пытаюсь исправить.
3. Я понимаю это, поэтому я спрашиваю, будет ли добавлено что -нибудь. Когда у меня была эта проблема в прошлом, это потому, что у меня были неправильные параметры в
target_include_directories
.4. Это ничего не добавляло к команде компиляции. Я обнаружил, что если я добавлю target_link_libraries в CMakeLists для проекта, включающего conduit, он будет включать conduit, но ни один из параметров компилятора, которые я настроил в conduit, не будет распространен (нужно ли мне использовать target_compile_options?)