如何将编译选项从目标传播到Cmake上的所有其他选项

如何将编译选项从目标传播到Cmake上的所有其他选项,c,gcc,cmake,cross-platform,target,C,Gcc,Cmake,Cross Platform,Target,我正在一个ARM项目上实现现代Cmake。我有3个不同的CmakeList: 顶级CMakeLists:包含要编译的应用程序文件(main.c)+2 目标依赖项(算法和硬件) AlgoCmakelists只有C文件 只进行计算(算法c) 编译的硬件CMakeLists 所有关于硬件依赖项(hardware.c)的文件和编译选项,具体取决于硬件-mcpu-mthumb-mfloat abi-mfpu 问题是,编译选项会传播到顶部,但不会传播到algo_目标上。我有以下错误: 应用程序使用V

我正在一个ARM项目上实现现代Cmake。我有3个不同的CmakeList:

  • 顶级CMakeLists:包含要编译的应用程序文件(main.c)+2 目标依赖项(算法和硬件)
  • AlgoCmakelists只有C文件 只进行计算(算法c)
  • 编译的硬件CMakeLists 所有关于硬件依赖项(hardware.c)的文件和编译选项,具体取决于硬件-mcpu-mthumb-mfloat abi-mfpu
问题是,编译选项会传播到顶部,但不会传播到algo_目标上。我有以下错误:

应用程序使用VFP寄存器参数,而algo.a(algo.cpp.obj)不使用

如何在所有目标上传播编译选项?
我不想在compile option变量中设置compile options,将来,应用程序将在两个不同的硬件目标上运行

,因为您没有提供最低限度的工作示例,我可能无法完全回答您的问题。然而,由于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
}
最后,对于
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;
}
这是因为我们没有告诉CMake算法取决于硬件。当我们取消注释该部分时

# if (TARGET hardware)
#   target_link_libraries(algo PRIVATE hardware)
# endif()
algo/CMakeLists.txt
中重建项目,这次我们得到

./app
10
8
基本上,
target.*
命令用于定义应该或不应该传播到目标消费者的依赖关系。因此,我们应该使
算法
目标成为
硬件
目标的消费者


还请注意,为了进行传播,
target.*
friends aldo需要填充目标的
INTERFACE.*
属性,即,
target.*
命令需要将属性定义为
PUBLIC
(出现在头文件和实现文件中)或
INTERFACE
(仅出现在头文件中),但不
PRIVATE
(仅出现在实现文件中).

您完全理解我的问题。对我来说,algo target依赖于hardware target很奇怪,我不想在构建algo.cpp时构建hardware.cpp。这是否意味着,我只需要第四个CMakeLists.txt作为编译选项?可能不需要。CMake必须知道您的目标的消费者,以及如何(如果有的话)构建您的目标的属性/配置会传播到目标的消费者。根据,如果您只在目标的名称后添加
PUBLIC
关键字到
target\u compile\u options
,这应该没问题。但真正的问题是,除非您定义一些依赖项或使用o定义全局选项
# 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
# if (TARGET hardware)
#   target_link_libraries(algo PRIVATE hardware)
# endif()
./app
10
8