美文网首页
CMake编译命令target_compile_options简

CMake编译命令target_compile_options简

作者: Domibaba | 来源:发表于2023-09-05 13:13 被阅读0次

本文使用的相关软件环境信息如下:

软件名称 软件版本
Linux操作系统 Ubuntu 22.04 LTS(X64)
cmake 3.22.1
g++ 11.4.0
  • target_compile_options

    命令格式:

    target_compile_options(<target> [BEFORE]
      <INTERFACE|PUBLIC|PRIVATE> [items1...]
      [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
    

    该命令添加编译选项到编译目标中,与add_compile_options不同的是,target_compile_options针对构建的目标添加编译选项,而add_compile_options是针对源文件添加预编译选项(实际上也隐含对当前构建目标添加编译选项)。

    因此,target_compile_options要求构建目标已经存在,也就是被add_executable()或add_library()等函数创建出来。此外,target_compile_options还要求对每一个编译选项指定范围,范围有三个选项:PUBLIC、PRIVATE和INTERFACE。通过PUBLIC和PRIVATE范围限定的预编译选项会被添加到构建目标的COMPILE_OPTIONS属性中,通过PUBLIC和INTERFACE范围限定的预编译选项会被添加到构建目标的INTERFACE_COMPILE_OPTIONS属性中。总结起来就是PUBLIC既给自己用,也给别人用;PRIVATE只给自己用;INTERFACE只给别人用。

    当多个构建目标在一起链接的时,最终的可执行文件会将各个构建目标的INTERFACE_COMPILE_OPTIONS属性继承过来。

    总体来说,target_compile_options与add_compile_options的关系,和add_compile_definitions与target_compile_definitions的关系类似。下面通过一个例子来演示一下:

    1、构建一个test库,对test使用PUBLIC、PRIVATE和INTERFACE三个编译选项,分别对应编译选项-Wunused-variable(未使用的变量)、-Wreturn-type(函数缺少返回值)、-Wuninitialized(变量使用前未初始化);

    2、构建一个main可执行文件,对main使用PRIVATE的编译选项-Wunused-parameter(从未使用过的函数参数);

    3、对test.cpp和main.cpp都模拟未使用的变量、函数缺少返回值、变量使用前未初始化、从未使用过的函数参数这4种情况。

    CMakeLists.txt文件内容:

    CMAKE_MINIMUM_REQUIRED(VERSION 3.22)
    PROJECT(compile_options_test)
    
    ADD_LIBRARY(test test.cpp)
    TARGET_COMPILE_OPTIONS(test
                            PUBLIC -Wunused-variable
                            PRIVATE -Wreturn-type
                            INTERFACE -Wuninitialized)
    
    ADD_EXECUTABLE(main main.cpp)
    TARGET_COMPILE_OPTIONS(main
                            PRIVATE -Wunused-parameter)
    
    TARGET_LINK_LIBRARIES(main test)
    

    test.h文件内容

    #ifndef __TEST_TT__
    #define __TEST_TT__
    
    int test(int para);
    
    #endif
    

    test.cpp文件内容:

    #include "test.h"
    
    int test(int para/* 未使用的函数参数 */)
    {
        int a = 5; // 未使用的变量
        int i; // 未初始化的变量
        if (i == 0) {
            
        }
        // 函数缺少返回值
    }
    

    main.cpp文件内容:

    #include "test.h"
    
    int main(int argc, char** argv /* 未使用的函数参数 */)
    {
        const char* not_use_var = "Hello world!"; // 未使用的变量
        int i; // 未初始化的变量
        test(i);
        //return 0; // 函数缺少返回值
    }
    

    运行cmake .make VERBOSE=1,关键信息输出如下:

    ……
    [ 25%] Building CXX object CMakeFiles/test.dir/test.cpp.o
    /usr/bin/c++   -Wunused-variable -Wreturn-type -MD -MT CMakeFiles/test.dir/test.cpp.o -MF CMakeFiles/test.dir/test.cpp.o.d -o CMakeFiles/test.dir/test.cpp.o -c /XXX/test.cpp
    /XXX/test.cpp: In function ‘int test(int)’:
    /XXX/test.cpp:5:9: warning: unused variable ‘a’ [-Wunused-variable]
        5 |     int a = 5; // 未使用的变量
          |         ^
    /XXX/test.cpp:11:1: warning: no return statement in function returning non-void [-Wreturn-type]
       11 | }
          | ^
    [ 50%] Linking CXX static library libtest.a
    ……
    [ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o
    /usr/bin/c++   -Wunused-parameter -Wunused-variable -Wuninitialized -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /XXX/main.cpp
    /XXX/main.cpp: In function ‘int main(int, char**)’:
    /XXX/main.cpp:5:17: warning: unused variable ‘not_use_var’ [-Wunused-variable]
        5 |     const char* not_use_var = "Hello world!"; // 未使用的变量
          |                 ^~~~~~~~~~~
    /XXX/main.cpp:3:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
        3 | int main(int argc, char** argv /* 未使用的函数参数 */)
          |          ~~~~^~~~
    /XXX/main.cpp:3:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
        3 | int main(int argc, char** argv /* 未使用的函数参数 */)
          |                    ~~~~~~~^~~~
    /XXX/main.cpp:7:9: warning: ‘i’ is used uninitialized [-Wuninitialized]
        7 |     test(i);
          |     ~~~~^~~
    [100%] Linking CXX executable main
    

    可以看到,对于test库,其PUBLIC和PRIVATE编译选项生效,2种告警提示;对于main可执行文件,继承了test库的PUBLIC和INTERFACE编译选项,加上自身的PRIVATE编译选项,3种告警提示。

相关文章

网友评论

      本文标题:CMake编译命令target_compile_options简

      本文链接:https://www.haomeiwen.com/subject/xlogmdtx.html