gpt4 book ai didi

cmake - 包含子库的现代 CMake 库

转载 作者:行者123 更新时间:2023-12-01 09:59:28 24 4
gpt4 key购买 nike

我有几个库(子项目)作为一个主库的一部分。如何将子库 (b) 聚合到“主库”(a) 中?

目标是只有一个图书馆 a并按如下方式使用子库 #include <b/b.h>

(有没有办法让包含路径如下:#include <a/b/b.h>?)

假设文件夹结构如下:

a
|-- CMakeLists.txt
|-- aConfig.cmake
`-- b
|-- CMakeLists.txt
|-- include
| `-- b
| `-- b.h
`-- src
`-- b.cpp


我有以下图书馆 a取决于图书馆 b .图书馆 a必须安装并因此可以通过 find_package(a CONFIG REQUIRED) 找到以现代 CMake 方式命令。该库不提供任何实现,但应聚合子库。我认为制作 target_include_directories Public会传播 INTERFACE_INCLUDE_DIRECTORIES属性(property)归图书馆a因为它链接到 b但我无法让它工作:

cmake_minimum_required(VERSION 3.0.2)

project(a)

find_package(Eigen3 3.2.2 REQUIRED)

add_subdirectory(b)

## Build
add_library(a)
add_library(a::a ALIAS a)

target_link_library(a
PUBLIC
b::b
)

## Install

include(GNUInstallDirs)

# create export set
install(TARGETS a
EXPORT "aTargets"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)

install(
DIRECTORY
b/include/
DESTINATION
"${CMAKE_INSTALL_INCLUDEDIR}"
)

install(EXPORT "${PROJECT_NAME}Targets"
FILE
"aTargets.cmake"
NAMESPACE
"a::"
DESTINATION
lib/cmake/a
)

install(
FILES
"aConfig.cmake"
DESTINATION
"lib/cmake/a"
)

最佳答案

使用 interface libraries连同 relocatable packages似乎可以解决您的问题。下面是一个最小的工作示例。

假设我们有如下目录结构

.
├── a
│ ├── b
│ │ ├── CMakeLists.txt
│ │ ├── include
│ │ │ └── b
│ │ │ └── b.h
│ │ └── src
│ │ └── b.cpp
│ ├── c
│ │ ├── CMakeLists.txt
│ │ ├── include
│ │ │ └── c
│ │ │ └── c.h
│ │ └── src
│ │ └── c.cpp
│ └── CMakeLists.txt
├── CMakeLists.txt
└── main.cpp

9 directories, 9 files

其中 a 是包含其他子项目的 super 项目。 bc 库的内容如下:

# a/b/CMakeLists.txt
cmake_minimum_required(VERSION 3.9)

project(b CXX)

add_library(b
include/b/b.h
src/b.cpp
)
add_library(b::b ALIAS b)

target_include_directories(b
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

install(TARGETS
b
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
install(DIRECTORY include/b DESTINATION include)

/* a/b/include/b/b.h */
#ifdef __cplusplus
extern "C" {
#endif

double funcb(const double);

#ifdef __cplusplus
}
#endif

/* a/b/src/b.cpp */
#include "b/b.h"

extern "C" {
double funcb(const double x) { return x + x; }
}

# a/c/CMakeLists.txt
cmake_minimum_required(VERSION 3.9)

project(c CXX)

add_library(c
include/c/c.h
src/c.cpp
)
add_library(c::c ALIAS c)

target_include_directories(c
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

install(TARGETS
c
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
install(DIRECTORY include/c DESTINATION include)

/* a/c/include/c/c.h */
#ifdef __cplusplus
extern "C" {
#endif

double funcc(const double);

#ifdef __cplusplus
}
#endif

/* a/c/src/c.cpp */
#include "c/c.h"

extern "C" {
double funcc(const double x) { return x * x; }
}

然后,您只需将 a 设为 INTERFACE 库,如下所示:

# a/CMakeLists.txt
cmake_minimum_required(VERSION 3.9)

project(a)

add_subdirectory(b)
add_subdirectory(c)

add_library(a INTERFACE)
add_library(a::a ALIAS a)
target_link_libraries(a
INTERFACE
b::b
c::c
)

最后,您的应用程序将照常使用 bc 库:

#include <iostream>
using namespace std;

#include "b/b.h"
#include "c/c.h"

int main(int argc, char* argv[]) {
cout << funcb(5) << '\n';
cout << funcc(5) << '\n';
return 0;
}

和相应的CMakeLists.txt会读

cmake_minimum_required(VERSION 3.9)

project(app)

add_subdirectory(a)

add_executable(app main.cpp)
target_link_libraries(app PRIVATE a::a)

希望这能解决您的问题。

关于cmake - 包含子库的现代 CMake 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56058854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com