提问人:Divelix 提问时间:11/16/2023 最后编辑:Divelix 更新时间:11/20/2023 访问量:82
将两个 cmake 项目并排链接
Link two cmake projects next to each other
问:
假设我有两个 cmake 库: 和 ,其中取决于 。我怎么能不把它们放到一个通用的cmake项目中,这意味着应该只有两个CMakeLists.txt(一个用于lib1,一个用于lib2),而不是将它们链接在一起的通用CMakeLists.txt。lib1
lib2
lib2
lib1
cmake_agnostic_root/
|-- lib1/
| |-- src/
| |-- include/
| |-- CMakeLists.txt
|-- lib2/
| |-- src/
| |-- include/
| |-- CMakeLists.txt
|-- (there must be no CMakeLists.txt on this level)
在我的理解中,CMakeLists.txt 中应该只有一些东西会包含 .lib2
lib1
我尝试了什么(没有任何效果):
- add_subdirectory:
尝试将这一行添加到 cmake:
lib2
add_subdirectory(../lib1 lib1)
但仍然找不到 的标题lib2
lib1
- 外部项目:
尝试将以下行添加到cmake:
lib2
include(ExternalProject)
ExternalProject_Add(
lib1
SOURCE_DIR ../lib1
)
可能我错误地使用此命令,因为在所有示例中它都会下载 git 存储库,但我需要在 旁边使用本地文件夹。lib1
lib2
我做错了什么?
编辑:我想调用cmake触发构建,然后用它来构建。lib2
lib1
lib2
答:
0赞
Divelix
11/16/2023
#1
我在 KISS-ICP 中找到了答案。CMakeLists.txt中应该有这样的函数调用。不知道它有什么作用,但有它的内容:set_global_target_properties
lib1
function(set_global_target_properties target)
target_compile_features(${target} PUBLIC cxx_std_17)
target_compile_definitions(${target} PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,MSVC>:_USE_MATH_DEFINES>)
target_compile_options(
${target}
PRIVATE # MSVC
$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/W4>
$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/WX>
# Clang/AppleClang
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-fcolor-diagnostics>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Werror>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wall>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wextra>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wconversion>
$<$<COMPILE_LANG_AND_ID:CXX,Clang,AppleClang>:-Wno-sign-conversion>
# GNU
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-fdiagnostics-color=always>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Werror>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wall>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wextra>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-pedantic>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wcast-align>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wcast-qual>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wconversion>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wdisabled-optimization>
$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Woverloaded-virtual>)
set(INCLUDE_DIRS ${PROJECT_SOURCE_DIR})
get_filename_component(INCLUDE_DIRS ${INCLUDE_DIRS} PATH)
target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PUBLIC $<BUILD_INTERFACE:${INCLUDE_DIRS}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
endfunction()
1赞
Sergey Vlasov
11/17/2023
#2
我用exe + lib创建了一个测试项目:
cmake_agnostic_root/
|-- app/
| |-- src/
| |-- include/
| |-- CMakeLists.txt
|-- lib/
| |-- src/
| |-- include/
| |-- CMakeLists.txt
|-- (there must be no CMakeLists.txt on this level)
它没有一点丑陋,需要改进,但是一个很好的起点
The exe CMakeList.txt:
project(app)
cmake_minimum_required(VERSION 3.16)
include(ExternalProject)
if (CMAKE_CONFIGURATION_TYPES)
# support multiple configurations: Debug and Release
set(TEST_INSTALL_PREFIX "<INSTALL_DIR>/$<CONFIG>")
set(TEST_LIBRARY_FILE ${CMAKE_BINARY_DIR}/test/$<CONFIG>/lib/test.lib)
set(TEST_LIBRARY_HEADERS ${CMAKE_BINARY_DIR}/test/$<CONFIG>/include)
else()
# single configuration: Debug or Release
set(TEST_INSTALL_PREFIX "<INSTALL_DIR>")
set(TEST_LIBRARY_FILE ${CMAKE_BINARY_DIR}/test/lib/libtest.a)
set(TEST_LIBRARY_HEADERS ${CMAKE_BINARY_DIR}/test/include)
endif()
ExternalProject_Add(test.proj
URL ${CMAKE_CURRENT_SOURCE_DIR}/../lib
PREFIX test
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${TEST_INSTALL_PREFIX}
BUILD_BYPRODUCTS ${TEST_LIBRARY_FILE}
)
add_library(test INTERFACE)
target_include_directories(test INTERFACE ${TEST_LIBRARY_HEADERS})
target_link_libraries(test INTERFACE ${TEST_LIBRARY_FILE})
add_dependencies(test test.proj)
add_executable(app src/main.cpp)
target_link_libraries(app test)
库的 CMakeList.txt:
project(test)
cmake_minimum_required(VERSION 3.16)
add_library(test src/test.cpp)
target_include_directories(test PRIVATE include)
install(TARGETS test DESTINATION lib)
install(FILES include/test.h DESTINATION include)
评论
0赞
Divelix
11/19/2023
我试图遵循您的答案并且命令运行没有错误,但是当我尝试使用内部构建文件夹创建可执行文件时,它会抛出:cmake
make
make[2]: *** No rule to make target 'test//lib/test.lib', needed by 'app'. Stop. make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/app.dir/all] Error 2
0赞
Sergey Vlasov
11/19/2023
我使用了具有 2 种构建配置的 Visual Studio cmake 生成器:调试和发布。在您的情况下,可能没有必要使用 $<CONFIG>
0赞
Sergey Vlasov
11/19/2023
另外,尝试将“BUILD_BYPRODUCTS ${CMAKE_BINARY_DIR}/test/$<CONFIG>/lib/test.lib”添加到ExternalProject_Add中。它指定 test.lib 必须由“test.proj”规则构建。
1赞
Sergey Vlasov
11/19/2023
问题也可能出在库名称上:Windows:test.lib,Linux:libtest.a
1赞
Sergey Vlasov
11/20/2023
我更新了我的示例以使用 Linux 和 Windows (MSVC)。对于 MSVC(Visual Studio cmake 生成器),支持多个生成配置。$<CONFIG> - 只是当前构建配置(调试或发布)的别名
评论
add_subdirectory(../lib1 lib1)
add_subdirectory(../lib1)
find_package
CMAKE_MODULE_PATH
add_subdirectory not given a binary directory but the given source directory lib1 is not a subdirectory of lib2. When specifying an out-of-tree source a binary directory must be explicitly specified.
add_subdirectory(../lib1 ../lib1/build)
CMakeLists.txt
add_subdirectory