从根目录或子目录构建项目的 CMake 配置
CMake configuration to build a project from root or from subdirectories
我最近开始使用 CMake(2.8.12.2,CentOS 6.8 中包含的那个),我认为它足够强大,可以帮助完成我想要的东西,但我一直无法弄清楚如何: -),所以我呼吁你的智慧帮我找到缺失的点。
我有这样的项目布局:
BaseDir
|
+-->bin (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->lib (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->CMakeLists.txt
|
+-->Library_A
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Library_B (depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Application_1 (depends on Library_B, hence transitivitely depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| |
| +-->CMakeLists.txt
|
+-->Application_2 (depends on Library_A)
|
+-->CMakeLists.txt
+-->include
+-->src
|
+-->CMakeLists.txt
当我将自己置于 BaseDir 和 运行 "cmake ." 下时,它就像一个魅力。 Application_1、Application_2、Library_A 和 Libray_B 都是按照正确的顺序构建、链接等
不过,我的想法是站在任何一个子目录(Application_、Library_)下也能构建,那样的话,只构建相关的代码它(意味着它本身,它的测试和它的依赖)。例如,当站在 Library_A 里面时,只有那个文件夹被构建,而来自 Library_B,Library_A 也被构建,和站在 Application_1 或 Application_2。另外,独立于我触发 cmake 过程的位置,构建结果(libs 或 bins)必须始终放置在 BaseDir/{lib|bin}/{Debug/Release/etc} 下,绝不能放置在 libraries 或 applications 子目录下.这意味着,例如,Library_B(取决于 Library_A)或 Application_1(取决于 Library_A 和 B)的链接必须查看 BaseDir/lib/{Debug/Release}.
我的目标是在 BaseDir 下有很多应用程序,所以如果不是真的需要,我想避免每次都构建它们,只是我想要的单个应用程序。
我调查了 CMakeLists.txt files for multiple libraries and executables and also CMake and finding other projects and their dependencies,但这与我在这里试图实现的情况并不完全相同。
我试过类似下面的方法:
BaseDir/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (BASE_DIR)
|
| add_subdirectory (Library_A) # No local dependencies
| add_subdirectory (Library_B) # Depends on A
| add_subdirectory (Application_1) # Depends on A and B
| add_subdirectory (Application_2) # Depends on A
|
| # I want all binary outputs (executables and libraries) placed under BaseDir/{lib|bin}/{Debug|Release}
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}") # For the executables
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
|
+-->BaseDir/Library_A/CMakeLists.txt (again, no dependencies)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_A)
| |
| | # In case CMake is run from within BaseDir/Library_A and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_A/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_A_SRCS "*.h" "*.cpp")
| |
| | # Create a library called libA.a
| | add_library(A ${LIB_A_SRCS})
| |
| +-->BaseDir/Library_A/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_A_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources
| add_executable(TEST_A ${TEST_A_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_A A)
|
+-->BaseDir/Library_B/CMakeLists.txt (dependency on A)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_B)
| |
| | # In case CMake is run from within BaseDir/Library_B and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_B/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_B_SRCS "*.h" "*.c")
| |
| | # Create a library called libB.a
| | add_library(B ${LIB_B_SRCS})
| |
| | # Add a dependency to Library_A
| | find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_A)
| | include_directories("$LIB_A_INCLUDE_DIRECTORIES")
| | target_link_libraries(B ${LIBRARY_A})
| |
| +-->BaseDir/Library_B/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_B_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources, for both versions of the library
| add_executable(TEST_B ${TEST_B_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_B B)
|
+-->BaseDir/Application_1/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (APP_1)
| |
| | # In case CMake is run from within BaseDir/Application_1 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | # In this case, only executables are generated.
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
| |
| | include_directories(include)
| | add_subdirectory (src)
| |
| +-->BaseDir/Application_1/src/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB APP_1_SRCS "*.cpp")
|
| # Create an executable file from sources
| add_executable(EXE_1 ${APP_1_SRCS})
|
| # This should automatically bring Library_A
| find_library(LIBRARY_B B PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_B)
| include_directories(${LIB_B_INCLUDE_DIRECTORIES})
| target_link_libraries(EXE_1 ${LIBRARY_B})
|
+-->BaseDir/Application_2/CMakeLists/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (APP_2)
|
| # In case CMake is run from within BaseDir/Application_2 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| # In this case, only executables are generated.
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
|
| include_directories(include)
| add_subdirectory (src)
|
+-->BaseDir/Application_2/src/CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
# add all files in the current directory
file(GLOB APP_2_SRCS "*.cpp")
# Create an executable file from sources
add_executable(EXE_2 ${APP_2_SRCS})
# Link this executable to the library it needs
find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}../../Library_A)
include_directories(${LIB_A_INCLUDE_DIRECTORIES})
target_link_libraries(EXE_2 ${LIBRARY_A})
但没有运气,因为当我从子目录(例如,BaseDir/Application_1)运行时,我只得到:
CMake错误:本项目中使用了以下变量,但它们被设置为NOTFOUND。
请设置它们或确保在 CMake 文件中正确设置和测试它们:
LIBRARY_B
我想 "find_library()" 调用不足以满足我的需求,这基本上是加载库项目中包含的所有设置,不仅包括库本身,还有该库添加的包含目录。 find_library() 的确切用法是什么,将其指向创建库的项目位置,或实际生成的库(“.a”或“.so")?
所以,我的主要疑问是:这种布局可行吗?如果是这样,我错过了什么?我应该使用 find_package() 还是 find_path()?如何从另一个 "same level" CMakeLists.txt 触发对 CMakeLists.txt 配置文件的解析?
PS:我真的需要在任何时候考虑使用 "add_dependencies()" 吗?如果不是,该命令有什么意义?
首先是一条一般性建议:在 CMake 中,您总是希望尝试将构建目录与源目录严格分开。特别是,您永远不应该将文件写回源目录作为构建过程的一部分。编写您的脚本,以便它们也可以与挂载在只读文件系统上的源目录一起使用。虽然乍一看这似乎是一个任意限制,但它实际上可以帮助您避免在漫长的 运行.
过程中遇到的许多麻烦。
至于你的实际问题:find_library
是一个非常低级的解决依赖问题的工具。这里的想法基本上是您在系统某处安装了第三方库(它本身对 CMake 一无所知)的二进制文件,并且您知道需要通过检查文件系统的内容来简单地找到它们。这里不是这种情况,因为您将依赖项构建为同一 CMake 配置 运行.
的一部分
你想做的是直接依赖于依赖的目标。所以不要这样做:
find_library(LIBRARY_A A)
target_link_libraries(B ${LIBRARY_A})
直接写
target_link_libraries(B A)
这当然只有在 A
是一个已知目标的情况下才有效,这是你应该关注的问题。
只要您继续将这些库作为同一个 CMake 的一部分一起构建 运行,这就非常简单:如果目标是由父目录或同级目录添加的,您应该能够使用它马上。使您的情况复杂化的是,您还希望能够单独构建不同的库。这意味着您需要一种将目标导入到您的构建中的机制,以便它看起来好像该目标再次作为同一 CMake 的一部分生成 运行.
您可以通过添加 imported target and setting its interface properties, or you can use CMake's packaging mechanism 以自动方式完成此操作来手动执行此操作。请注意,实现这些都不是微不足道的,因此您可能希望从简单的情况开始,即一切都发生在一个 CMake 运行 中,然后在您熟悉使用 CMake 后添加对分离构建的支持。
我最近开始使用 CMake(2.8.12.2,CentOS 6.8 中包含的那个),我认为它足够强大,可以帮助完成我想要的东西,但我一直无法弄清楚如何: -),所以我呼吁你的智慧帮我找到缺失的点。
我有这样的项目布局:
BaseDir
|
+-->bin (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->lib (generated by the process)
| |
| +-->Debug
| +-->Release
|
+-->CMakeLists.txt
|
+-->Library_A
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Library_B (depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| | |
| | +-->CMakeLists.txt
| |
| +-->test # Small binary to test solely the library functions
| |
| +-->CMakeLists.txt
|
+-->Application_1 (depends on Library_B, hence transitivitely depends on Library_A)
| |
| +-->CMakeLists.txt
| +-->include
| +-->src
| |
| +-->CMakeLists.txt
|
+-->Application_2 (depends on Library_A)
|
+-->CMakeLists.txt
+-->include
+-->src
|
+-->CMakeLists.txt
当我将自己置于 BaseDir 和 运行 "cmake ." 下时,它就像一个魅力。 Application_1、Application_2、Library_A 和 Libray_B 都是按照正确的顺序构建、链接等
不过,我的想法是站在任何一个子目录(Application_、Library_)下也能构建,那样的话,只构建相关的代码它(意味着它本身,它的测试和它的依赖)。例如,当站在 Library_A 里面时,只有那个文件夹被构建,而来自 Library_B,Library_A 也被构建,和站在 Application_1 或 Application_2。另外,独立于我触发 cmake 过程的位置,构建结果(libs 或 bins)必须始终放置在 BaseDir/{lib|bin}/{Debug/Release/etc} 下,绝不能放置在 libraries 或 applications 子目录下.这意味着,例如,Library_B(取决于 Library_A)或 Application_1(取决于 Library_A 和 B)的链接必须查看 BaseDir/lib/{Debug/Release}.
我的目标是在 BaseDir 下有很多应用程序,所以如果不是真的需要,我想避免每次都构建它们,只是我想要的单个应用程序。
我调查了 CMakeLists.txt files for multiple libraries and executables and also CMake and finding other projects and their dependencies,但这与我在这里试图实现的情况并不完全相同。
我试过类似下面的方法:
BaseDir/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (BASE_DIR)
|
| add_subdirectory (Library_A) # No local dependencies
| add_subdirectory (Library_B) # Depends on A
| add_subdirectory (Application_1) # Depends on A and B
| add_subdirectory (Application_2) # Depends on A
|
| # I want all binary outputs (executables and libraries) placed under BaseDir/{lib|bin}/{Debug|Release}
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE}") # For the executables
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
|
+-->BaseDir/Library_A/CMakeLists.txt (again, no dependencies)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_A)
| |
| | # In case CMake is run from within BaseDir/Library_A and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_A/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_A_SRCS "*.h" "*.cpp")
| |
| | # Create a library called libA.a
| | add_library(A ${LIB_A_SRCS})
| |
| +-->BaseDir/Library_A/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_A_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources
| add_executable(TEST_A ${TEST_A_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_A A)
|
+-->BaseDir/Library_B/CMakeLists.txt (dependency on A)
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (LIB_B)
| |
| | # In case CMake is run from within BaseDir/Library_B and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}") # For the test executables
| | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the static libraries
| | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib/${CMAKE_BUILD_TYPE}") # For the dynamic libraries
| |
| | include_directories(include)
| | add_subdirectory (src)
| | add_subdirectory (test)
| | set(${PROJECT_NAME}_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
| |
| +-->BaseDir/Library_B/src/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| |
| | # add all files in the current directory
| | file(GLOB LIB_B_SRCS "*.h" "*.c")
| |
| | # Create a library called libB.a
| | add_library(B ${LIB_B_SRCS})
| |
| | # Add a dependency to Library_A
| | find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_A)
| | include_directories("$LIB_A_INCLUDE_DIRECTORIES")
| | target_link_libraries(B ${LIBRARY_A})
| |
| +-->BaseDir/Library_B/test/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB TEST_B_SRCS "*.h" "*.cpp")
|
| # Create an executable file from sources, for both versions of the library
| add_executable(TEST_B ${TEST_B_SRCS})
|
| # Link this executable to the library it's testing
| target_link_libraries(TEST_B B)
|
+-->BaseDir/Application_1/CMakeLists.txt
| |
| | cmake_minimum_required (VERSION 2.8)
| | project (APP_1)
| |
| | # In case CMake is run from within BaseDir/Application_1 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| | # In this case, only executables are generated.
| | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
| |
| | include_directories(include)
| | add_subdirectory (src)
| |
| +-->BaseDir/Application_1/src/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
|
| # add all files in the current directory
| file(GLOB APP_1_SRCS "*.cpp")
|
| # Create an executable file from sources
| add_executable(EXE_1 ${APP_1_SRCS})
|
| # This should automatically bring Library_A
| find_library(LIBRARY_B B PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../../Library_B)
| include_directories(${LIB_B_INCLUDE_DIRECTORIES})
| target_link_libraries(EXE_1 ${LIBRARY_B})
|
+-->BaseDir/Application_2/CMakeLists/CMakeLists.txt
|
| cmake_minimum_required (VERSION 2.8)
| project (APP_2)
|
| # In case CMake is run from within BaseDir/Application_2 and not from BaseDir, I still want the outputs being placed under BaseDir/{lib|bin}/{Debug|Release}
| # In this case, only executables are generated.
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/${CMAKE_BUILD_TYPE}")
|
| include_directories(include)
| add_subdirectory (src)
|
+-->BaseDir/Application_2/src/CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
# add all files in the current directory
file(GLOB APP_2_SRCS "*.cpp")
# Create an executable file from sources
add_executable(EXE_2 ${APP_2_SRCS})
# Link this executable to the library it needs
find_library(LIBRARY_A A PATHS ${CMAKE_CURRENT_SOURCE_DIR}../../Library_A)
include_directories(${LIB_A_INCLUDE_DIRECTORIES})
target_link_libraries(EXE_2 ${LIBRARY_A})
但没有运气,因为当我从子目录(例如,BaseDir/Application_1)运行时,我只得到:
CMake错误:本项目中使用了以下变量,但它们被设置为NOTFOUND。 请设置它们或确保在 CMake 文件中正确设置和测试它们: LIBRARY_B
我想 "find_library()" 调用不足以满足我的需求,这基本上是加载库项目中包含的所有设置,不仅包括库本身,还有该库添加的包含目录。 find_library() 的确切用法是什么,将其指向创建库的项目位置,或实际生成的库(“.a”或“.so")?
所以,我的主要疑问是:这种布局可行吗?如果是这样,我错过了什么?我应该使用 find_package() 还是 find_path()?如何从另一个 "same level" CMakeLists.txt 触发对 CMakeLists.txt 配置文件的解析?
PS:我真的需要在任何时候考虑使用 "add_dependencies()" 吗?如果不是,该命令有什么意义?
首先是一条一般性建议:在 CMake 中,您总是希望尝试将构建目录与源目录严格分开。特别是,您永远不应该将文件写回源目录作为构建过程的一部分。编写您的脚本,以便它们也可以与挂载在只读文件系统上的源目录一起使用。虽然乍一看这似乎是一个任意限制,但它实际上可以帮助您避免在漫长的 运行.
过程中遇到的许多麻烦。至于你的实际问题:find_library
是一个非常低级的解决依赖问题的工具。这里的想法基本上是您在系统某处安装了第三方库(它本身对 CMake 一无所知)的二进制文件,并且您知道需要通过检查文件系统的内容来简单地找到它们。这里不是这种情况,因为您将依赖项构建为同一 CMake 配置 运行.
你想做的是直接依赖于依赖的目标。所以不要这样做:
find_library(LIBRARY_A A)
target_link_libraries(B ${LIBRARY_A})
直接写
target_link_libraries(B A)
这当然只有在 A
是一个已知目标的情况下才有效,这是你应该关注的问题。
只要您继续将这些库作为同一个 CMake 的一部分一起构建 运行,这就非常简单:如果目标是由父目录或同级目录添加的,您应该能够使用它马上。使您的情况复杂化的是,您还希望能够单独构建不同的库。这意味着您需要一种将目标导入到您的构建中的机制,以便它看起来好像该目标再次作为同一 CMake 的一部分生成 运行.
您可以通过添加 imported target and setting its interface properties, or you can use CMake's packaging mechanism 以自动方式完成此操作来手动执行此操作。请注意,实现这些都不是微不足道的,因此您可能希望从简单的情况开始,即一切都发生在一个 CMake 运行 中,然后在您熟悉使用 CMake 后添加对分离构建的支持。