【发布时间】:2023-03-18 12:11:02
【问题描述】:
在 CMake 中有没有办法为具有不同静态依赖项的多个目标使用库? 为了更好地解释它,考虑这个最小的例子:我想要两个可执行文件:第一个应该打印“YES”,第二个应该打印“NO”。为此,我使用库“printsth”,它打印“某物”。它打印的字符串来自“用户”(printyes 或 printno)提供的头文件。这看起来像这样:
├── apps
│ ├── printno
│ │ ├── CMakeLists.txt
│ │ │ add_executable(printno main.cpp)
│ │ │ target_link_libraries(printno PRIVATE printsth)
│ │ │
│ │ ├── main.cpp
│ │ │ #include "printsth/printsth.h"
│ │ │
│ │ │ int main() {
│ │ │ printsth();
│ │ │ return 0;
│ │ │ }
│ │ │
│ │ └── print_usr.h
│ │ #define USR_STRING "NO"
│ │
│ └── printyes
│ │ ├── CMakeLists.txt
│ │ │ add_executable(printyes main.cpp)
│ │ │ target_link_libraries(printyes PRIVATE printsth)
│ │ │
│ │ ├── main.cpp
│ │ │ #include "printsth/printsth.h"
│ │ │
│ │ │ int main() {
│ │ │ printsth();
│ │ │ return 0;
│ │ │ }
│ │ │
│ │ └── print_usr.h
│ │ #define USR_STRING "YES"
│ │
├── extern
│ └── printsh
│ ├── include
│ │ └── printsh
│ │ └── printsh.h
│ │ void printsth();
│ │
│ ├── src
│ │ ├── CMakeLists.txt
│ │ │ add_library(printsth printsth.cpp)
│ │ │ target_include_directories(printsth PUBLIC ../include)
│ │ │
│ │ └── printsh.cpp
│ │ #include "printsth/printsth.h"
│ │ #include "print_usr.h"
│ │ #include <iostream>
│ │
│ │ void printsth() {
│ │ std::cout << USR_STRING << std::endl;
│ │ }
│ │
│ └── CMakeLists.txt
│ cmake_minimum_required(VERSION 3.11...3.16)
│
│ project(printsh
│ VERSION 0.1
│ DESCRIPTION "Print something"
│ LANGUAGES CXX)
│
│ add_subdirectory(src)
│
└── CMakeLists.txt
cmake_minimum_required(VERSION 3.11...3.16)
project(printexamples
VERSION 0.1
DESCRIPTION "Print examples"
LANGUAGES CXX)
add_subdirectory(apps/printyes)
add_subdirectory(apps/printno)
add_subdirectory(extern/printsth)
在构建时我显然得到了错误
fatal error: print_usr.h: No such file or directory
那么我可以告诉 CMake 在为 printno 构建 printsh lib 时使用 apps/printno 作为包含目录并在为 printyes 构建时使用 apps/printyes 作为包含目录的任何更改吗?
我知道这个例子没有多大意义,并且很容易摆脱标题依赖项(例如,将自定义字符串作为参数传递给 printsth())并且一切正常。所以这只是一个演示“现实世界”问题的示例,我无法轻易摆脱依赖关系。
【问题讨论】:
-
你的意思是像 cmake 中的 if else 一样吗?
-
库不是“为...构建”的,它只是构建一次,然后与其他模块链接在一起。 CMake 不会改变库的工作方式。
-
欢迎来到 Stack Overflow!这是一个很好的第一个问题!除了完全重新设计以消除依赖关系之外,一种方法是创建
printsh库的“是”和“否”版本。然后,将库的正确“是”或“否”版本链接到printyes和printno。 -
感谢您的 cmets。我看到它实际上不是一个真正的静态库。 @squareskittles问题是,在“现实”中,这可能是很多不同的版本,我想让libraray(printsth)独立于配置。另一种方法是将库源直接包含到可执行文件中,但我看不到任何方法仍然能够控制库源文件的包含路径等。
标签: c++ cmake header dependencies static-libraries