CMake学习-01-basic

01-basic

cmake学习项目github地址

A-hello-cmake

  • CMakelist.txt存放了所有的cmake命令,makefile是由CMakelist.txt生成的

  • CMakelist.txt里面一般包含这几个基本的命令

    cmake_minimum_required(VERSION 3.5) #指定了运行此文件所需要的最小cmake版本
    project (hello_cmake) #指定项目名
    add_executable(hello_cmake main.cpp) #从指定的源文件构建可执行文件,在本例中为main.cpp。add_executable()函数的第一个参数是要构建的可执行文件的名称,第二个参数是要编译的源文件列表
    
  • 运行cmake命令的根目录叫做CMAKE_BINARY_DIR,是所有二进制文件的根文件夹。CMake支持就地和外部构建来生成二进制文件

  • 就地构建就是直接在CMakelist.txt所在目录构建,外部构建一般就是创建一个build目录,然后去build目录中构建(一般推荐这种方式)

B-hello-headers

  • 项目结构

    B-hello-headers$ tree
    .
    ├── CMakeLists.txt
    ├── include
    │   └── Hello.h
    └── src
        ├── Hello.cpp
        └── main.cpp
    
  • cmake的一些目录变量

    变量描述
    CMAKE_SOURCE_DIR根源目录
    CMAKE_CURRENT_SOURCE_DIR如果使用子项目和目录,则为当前源目录。
    PROJECT_SOURCE_DIR当前 cmake 项目的源目录。
    CMAKE_BINARY_DIR根二进制/构建目录,这是运行 cmake 命令的目录。
    CMAKE_CURRENT_BINARY_DIR当前所在的构建目录。
    PROJECT_BINARY_DIR当前项目的构建目录。
  • CMakelist.txt

    cmake_minimum_required(VERSION 3.5) 
    project (hello_headers) 
    set(SOURCES #创建SOURCE变量
        src/Hello.cpp
        src/main.cpp
    )
    add_executable(hello_headers ${SOURCES})
    # 给hello_header设置头文件
    # 这样在执行g++编译命令时会带上-I/directory/path,这个命令会指定头文件的路径
    target_include_directories(hello_headers 
        PRIVATE 
            ${PROJECT_SOURCE_DIR}/include
    )
    

C-static-library

  • 项目结构

    $ tree
    .
    ├── CMakeLists.txt
    ├── include
    │   └── static
    │       └── Hello.h
    └── src
        ├── Hello.cpp
        └── main.cpp
    
  • CMakelist.txt

    cmake_minimum_required(VERSION 3.5)
    project(hello_library)
    
    #将Hello.cpp制作成静态库
    add_library(hello_library STATIC
    	src/Hello.cpp
    )
    
    # 给这个库设置头文件,让编译器可以找到
    # 下面设置成PUBLIC使得所有链接这个库的文件在编译时,编译器都可以在这个include目录里面去找头文件
    # 除了PUBLIC,还要PRIVATE(只能编译这个库时去这个头文件目录找)和INTERFACE(只有在被链接时,去这个头文件目录找)
    target_include_directories(hello_library
    	PUBLIC
    		${PROJECT_SOURCE_DIR}/include
    )
    
    add_executable(hello_binary
    	src/main.cpp
    )
    
    # 指定链接这个静态库
    target_link_libraries( hello_binary
    	PRIVATE
    		hello_libiary
    )
    
  • 补充知识,gcc编译时的头文件搜索路径,参考gcc 头文件搜索路径

D-shared-library

  • 项目结构

    $ tree
    .
    ├── CMakeLists.txt
    ├── include
    │   └── shared
    │       └── Hello.h
    └── src
        ├── Hello.cpp
        └── main.cpp
    
  • 将Hello做成动态链接库,然后链接到main中。

  • CMakelist.txt

    cmake_minimum_required(VERSION 3.5)
    project(hello_library)
    
    add_library(hello_library SHARED
    	src/Hello.cpp
    )
    add_library(hello::library AIAS hello_library) #给hello_library起别名hello:library
    target_include_directories(hello_library
    	${PROJECT_SRC_DIR}/include
    )
    
    #创建可执行文件
    add_execuable(hello_binary
    	src/main.cpp
    )
    
    target_link_libraries(hello_binary
    	PRIVATE
    		hello::library
    )
    

E-installing

  • 项目结构

    $ tree
    .
    ├── cmake-examples.conf
    ├── CMakeLists.txt
    ├── include
    │   └── installing
    │       └── Hello.h
    ├── README.adoc
    └── src
        ├── Hello.cpp
        └── main.cpp
    
  • cmake提供对于make install的支持,默认的安装路径由CMAKE_INSTALL_PREFIX指定,可以使用cmake .. -DCMAKE_INSTALL_PREFIX=/install/location来设置,Linux默认安装目录是/usr/local/下面(这个目录就是用来安装一些用户软件之类的)

  • CMakelist.txt

    cmake_minimum_required(VERSION 3.5)
    project(cmake_examples_install)
    
    ############################################################
    # Create a library
    ############################################################
    
    #Generate the shared library from the library sources
    add_library(cmake_examples_inst SHARED
        src/Hello.cpp
    )
    
    target_include_directories(cmake_examples_inst
        PUBLIC 
            ${PROJECT_SOURCE_DIR}/include
    )
    
    ############################################################
    # Create an executable
    ############################################################
    
    # Add an executable with the above sources
    add_executable(cmake_examples_inst_bin
        src/main.cpp
    )
    
    # link the new hello_library target with the hello_binary target
    target_link_libraries( cmake_examples_inst_bin
        PRIVATE 
            cmake_examples_inst
    )
    
    ############################################################
    # Install
    ############################################################
    
    #将cmake_examples_inst_bin安装到${CMAKE_INSTALL_PREFIX}/bin目录下
    #这里${CMAKE_INSTALL_PREFIX}默认就是/usr/local
    install (TARGETS cmake_examples_inst_bin
        DESTINATION bin)
    
    # Library
    # 此处在windows上可以无法运行
    # 将cmake_examples_inst安装到${CMAKE_INSTALL_PREFIX}/lib目录下
    install (TARGETS cmake_examples_inst
        LIBRARY DESTINATION lib)
    
    #安装头文件
    install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ 
        DESTINATION include)
    
    # 安装配置文件
    install (FILES cmake-examples.conf
        DESTINATION etc)
    
  • 安装完成后,在build目录中运行LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib cmake_examples_inst_bin,指定去LD_LIBRARY_PATH环境变量下寻找动态链接库文件,不过不设置环境变量。

  • 补充知识,Linux动态链接库的默认搜索路径

    (1) 编译目标代码时指定的动态库搜索路径(-Wl,-rpath 指定);
    (2) 环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
    (3) 配置文档/etc/ld.so.conf中指定的动态库搜索路径;
    (4) 默认的动态库搜索路径/lib;
    (5) 默认的动态库搜索路径/usr/lib.

更改默认安装位置

  • 下面的代码可以用来更改默认安装位置CMAKE_INSTALL_PREFIX

    if( CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT )
      message(STATUS "Setting default CMAKE_INSTALL_PREFIX path to ${CMAKE_BINARY_DIR}/install")
      set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING "The path to use for make install" FORCE)
    endif()
    
  • DESTDIR的使用

    GNU Make中,有许多约定俗成的东西,比如这个DESTDIR:用于加在要安装的文件路径前的一个前缀变量。

    比如,我们本地编译了一个第三方库,但需要对其打包发布给其他人使用,一方面如果我们安装到默认目录,比如/usr,这时,安装后的文件一但数量很大,则打包时很难找全;或者我们在configure时指定了–prefix,或cmake时指定了CMAKE_INSTALL_PREFIX,则pc文件内的编译依赖关系又会出错,变成了我们指定的那个路径,使用起来会很不方便。此时,DESTDIR就会派上用场。

    DESTDIR只在make install时起作用,且和Makefile是由什么工具生成的没有关系,用法如下:

    # make install DESTDIR=<$CUSTOM_PREFIX> 
    make install DESTDIR=/tmp/stage
    

    在configure或cmake时,指定了要安装的路径后,以这种方式make install安装的文件会通通安装到以$CUSTOM_PREFIX为前缀的目录中(比如这个例子就是/tmp/stage/usr/local),这样,开发者直接对这目录中的文件打包,即可发布使用。

    $ tree /tmp/stage
    /tmp/stage
    └── usr
        └── local
            ├── bin
            │   └── cmake_examples_inst_bin
            ├── etc
            │   └── cmake-examples.conf
            └── lib
                └── libcmake_examples_inst.so
    

卸载

  • 默认情况下,CMake 不提供"make uninstall"。我们不希望"make uninstall"从系统中删除有用的文件。如果你想在你的项目中有一个"uninstall"目标,那么没有人会阻止你提供一个。你需要删除 install_manifest.txt 文件中列出的文件。
对于非Unix用户
  • 首先在项目顶层目录下创建文件cmake_uninstall.cmake.in

    if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
      message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
    endif()
    
    file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
    string(REGEX REPLACE "\n" ";" files "${files}")
    foreach(file ${files})
      message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
      if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
        exec_program(
          "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
          OUTPUT_VARIABLE rm_out
          RETURN_VALUE rm_retval
          )
        if(NOT "${rm_retval}" STREQUAL 0)
          message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
        endif()
      else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
        message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
      endif()
    endforeach()
    
  • 然后在 CMakeLists.txt中加入以下代码,这下你就创建了"uninstall"目标

    # uninstall target
    if(NOT TARGET uninstall)
      configure_file(
        "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
        "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
        IMMEDIATE @ONLY)
      add_custom_target(uninstall
        COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
    endif()
    
对于Unix用户
  • 对于Unix用户在shell中输入xargs rm < install_manifest.txt进行卸载

F-build-type

  • CMake有很多内置的构建配置,可以用来编译你的项目。它们指定了优化级别,以及是否将调试信息包含在二进制文件中。

    所提供的级别是:

    • Release——在编译器中添加-O3 -DNDEBUG标志

    • Debug——添加-g标志

    • MinSizeRel——添加-Os -DNDEBUG

    • RelWithDebInfo——添加-O2 -g -DNDEBUG标志

  • CMakelist.txt

    cmake_minimum_required(VERSION 3.5)
    
    # 设置默认build类型
    if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
      message("Setting build type to 'RelWithDebInfo' as none was specified.")
      set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
      # Set the possible values of build type for cmake-gui
      set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
        "MinSizeRel" "RelWithDebInfo")
    endif()
    
    # Set the project name
    project (build_type)
    
    # Add an executable
    add_executable(cmake_examples_build_type main.cpp)
    

E-compile-flags

  • cmake支持设置编译标志(flags)
    • 使用target_compile_definitions()
    • 使用变量CMAKE_C_FLAGSCMAKE_CXX_FLAGS
设置 每个目标的C++ Flags
  • 在现代CMake中,设置c++标志的推荐方法是通过target_compile_definitions()函数设置每个目标的标志,这些标志可以填充到其他目标中。这会填充库的INTERFACE_COMPILE_DEFINITIONS,并根据作用域将该定义推到链接目标。
设置默认C++ Flags
  • 默认的CMAKE_CXX_FLAGS要么为空,要么包含构建类型(build type)的一些标志。要设置额外的默认编译标志,你可以在你的顶层CMakeLists.txt中添加以下内容:

    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)
    
  • 上述命令中的值CACHE STRING “Set c++ Compiler Flags” FORCE用于强制在CMakeCache.txt文件中设置该变量,详见https://cmake.org/cmake/help/v3.0/command/set.html

  • 同样地,可以使用CMAKE_C_FLAGS设置C编译器标志,使用CMAKE_LINKER_FLAGS设置链接器标志

设置cmake标志
cmake .. -DCMAKE_CXX_FLAGS="-DEX3"
CMakelist.txt
cmake_minimum_required(VERSION 3.5)

# Set a default C++ compile flag
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEX2" CACHE STRING "Set C++ Compiler Flags" FORCE)

# Set the project name
project (compile_flags)

# Add an executable
add_executable(cmake_examples_compile_flags main.cpp)

#设置编译标志
target_compile_definitions(cmake_examples_compile_flags 
    PRIVATE EX3
)

H-third-party-library

  • 这一部分主要是查找并链接第三方库。几乎所有重要的项目都要求包含第三方库、头文件或程序。CMake支持使用find_package()函数找到这些第三方库的路径,这个函数将以FindXXX.cmake的格式从CMAKE_MODULE_PATH的文件夹列表中搜索CMake模块。在linux上,默认的搜索路径将包括/usr/share/cmake/Modules,在我的系统上,这包括对大约142个公共第三方库的支持。

寻找Package

find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)
  • 参数解释:
    • Boost——库的名字,FindXXX.cmake这里的XXX就是Boost,即FindBoost.cmake。如果系统上安装了Boost这个第三方库,进入/usr/share/cmake/Modules目录里面,就会发现FindBoost.cmake这个文件。
    • 1.46.1——要求所查找的Boost的最低版本
    • REQUIRED——说明这个模块是必需的,如果找不到就会失败。
    • COMPONENTS——要在库中查找的组件列表,这里就是filesystem和system。

检测是否找到了这个包

  • 大多数包含的包将设置一个变量XXX_FOUND,该变量可用于检查该包在系统上是否可用(这个例子里就是Boost_FOUND
if(Boost_FOUND)
    message ("boost found")
    include_directories(${Boost_INCLUDE_DIRS})
else()
    message (FATAL_ERROR "Cannot find Boost")
endif()

导出变量

  • 在找到一个包之后,它通常会导出一些变量,这些变量可以告诉用户在哪里可以找到库、头文件或可执行文件。与XXX_FOUND变量类似,它们是特定于包的,通常在FindXXX.cmake的顶部进行记录。这个例子导出了Boost_INCLUDE_DIRS(指示boost头文件的路径)

别名(Alias)和导入目标

  • 大多数现代的CMake库在它们的模块文件中导入别名目标。导入目标的好处是,它们还可以填充include目录和链接库。

  • 例如,从CMake的3.5+版本开始,Boost模块就支持这一点。与为库使用自己的ALIAS目标类似(参见前面的D-shared-library),模块中的ALIAS可以使引用找到的目标变得更容易。在Boost的情况下,使用Boost::标识符导出所有目标,然后使用子系统的名称。例如,你可以使用:

    • Boost::boost 仅使用头文件
    • Boost::system 使用boost system库
    • Boost::filesystem 使用filesystem库
  • 和之前使用自己定义的shared-library类似,这些库也是有它们的依赖项的,链接这些库也会自动添加这些依赖项(和shared-library中自动继承那些链接库包含的头文件类似)。

不使用别名(Alias)

  • 虽然大多数现代库使用导入的目标,但并不是所有的模块都更新了。在库没有更新的情况下,你通常会发现以下可用变量:

    • xxx_INCLUDE_DIRS——指向库的包含目录的变量。
    • xxx_LIBRARY ——指向库路径的变量

    这些可以添加到你的target_include_directoriestarget_link_libraries

    # Include the boost headers
    target_include_directories( third_party_include
        PRIVATE ${Boost_INCLUDE_DIRS}
    )
    
    # link against the boost libraries
    target_link_libraries( third_party_include
        PRIVATE
        ${Boost_SYSTEM_LIBRARY}
        ${Boost_FILESYSTEM_LIBRARY}
    )
    

CMakelist.txt

cmake_minimum_required(VERSION 3.5)

# Set the project name
project (third_party_include)

# 查找Boost库
find_package(Boost 1.46.1 REQUIRED COMPONENTS filesystem system)

# 判断查找成功没有
if(Boost_FOUND)
	message("boost found.")
else()
	message(FATAL_ERROR"Cannot find Boost")
endif()

# 添加可执行文件
add_executable(third_patry_include main.cpp)

# 链接这个第三方库
target_link_libraries(third_patry_include
	PRIVATE:
		Boost::filesystem
)

I-Compiling with clang

  • 当使用cmake进行构建时,可以设置C或C++编译器,这个例子和第一个hello-cmake的例子很相似,只不过这个例子展示了将默认的gcc编译器变为clang的基本方法。

编译选项

  • CMake公开了用来控制编译和链接代码的程序,这些程序包括:

    • CMAKE_C_COMPILER - 用于编译C的程序
    • CMAKE_CXX_COMPILER - 用于编译C++的程序
    • CMAKE_LINKER - 用于链接二进制文件的程序
  • 这个例子是展示调用clang的最基本、最简单的方法,以后的示例将展示调用编译器的更好方法。

设置flags

  • 下面这段命令指定了使用clang和clang++来编译
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++

J-building-with-ninja

  • 如前所述,CMake是一个元构建系统(meta-build system),可以用来为许多其他构建工具创建构建文件,这个例子展示了如何让CMake使用ninja构建工具。

生成器(Generators)

  • CMake生成器负责为底层构建系统编写输入文件(例如Makefiles),运行cmake --help将显示可用的生成器。对于cmake v2.8.12.2,我的系统支持的生成器包括:

    Generators
    
    The following generators are available on this platform:
      Unix Makefiles              = Generates standard UNIX makefiles.
      Ninja                       = Generates build.ninja files (experimental).
      CodeBlocks - Ninja          = Generates CodeBlocks project files.
      CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
      Eclipse CDT4 - Ninja        = Generates Eclipse CDT 4.0 project files.
      Eclipse CDT4 - Unix Makefiles
                                  = Generates Eclipse CDT 4.0 project files.
      KDevelop3                   = Generates KDevelop 3 project files.
      KDevelop3 - Unix Makefiles  = Generates KDevelop 3 project files.
      Sublime Text 2 - Ninja      = Generates Sublime Text 2 project files.
      Sublime Text 2 - Unix Makefiles
                                  = Generates Sublime Text 2 project files.Generators
    

命令行(Command-Line)构建工具生成器

  • 这些生成器用于命令行构建工具,比如Make和Ninja。选择的工具链必须在用CMake生成构建系统之前配置好。
  • 支持的生成器包括:
    • Borland Makefiles
    • MSYS Makefiles
    • MinGW Makefiles
    • NMake Makefiles
    • NMake Makefiles JOM
    • Ninja
    • Unix Makefiles
    • Watcom WMake

IDE构建工具生成器

  • 这些生成器适用于集成开发环境(IDE),其中包含自己的编译器。例如,Visual Studio和Xcode就包含了一个本地编译器。
  • 支持的生成器包括:
    • Visual Studio 6
    • Visual Studio 7
    • Visual Studio 7 .NET 2003
    • Visual Studio 8 2005
    • Visual Studio 9 2008
    • Visual Studio 10 2010
    • Visual Studio 11 2012
    • Visual Studio 12 2013
    • Xcode

其他生成器

  • 这些生成器创建了一个配置,用于使用另一个IDE工具,并且必须包含在IDE或命令行生成器中。
  • 支持的生成器包括:
    • CodeBlocks
    • CodeLite
    • Eclipse CDT4
    • KDevelop3
    • Kate
    • Sublime Text 2

调用一个生成器

  • 使用-G调用

    cmake .. -G Ninja
    
  • 完成上述操作后,CMake将生成所需的ninja构建文件,可以使用ninja命令运行

    $ cmake .. -G Ninja
    
    $ ls
    build.ninja  CMakeCache.txt  CMakeFiles  cmake_install.cmake  rules.ninja
    

K-impoerted-targets

  • 正如前面在第三方库(H-third-party-library)中提到的,更新版本的CMake允许使用导入的ALIAS目标链接第三方库。

导入目标

  • 导入的目标是由FindXXX模块导出的只读目标。要包含boost文件系统,你可以这样做:

      target_link_libraries(imported_targets
          PRIVATE
              Boost::filesystem
      )
    
  • 这将自动链接Boost::filesystem和Boost::system库,同时也包含Boost include目录

L-cpp-standard

  • 由于c++ 11和c++ 14的发布,一个常见的用例是调用编译器来使用这些标准。随着CMake的发展,它增加了一些特性来简化这一过程,而CMake的新版本改变了实现这一过程的方式。下面的例子展示了设置c++标准的不同方法,以及它们可以使用的CMake版本。例子包括:
    • common-method。一个简单的版本,在大多数版本的CMake中可以正常工作。
    • cxx-standard。使用CMake 3.1中引入的CMAKE_CXX_STANDARD变量。
    • compile-features。使用CMake v3.1中引入的target_compile_features函数

i-comm-method

  • 这个例子展示了一个设置c++标准的常用方法。这可以用于大多数版本的CMake。但是,如果你的目标是CMake的最新版本,有更方便的方法可用。
检查编译flags
  • CMake支持使用传入CMAKE_CXX_COMPILER_FLAG函数的任何标志来编译程序,然后将结果存储在传入的变量中,例如:

    include(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
    

    这个例子将会尝试用标志"-std=c++11"编译并将结果存在变量COMPILER_SUPPORTS_CXX11中。include(CheckCXXCompilerFlag)告诉CMake包含这个函数以使其可用。

添加flag
  • 一旦你确定编译是否支持一个标志,你就可以使用标准的cmake方法将这个标志添加到目标中。在本例中,我们使用CMAKE_CXX_FLAGS将该标志传播到所有目标。

    if(COMPILER_SUPPORTS_CXX11)#
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    elseif(COMPILER_SUPPORTS_CXX0X)#
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
    else()
        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
    endif()
    
  • 上面的例子只检查编译标志的gcc版本,并支持从c++11回退到标准化前的c++0x标志。在实际使用中,你可能想检查C14,或者添加对设置编译的不同方法的支持,例如-std=gnu11

  • CMakelist.txt

    # Set the minimum version of CMake that can be used
    # To find the cmake version run
    # $ cmake --version
    cmake_minimum_required(VERSION 2.8)
    
    # Set the project name
    project (hello_cpp11)
    
    # try conditional compilation
    include(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
    CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
    
    # check results and add flag
    if(COMPILER_SUPPORTS_CXX11)#
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    elseif(COMPILER_SUPPORTS_CXX0X)#
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
    else()
        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
    endif()
    
    # Add an executable
    add_executable(hello_cpp11 main.cpp)
    

ii-cxx-standard

  • 这个例子展示了如何使用CMAKE_CXX_STANDARD变量来设置c++标准,这是从CMake 3.1版本开始的。

  • 设置CMAKE_CXX_STANDARD变量会使得在所有目标上使用CXX_STANDARD属性。这将使得CMake在编译时设置适当的标志。

    • CMAKE_CXX_STANDARD变量会匹配最合适的标准,而不报错。例如,如果你请求-std=gnu11,你可能会得到-std=gnu0x。这可能会在编译时导致意外的失败。
  • CMakelist.txt

    # Set the minimum version of CMake that can be used
    # To find the cmake version run
    # $ cmake --version
    cmake_minimum_required(VERSION 3.1)
    
    # Set the project name
    project (hello_cpp11)
    
    # set the C++ standard to C++ 11
    set(CMAKE_CXX_STANDARD 11)
    
    # Add an executable
    add_executable(hello_cpp11 main.cpp)
    

iii-compile-features

  • 这个例子展示了如何使用target_compile_features函数来设置c++标准。这是从CMake 3.1版本开始的。

  • 在目标上调用target_compile_features函数将查看传入的特性,并确定要为目标使用的正确编译器标志。

    target_compile_features(hello_cpp11 PUBLIC cxx_auto_type)
    
  • 与其他target_*函数一样,您可以为所选目标指定特性的作用域范围。这将为目标填充INTERFACE_COMPILE_FEATURES属性。

  • 可用特性的列表可以从CMAKE_CXX_COMPILE_FEATURES变量中找到。你可以使用以下代码获得可用特性的列表:

    message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
    
  • CMakelist.txt

    # Set the minimum version of CMake that can be used
    # To find the cmake version run
    # $ cmake --version
    cmake_minimum_required(VERSION 3.1)
    
    # Set the project name
    project (hello_cpp11)
    
    # Add an executable
    add_executable(hello_cpp11 main.cpp)
    
    # set the C++ standard to the appropriate standard for using auto
    target_compile_features(hello_cpp11 PUBLIC cxx_auto_type)
    
    # Print the list of known compile features for this version of CMake
    message("List of compile features: ${CMAKE_CXX_COMPILE_FEATURES}")
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值