cmake如何设置全局定义?

Cmake how to set a global definition?

我的项目中有一个简单的结构,其中包括几个 subfolders/subprojects。结构如下:

main
|- CmakeLists.txt
|- include
|- src
|- library
   |- CmakeLists.txt
   |- include
   |- src

主要CmakeLists.txt

project(main)
file(GLOB SRC . src/*.cpp)
file(GLOB INC . include/*.h)

add_executable(${PROJECT_NAME} ${SRC} ${INC})

target_include_directories(${PROJECT_NAME} PUBLIC
  ${CMAKE_CURRENT_SOURCE_DIR}/include

option(ADDS, "", ON)
add_subdirectory(library)
target_link_libraries(${PROJECT_NAME} PRIVATE library)     

和图书馆的 CmakeLists.txt

project(library)
file(GLOB SRC . src/*.cpp)
file(GLOB INC . include/*.h)
add_library(${PROJECT_NAME} SHARED ${SRC} ${INC})

option(ADDS, "Some additional classes", OFF)
if(ADDS)
    message(STATUS "Configure with some extra classes")
    add_definitions(-DWITH_ADDS)
endif()

实际上我需要 option 来选择性地 add/compile 几个额外的 类,通常我不打算 use/compile。在这些额外的 类 中,我做了这样的事情:

library/add.h

#ifdef WITH_ADDS
class Adds
{
public:
    void doSomething();
}
#endif

与*.cpp文件相同

但现在我想在我的主项目中使用这些额外的 类。

main.cpp

#include "adds.h"

Adds adds;
adds.doSomething();

所以我在主要 CMakeFiles.txt 中打开了选项,但不幸的是我得到了错误:

error: ‘Adds ’  does not name a type

经过研究,我发现 add_definitions() 仅在定义它的项目中有效。因此,尽管我已经在我的主文件中打开了该选项,但定义 WITH_ADDS 仍然没有在主项目中定义,但仅在子项目中定义。

所以我的问题 - 有没有办法全局定义预处理器变量。因此,一旦在子项目中定义,它就可以在所有其他 projects/subprojects 中访问?或者也许还有其他解决方案?

“现代 cmake”方法是所有标志都封装在子项目中,当您 link 使用 target_link_library(MYEXE libsubproject) 到子项目时,所有必要的路径、标志和定义都会传播到主要项目。

为此,请在子项目中使用 target_compile_definitions(library PUBLIC ADDS),这会将设置传播给该目标的所有用户。如果您的顶层手动添加此子项目的包含路径,请将其删除并使用相同的包含路径策略:在子项目中,target_include_directories(library PUBLIC ./include),以便目标的任何用户都将继承此路径。

PUBLIC 关键字使传播起作用:这意味着该设置既适用于构建库,也适用于用户。 INTERFACE表示仅供用户使用,PRIVATE表示仅用于构建库。