我正在 ARM 项目上实现现代 Cmake。我有 3 个不同的 CMakeLists:
目标依赖项(算法和硬件)
target_link_libraries(app_target PUBLIC algo_target hardware_target)
只计算 (algo.c)
所有关于硬件依赖项 (hardware.c) 和编译选项的文件特别取决于硬件 -mcpu -mthumb -mfloat-abi -mfpu
target_compile_options(hardware_target -mcpu=${CPU} -mthumb -mfloat-abi=hard -mfpu=${FPU})
问题是,编译选项会传播到顶部,但不会传播到 algo_target。我有以下错误:
如何在所有目标上传播编译选项?
我不想在编译选项变量中设置编译选项,将来,应用程序将在 2 个不同的硬件目标上运行
最佳答案
因为您没有提供最小的工作示例,所以我可能无法完全回答您的问题。但是,由于 CMake 完全是关于目标和这些目标之间的依赖关系管理,我想任何需要另一个目标的设置/依赖关系的目标都应该依赖于该目标。
假设我们有以下目录结构:
.
├── algo
│ ├── CMakeLists.txt
│ ├── include
│ │ └── algo.hpp
│ └── src
│ └── algo.cpp
├── CMakeLists.txt
├── hardware
│ ├── CMakeLists.txt
│ ├── include
│ │ └── hardware.hpp
│ └── src
│ └── hardware.cpp
└── main.cpp
6 directories, 8 files
algo
的文件内容如下# algo/CMakeLists.txt
add_library(algo
include/algo.hpp
src/algo.cpp
)
target_include_directories(algo
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
# if (TARGET hardware)
# target_link_libraries(algo PRIVATE hardware)
# endif()
/* algo/include/algo.hpp */
#pragma once
double func1(const double);
/* algo/src/algo.cpp */
#include "algo.hpp"
double func1(const double x) {
#ifdef IMPORTANT_DEF
return 2 * x;
#else
return x;
#endif
}
对于
hardware
# hardware/CMakeLists.txt
add_library(hardware
include/hardware.hpp
src/hardware.cpp
)
target_include_directories(hardware
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_definitions(hardware
PUBLIC
IMPORTANT_DEF
)
/* hardware/include/hardware.hpp */
#pragma once
#ifdef IMPORTANT_DEF
double func2(const double, const double);
#else
int func2(int, const int);
#endif
/* hardware/src/hardware.cpp */
#include "hardware.hpp"
#ifdef IMPORTANT_DEF
double func2(const double x, const double y) { return x + y; }
#else
int func2(int x, const int y) { return x - y; }
#endif
最后,对于
app
# CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project(propagate LANGUAGES C CXX)
add_subdirectory(hardware)
add_subdirectory(algo)
add_executable(app main.cpp)
target_link_libraries(app
PRIVATE
hardware
algo
)
/* main.cpp */
#include <iostream>
using namespace std;
#include "hardware.hpp"
#include "algo.hpp"
int main(int argc, char* argv[]) {
cout << func1(5) << '\n';
cout << func2(5, 3) << '\n';
return 0;
}
当我们构建上面的项目并运行它时,我们得到
./app
5
8
这是因为我们没有告诉 CMake
algo
取决于 hardware
。当我们取消对部分的注释时# if (TARGET hardware)
# target_link_libraries(algo PRIVATE hardware)
# endif()
在
algo/CMakeLists.txt
中并重建项目,这次我们得到./app
10
8
基本上,
target_*
命令用于定义应该或不应该传播到目标消费者的依赖项。因此,我们应该让 algo
目标成为 hardware
目标的消费者。另请注意,为了传播发生,
target_*
friend 还需要填充目标的 INTERFACE_*
属性,即 target_*
命令需要将属性定义为 PUBLIC
(同时出现在头文件和实现文件中)或 INTERFACE
(仅出现)在头文件中),但不是 PRIVATE
(仅出现在实现文件中)。关于c - 如何将编译选项从目标传播到 Cmake 上的所有其他人,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56073201/