如何在CMake中自动链接本地生成的库或导入的库

How to link local generated library or imported library automatically in CMake

本文关键字:导入 链接 CMake      更新时间:2023-10-16

下面是我们项目的简单版本:

project/
├── CMakeLists.txt
├── dependency
│   └── CMakeLists.txt
├── factory_test
│   ├── CMakeLists.txt
│   └── FactoryTest.cpp
├── install
│   ├── include
│   │   └── locator
│   └── lib
│       └── locator
└── locator
├── CMakeLists.txt
├── Locator.cpp
└── Locator.h

CMakeList 的内容.txt依赖项:

cmake_minimum_required(VERSION 3.12)
project(dependency)
function(import_lib lib_name lib_dir_name)
add_library(${lib_name} STATIC IMPORTED GLOBAL)
set_target_properties(${lib_name} PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/install/include
IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/install/lib/${lib_dir_name}
IMPORTED_IMPLIB ${CMAKE_SOURCE_DIR}/install/lib/${lib_dir_name})
endfunction()
import_lib(import_locator locator/liblocator.a)

CMakeLists的内容.txt factory_test:

cmake_minimum_required(VERSION 3.12)
project(factory_test)
add_library(factory_test FactoryTest.cpp)
target_link_library(factory_test PUBLIC import_locator)

CMake列表的内容.txt定位器:

cmake_minimum_required(VERSION 3.12)
project(locator)
add_libary(locator Locator.cpp)
install(FILES Locator.h ${CMAKE_SOURCE_DIR}/install/include/locator)
install(TARGET locator ${CMAKE_SOURCE_DIR}/install/lib/locator)

热门CMakeList的内容.txt:

cmake_minimum_required(VERSION 3.12)
project(test_project)
add_subdirectory(dependency)
add_subdirectory(locator)
add_subdirectory(factory_test)

依赖关系层次结构factory_test依赖于依赖关系。我们想在顶部目录构建项目。我们编写 CMake 的目的是我们希望所有子目录都依赖于安装目录,以便我们可以构建任何一个子目录,而无需它的依赖子目录。

我们对这个 CMake 提案的问题是,如果修改了定位器的接口,并且我们想在顶级目录中构建项目,它将失败。因为定位器库仍未导出到安装目录。我们目前的方法是首先构建定位器并将其导出以进行安装,然后构建所有其他目标。

所以我想知道如果定位器目录存在,CMa factory_test ke 是否可以动态链接到本地生成的定位器库,或者如果目录不存在,或者有更好的 CMake 建议,则 CMake 是否可以动态链接到导入的定位器库这个问题?

希望熟悉这方面的人能给我们一些建议。感谢您的提前。

您可以在factory_test/CMakeLists.txt中放置一个if语句来检查locator目录是否存在。这将确定是直接链接到locatorCMake 目标,还是链接到导入的定位器目标。

cmake_minimum_required(VERSION 3.12)
project(factory_test)
add_library(factory_test FactoryTest.cpp)
# Check if the 'locator' directory exists.
if(EXISTS ${CMAKE_SOURCE_DIR}/locator)
target_link_library(factory_test PUBLIC locator)
else()
target_link_library(factory_test PUBLIC import_locator)
endif()

您可能需要调整 if 语句中的检查,因为从您的描述中不清楚哪些目录/文件可以访问,哪些不可访问。另外,我想您可能希望在顶级CMake文件中进行类似的检查,因为默认情况下它将遍历到locator目录。