跳到主要内容

CMake 操作编译器

定义编译器标志

target_compile_definitions 是 CMake 中的一个命令,用于为特定的目标(如可执行文件或库)定义编译器标志。

target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE __JNI__)

例如上面的代码,__JNI__ 就是一个宏定义,这样在代码中就可以使用 #ifdef __JNI__ 来判断是否定义了这个宏。

在一些情况下,我们需要根据不同的编译器来定义不同的宏,这时候我们可以使用 if 语句来判断编译器类型,然后定义不同的宏。

if (OCR_OUTPUT STREQUAL "JNI") # JNI
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE __JNI__)
elseif (OCR_OUTPUT STREQUAL "CLIB") # CLIB
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE __CLIB__)
elseif (OCR_OUTPUT STREQUAL "BIN") # BIN
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE __EXEC__)
elseif(OCR_OUTPUT STREQUAL "PYBIND") # PYBIND
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE __PYBIND__)
endif ()

如上面的代码,我们根据 OCR_OUTPUT 的值来定义不同的宏。使用 cmake 时,我们可以通过 -D 选项来定义宏,例如:

cmake -D OCR_OUTPUT=JNI ..

这样就可以根据不同的编译器来定义不同的宏。

添加编译器选项

target_compile_options 是 CMake 中的一个命令,用于为特定的目标(如可执行文件或库)添加编译器选项。

这些选项可以是警告级别、优化级别或任何特定编译器支持的其他标志。使用 target_compile_options 可以细粒度地控制编译过程,为不同的目标设置不同的编译选项。

target_compile_options(<target> [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
  • <target>: 指定要为其添加编译选项的目标名称(已通过 add_executableadd_library 创建)。
  • PUBLIC, PRIVATE, INTERFACE: 指定作用范围。
    • PRIVATE: 选项仅应用于指定的目标。
    • PUBLIC: 选项应用于指定目标及其链接的目标。
    • INTERFACE: 选项不应用于指定目标,只应用于链接了此目标的其他目标。

假设你有一个名为 my_app 的应用程序,你想为它添加额外的编译警告和优化选项。你可以使用 target_compile_options 来实现:

add_executable(my_app main.cpp)

# 为 my_app 目标添加编译选项
target_compile_options(my_app PRIVATE
-Wall # 开启所有警告
-Wextra # 开启额外警告
-O2 # 使用第二级优化
)

在这个例子中,-Wall-Wextra-O2 是传递给编译器的选项。通过将这些选项标记为 PRIVATE,它们仅应用于 my_app 目标,而不影响其他可能链接到 my_app 的目标。

CMake 也允许你根据条件来设置编译选项,例如,仅当使用特定编译器时添加某些选项:

if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(my_app PRIVATE
-Wall -Wextra -O2
)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
target_compile_options(my_app PRIVATE
/W4 /O2
)
endif()

这个例子中,对于 GNU 编译器,我们添加了 -Wall -Wextra -O2,而对于 MSVC 编译器,我们添加了 /W4 /O2。这展示了如何根据不同的编译器选择不同的编译选项。