cmake 订阅
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。 展开全文
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。
信息
外文名
cross platform make
描    述
所有平台的安装(编译过程)
类    型
跨平台的安装(编译)工具
中文名
描述所有平台的安装(编译过程)
功    能
可以编译源代码、制作程式库
cmake定义
CMake 可以编译源代码、制作程序库、产生适配器(wrapper)、还可以用任意的顺序建构执行档。CMake 支持 in-place 建构(二进档和源代码在同一个目录树中)和 out-of-place 建构(二进档在别的目录里),因此可以很容易从同一个源代码目录树中建构出多个二进档。CMake 也支持静态与动态程式库的建构。“CMake”这个名字是“cross platform make”的缩写。虽然名字中含有“make”,但是CMake和Unix上常见的“make”系统是分开的,而且更为高阶。
收起全文
精华内容
下载资源
问答
  • cmake

    千次阅读 2016-02-15 17:01:27
    cmake内部变量CMAKE_C_COMPILE 指定c编译器 CMAKE_CXX_COMPILER CMAKE_C_FLAGS 编译c文件时的选项,如-g,也可以通过add_definitions添加编译选项 EXECUTABLE_OUTPUT_PATH 可执行文件的存放路径 LIBRARY_OUTPUT_PATH...

    包含CMakeLists.txt源码的使用

    当从网上或者其他地方获取源码后,在目录里面会有CMakeLists.txt和其他一些.c .h文件
    基本操作流程为:
    ccmake directory 用于配置编译选项,一般这一步不需要配置,直接执行第二步
    cmake directory 用于根据CMakeLists.txt生成Makefile文件
    make


    cmake内部变量

    CMAKE_C_COMPILE     指定c编译器
    CMAKE_CXX_COMPILER
    CMAKE_C_FLAGS       编译c文件时的选项,如-g,也可以通过add_definitions添加编译选项
    EXECUTABLE_OUTPUT_PATH  可执行文件的存放路径
    LIBRARY_OUTPUT_PATH 库文件路径
    CMAKE_BUILD_TYPE    build类型(Debug, Release...),如CMAKE_BUILD_TYPE=Debug
    BUILD_SHARED_LIBS   switch between shared and statis libraries

    内部变量可以
    在CMakeList.txt中指定,使用set
    在cmake命令中使用,如cmake -DBUILD_SHARED_LIBS=OFF

    另外自定义变量
    cmake -DDEBUG_mode=ON
    就可以在CMakeList.txt中判断这个变量
    if(DEBUG_mode)
    add_definitions(-DDEBUG)
    endif()


    cmake命令

    project(HELLO)      指定项目名称
    add_subdirectory    包含子目录
    include_directories 指定头文件的搜索路径,相当于指定gcc的-I参数
    link_directories    动态链接库或者静态链接库的搜索路径,相当于gcc的-L参数
    target_link_libraries   添加链接库,相当于指定-l参数
    
    add_library
        add_library(hello, hello.c) 将hello.c编译成静态库如libhello.a
    add_executable      编译可执行程序
        add_executable(helloDemo demo_a.c demo_b.c) 将demo_a.c demo_b.c编译成helloDemo
    add_definitions     添加编译参数
        add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义
        add_definitions( “-Wall -ansi –pedantic –g”)
    
    message([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)

    cmake中使用宏

    cmake中使用宏的几种方法:
    1) set(CMAKE_C_FLAGS “”)
    2) add_definitions()
    3) 通过cmake command传递

    这里我采用在cmake command中传递变量:
    cmake -DFT2_TEST_LOOP=$(CONFIG_ft2_test_loop)
    (这个CONFIG_ft2_test_loop配置选项是由Kbuild生成),FT2_TEST_LOOP又不能直接在c代码中当作宏来使用,只能在CMakelist.txt中根据FT2_TEST_LOOP这个变量(其实是一个变量)来重新生成一个宏定义
    if(FT2_TEST_LOOP)
    set(CMAKE_C_FLAGS “${CMAKE_C_FLAGS} -DFT2_TEST_LOOP”)
    endif(FT2_TEST_LOOP)
    这里的FT2_TEST_LOOP就能在c代码中使用了。

    另外KBuild系统生成的.config文件中显示”CONFIG_ft2_test_loop is not set”的意思是CONFIG_ft2_test_loop已经定义,但是值为0


    参考文章

    1. CMake的使用
    2. CMAKE官网
    展开全文
  • CMake

    千次阅读 2012-06-07 16:16:48
    First time to use cmake in Win7 64bit. The MinGW compiler is installed. (1) Configure top CMakeLists.txt as below to point to MinGW compiler. cmake_minimum_required(VERSION 2.6) project(CMAKEDEMO)

    First time to use cmake in Win7 64bit. The MinGW compiler is installed.
    (1) Configure top CMakeLists.txt as below to point to MinGW compiler.

    cmake_minimum_required(VERSION 2.6)
    project(CMAKEDEMO)
    set(CMAKE_C_COMPILER "mingw32-gcc")
    set(CMAKE_CXX_COMPILER "mingw32-g++")

    set(CMAKE_CXX_FLAGS "-g -Wall")
    add_subdirectory(w01-cpp)

    (2) Create a build dir, enter to the build dir and issue 'cmake -G "MinGW Makefiles" ..', encounter following error which complained the sh.exe is in the path.

    CMake Error at c:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeMinGWFindMake.cmake:20 (MESSAGE):
      sh.exe was found in your PATH, here:

      c:/Program Files (x86)/Git/bin/sh.exe

      For MinGW make to work correctly sh.exe must NOT be in your path.

      Run cmake from a shell that does not have sh.exe in your PATH.

      If you want to use a UNIX shell, then use MSYS Makefiles.

    ...

    (3) That is not good, I need Git.  I try 'cmake -G "MSYS Makefiles" ..' and then "make", it worked.

    (4) I also tried to rename my sh.exe to shxx.exe, and then issue 'cmake -G "MSYS Makefiles" ..' again, then issue  'mingw32-make', also worked.

    Reference:

    http://www.cnblogs.com/ode/archive/2011/08/03/2147089.html



    展开全文
  • Linux下CMake简明教程

    万次阅读 多人点赞 2018-08-26 23:14:45
    CMake是开源、跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本地的Makefile,这个配置文件是独立于运行平台和编译器的,这样就不用亲自去编写Makefile了,而且配置文件可以直接拿到其它平台上使用,...

    CMake是开源、跨平台的构建工具,可以让我们通过编写简单的配置文件去生成本地的Makefile,这个配置文件是独立于运行平台和编译器的,这样就不用亲自去编写Makefile了,而且配置文件可以直接拿到其它平台上使用,无需修改,非常方便。
    这里写图片描述
    本文主要讲述在Linux下如何使用CMake来编译我们的程序。


    一 安装CMake

    本文使用ubuntu18.04,安装cmake使用如下命令,
    sudo apt install cmake
    安装完成后,在终端下输入cmake -version查看cmake版本,
    这里写图片描述
    这样cmake就安装好了。


    二 简单样例

    首先让我们从最简单的代码入手,先来体验下cmake是如何操作的。编写main.c,如下,

    #include <stdio.h>
    
    int main(void)
    {
    	printf("Hello World\n");
    
    	return 0;
    }
    

    然后在main.c相同目录下编写CMakeLists.txt,内容如下,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    add_executable(main main.c)
    

    第一行意思是表示cmake的最低版本要求是2.8,我们安装的是3.10.2;第二行是表示本工程信息,也就是工程名叫demo;第三行比较关键,表示最终要生成的elf文件的名字叫main,使用的源文件是main.c
    在终端下切到main.c所在的目录下,然后输入以下命令运行cmake,
    cmake .
    会输出如下信息,
    这里写图片描述
    再来看看目录下的文件,
    这里写图片描述
    可以看到成功生成了Makefile,还有一些cmake运行时自动生成的文件。
    然后在终端下输入make并回车,
    这里写图片描述
    可以看到执行cmake生成的Makefile可以显示进度,并带颜色。再看下目录下的文件,
    这里写图片描述
    可以看到我们需要的elf文件main也成功生成了,然后运行main,
    这里写图片描述
    运行成功!

    PS: 如果想重新生成main,输入make clean就可以删除main这个elf文件。


    三 同一目录下多个源文件

    接下来进入稍微复杂的例子:在同一个目录下有多个源文件。
    在之前的目录下添加2个文件,testFunc.c和testFunc.h。添加完后整体文件结构如下,
    这里写图片描述
    testFunc.c内容如下,

    /*
    ** testFunc.c
    */
    
    #include <stdio.h>
    #include "testFunc.h"
    
    void func(int data)
    {
    	printf("data is %d\n", data);
    }
    

    testFunc.h内容如下,

    /*
    ** testFunc.h
    */
    
    #ifndef _TEST_FUNC_H_
    #define _TEST_FUNC_H_
    
    void func(int data);
    
    #endif
    

    修改main.c,调用testFunc.h里声明的函数func(),

    #include <stdio.h>
    
    #include "testFunc.h"
    
    int main(void)
    {
    	func(100);
    
    	return 0;
    }
    

    修改CMakeLists.txt,在add_executable的参数里把testFunc.c加进来

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    add_executable(main main.c testFunc.c)
    

    然后重新执行cmake生成Makefile并运行make,
    这里写图片描述
    然后运行重新生成的elf文件main,
    这里写图片描述
    运行成功!

    可以类推,如果在同一目录下有多个源文件,那么只要在add_executable里把所有源文件都添加进去就可以了。但是如果有一百个源文件,再这样做就有点坑了,无法体现cmake的优越性,cmake提供了一个命令可以把指定目录下所有的源文件存储在一个变量中,这个命令就是 aux_source_directory(dir var)
    第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量。

    我们在main.c所在目录下再添加2个文件,testFunc1.c和testFunc1.h。添加完后整体文件结构如下,
    这里写图片描述
    testFunc1.c如下,

    /*
    ** testFunc1.c
    */
    
    #include <stdio.h>
    #include "testFunc1.h"
    
    void func1(int data)
    {
    	printf("data is %d\n", data);
    }
    

    testFunc1.h如下,

    /*
    ** testFunc1.h
    */
    
    #ifndef _TEST_FUNC1_H_
    #define _TEST_FUNC1_H_
    
    void func1(int data);
    
    #endif
    

    再修改main.c,调用testFunc1.h里声明的函数func1(),

    #include <stdio.h>
    
    #include "testFunc.h"
    #include "testFunc1.h"
    
    int main(void)
    {
    	func(100);
    	func1(200);
    
    	return 0;
    }
    

    修改CMakeLists.txt,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    aux_source_directory(. SRC_LIST)
    
    add_executable(main ${SRC_LIST})
    

    使用aux_source_directory把当前目录下的源文件存列表存放到变量SRC_LIST里,然后在add_executable里调用SRC_LIST(注意调用变量时的写法)。
    再次执行cmake和make,并运行main,
    这里写图片描述
    可以看到运行成功了。

    aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    set( SRC_LIST
    	 ./main.c
    	 ./testFunc1.c
    	 ./testFunc.c)
    
    add_executable(main ${SRC_LIST})
    

    四 不同目录下多个源文件

    一般来说,当程序文件比较多时,我们会进行分类管理,把代码根据功能放在不同的目录下,这样方便查找。那么这种情况下如何编写CMakeLists.txt呢?
    我们把之前的源文件整理一下(新建2个目录test_func和test_func1),整理好后整体文件结构如下,
    这里写图片描述
    把之前的testFunc.c和testFunc.h放到test_func目录下,testFunc1.c和testFunc1.h则放到test_func1目录下。

    其中,CMakeLists.txt和main.c在同一目录下,内容修改成如下所示,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    include_directories (test_func test_func1)
    
    aux_source_directory (test_func SRC_LIST)
    aux_source_directory (test_func1 SRC_LIST1)
    
    add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})
    

    这里出现了一个新的命令:include_directories。该命令是用来向工程添加多个指定头文件的搜索路径,路径之间用空格分隔。
    因为main.c里include了testFunc.h和testFunc1.h,如果没有这个命令来指定头文件所在位置,就会无法编译。当然,也可以在main.c里使用include来指定路径,如下

    #include "test_func/testFunc.h"
    #include "test_func1/testFunc1.h"
    

    只是这种写法不好看。
    另外,我们使用了2次aux_source_directory,因为源文件分布在2个目录下,所以添加2次。


    五 正规一点的组织结构

    正规一点来说,一般会把源文件放到src目录下,把头文件放入到include文件下,生成的对象文件放入到build目录下,最终输出的elf文件会放到bin目录下,这样整个结构更加清晰。让我们把前面的文件再次重新组织下,
    这里写图片描述
    我们在最外层目录下新建一个CMakeLists.txt,内容如下,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    add_subdirectory (src)
    

    这里出现一个新的命令add_subdirectory(),这个命令可以向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制的存放位置,具体用法可以百度。
    这里指定src目录下存放了源文件,当执行cmake时,就会进入src目录下去找src目录下的CMakeLists.txt,所以在src目录下也建立一个CMakeLists.txt,内容如下,

    aux_source_directory (. SRC_LIST)
    
    include_directories (../include)
    
    add_executable (main ${SRC_LIST})
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    

    这里又出现一个新的命令set,是用于定义变量的,EXECUTABLE_OUT_PATH和PROJECT_SOURCE_DIR是CMake自带的预定义变量,其意义如下,

    • EXECUTABLE_OUTPUT_PATH :目标二进制可执行文件的存放位置
    • PROJECT_SOURCE_DIR:工程的根目录

    所以,这里set的意思是把存放elf文件的位置设置为工程根目录下的bin目录。(cmake有很多预定义变量,详细的可以网上搜索一下)

    添加好以上这2个CMakeLists.txt后,整体文件结构如下,
    这里写图片描述
    下面来运行cmake,不过这次先让我们切到build目录下,然后输入以下命令,
    cmake ..
    Makefile会在build目录下生成,然后在build目录下运行make,
    这里写图片描述
    运行ok,我们再切到bin目录下,发现main已经生成,并运行测试,
    这里写图片描述
    测试OK!

    这里解释一下为什么在build目录下运行cmake?从前面几个case中可以看到,如果不这样做,cmake运行时生成的附带文件就会跟源码文件混在一起,这样会对程序的目录结构造成污染,而在build目录下运行cmake,生成的附带文件就只会待在build目录下,如果我们不想要这些文件了就可以直接清空build目录,非常方便。

    另外一种写法:
    前面的工程使用了2个CMakeLists.txt,最外层的CMakeLists.txt用于掌控全局,使用add_subdirectory来控制其它目录下的CMakeLists.txt的运行。

    上面的例子也可以只使用一个CMakeLists.txt,把最外层的CMakeLists.txt内容改成如下,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
    aux_source_directory (src SRC_LIST)
    
    include_directories (include)
    
    add_executable (main ${SRC_LIST})
    

    同时,还要把src目录下的CMakeLists.txt删除。


    六 动态库和静态库的编译控制

    有时只需要编译出动态库和静态库,然后等着让其它程序去使用。让我们看下这种情况该如何使用cmake。首先按照如下重新组织文件,只留下testFunc.h和TestFunc.c,
    在这里插入图片描述

    我们会在build目录下运行cmake,并把生成的库文件存放到lib目录下。
    CMakeLists.txt内容如下,

    cmake_minimum_required (VERSION 3.5)
    
    project (demo)
    
    set (SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.c)
    
    add_library (testFunc_shared SHARED ${SRC_LIST})
    add_library (testFunc_static STATIC ${SRC_LIST})
    
    set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
    set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")
    
    set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
    

    这里又出现了新的命令和预定义变量,

    • add_library: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
    • set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
    • LIBRARY_OUTPUT_PATH: 库文件的默认输出路径,这里设置为工程目录下的lib目录

    好了,让我们进入build目录下运行cmake ..,成功后再运行make,
    这里写图片描述
    cd到lib目录下进行查看,发现已经成功生成了动态库和静态库,
    这里写图片描述
    PS:前面使用set_target_properties重新定义了库的输出名称,如果不使用set_target_properties也可以,那么库的名称就是add_library里定义的名称,只是连续2次使用add_library指定库名称时(第一个参数),这个名称不能相同,而set_target_properties可以把名称设置为相同,只是最终生成的库文件后缀不同(一个是.so,一个是.a),这样相对来说会好看点。


    七 对库进行链接

    既然我们已经生成了库,那么就进行链接测试下。重新建一个工程目录,然后把上节生成的库拷贝过来,然后在在工程目录下新建src目录和bin目录,在src目录下添加一个main.c,整体结构如下,
    在这里插入图片描述

    main.c内容如下,

    #include <stdio.h>
    
    #include "testFunc.h"
    
    int main(void)
    {
        func(100);
        
        return 0;
    }
    

    工程目录下的CMakeLists.txt内容如下,

    cmake_minimum_required (VERSION 3.5)
    
    project (demo)
    
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
    set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)
    
    # find testFunc.h
    include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)
    
    find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)
    
    add_executable (main ${SRC_LIST})
    
    target_link_libraries (main ${TESTFUNC_LIB})
    

    这里出现2个新的命令,

    • find_library: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径,其它用法可以参考cmake文档
    • target_link_libraries: 把目标文件与库文件进行链接

    使用find_library的好处是在执行cmake ..时就会去查找库是否存在,这样可以提前发现错误,不用等到链接时。

    cd到build目录下,然后运行cmake .. && make,最后进入到bin目录下查看,发现main已经生成,运行之,
    这里写图片描述
    运行成功!

    ps:在lib目录下有testFunc的静态库和动态库,find_library(TESTFUNC_LIB testFunc ...默认是查找动态库,如果想直接指定使用动态库还是静态库,可以写成find_library(TESTFUNC_LIB libtestFunc.so ...或者find_library(TESTFUNC_LIB libtestFunc.a ...

    ps: 查看elf文件使用了哪些库,可以使用readelf -d ./xx来查看

    之前本节教程使用的是库查找方法是link_directories,但是很多读者反映运行时有问题,本人去官方文档上查了下,发现不建议使用了,推荐使用find_library或者find_package
    在这里插入图片描述


    八 添加编译选项

    有时编译程序时想添加一些编译选项,如-Wall,-std=c++11等,就可以使用add_compile_options来进行操作。
    这里以一个简单程序来做演示,main.cpp如下

    #include <iostream>
    
    int main(void)
    {
        auto data = 100;
        std::cout << "data: " << data << "\n";
        return 0;
    }
    

    CMakeLists.txt内容如下,

    cmake_minimum_required (VERSION 2.8)
    
    project (demo)
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
    add_compile_options(-std=c++11 -Wall) 
    
    add_executable(main main.cpp)
    

    整体目录结构如下,
    在这里插入图片描述
    然后cd到build目录下,执行cmake .. && make命令,就可以在bin目录下得到main的elf文件


    九 添加控制选项

    有时希望在编译代码时只编译一些指定的源码,可以使用cmake的option命令,主要遇到的情况分为2种:

    1. 本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件
    2. 对于同一个bin文件,只想编译其中部分代码(使用宏来控制)

    第1种情况

    假设我们现在的工程会生成2个bin文件,main1和main2,现在整体结构体如下,
    在这里插入图片描述
    外层的CMakeLists.txt内容如下,

    cmake_minimum_required(VERSION 3.5)
    
    project(demo)
    
    option(MYDEBUG "enable debug compilation" OFF)
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
    add_subdirectory(src)
    

    这里使用了option命令,其第一个参数是这个option的名字,第二个参数是字符串,用来描述这个option是来干嘛的,第三个是option的值,ON或OFF,也可以不写,不写就是默认OFF。

    然后编写src目录下的CMakeLists.txt,如下

    cmake_minimum_required (VERSION 3.5)
    
    add_executable(main1 main1.c)
    
    if (MYDEBUG)
        add_executable(main2 main2.c)
    else()
        message(STATUS "Currently is not in debug mode")    
    endif()
    

    注意,这里使用了if-else来根据option来决定是否编译main2.c
    其中main1.c和main2.c的内容如下,

    // main1.c
    #include <stdio.h>
    
    int main(void)
    {
        printf("hello, this main1\n");
        
        return 0;
    }
    
    // main2.c
    #include <stdio.h>
    
    int main(void)
    {
        printf("hello, this main2\n");
        
        return 0;
    }
    

    然后cd到build目录下输入cmake .. && make就可以只编译出main1,如果想编译出main2,就把MYDEBUG设置为ON,再次输入cmake .. && make重新编译。

    每次想改变MYDEBUG时都需要去修改CMakeLists.txt,有点麻烦,其实可以通过cmake的命令行去操作,例如我们想把MYDEBUG设置为OFF,先cd到build目录,然后输入cmake .. -DMYDEBUG=ON,这样就可以编译出main1和main2 (在bin目录下)
    在这里插入图片描述

    第2种情况

    假设我们有个main.c,其内容如下,

    #include <stdio.h>
    
    int main(void)
    {
    #ifdef WWW1
        printf("hello world1\n");
    #endif    
    
    #ifdef WWW2     
        printf("hello world2\n");
    #endif
    
        return 0;
    }
    

    可以通过定义宏来控制打印的信息,我们CMakeLists.txt内容如下,

    cmake_minimum_required(VERSION 3.5)
    
    project(demo)
    
    set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
    option(WWW1 "print one message" OFF)
    option(WWW2 "print another message" OFF)
    
    if (WWW1)
        add_compile_options(-DWWW1)
    endif()
    
    if (WWW2)
        add_compile_options(-DWWW2)
    endif()
    
    add_executable(main main.c)
    

    这里把option的名字保持和main.c里的宏名称一致,这样更加直观,也可以选择不同的名字。通过与add_compile_options()的配合,就可以控制单个bin文件的打印输出了。

    整体工程结构如下,
    在这里插入图片描述
    cd到build目录下执行cmake .. && make,然后到bin目录下执行./main,可以看到打印为空,
    接着分别按照下面指令去执行,然后查看打印效果,

    • cmake .. -DWWW1=ON -DWWW2=OFF && make
    • cmake .. -DWWW1=OFF -DWWW2=ON && make
    • cmake .. -DWWW1=ON -DWWW2=ON && make

    这里有个小坑要注意下:假设使用cmake设置了一个option叫A,下次再设置别的option例如B,如果没有删除上次执行cmake时产生的缓存文件,那么这次虽然没设置A,也会默认使用A上次的option值。

    所以如果option有变化,要么删除上次执行cmake时产生的缓存文件,要么把所有的option都显式的指定其值。


    十 总结

    以上是自己学习CMake的一点学习记录,通过简单的例子让大家入门CMake,学习的同时也阅读了很多网友的博客。CMake的知识点还有很多,具体详情可以在网上搜索。总之,CMake可以让我们不用去编写复杂的Makefile,并且跨平台,是个非常强大并值得一学的工具。

    如果有写的不对的地方,希望能留言指正,谢谢阅读。

    展开全文
  • cmake快速入门

    万次阅读 多人点赞 2018-09-12 10:10:16
    1, cmake 的介绍,下载,安装和使用 2, cmake 的手册详解,我关注了 -C和-G 的使用 3, 在Linux中构建cmake 的工程 第一个问题: cmake 介绍,下载和安装以及使用:https://fukun.org/archives/0421949.html ...

        

    本博文的大概框架:

    1, cmake 的介绍,下载,安装和使用

    2, cmake 的手册详解,我关注了 -C和-G 的使用

    3, 在Linux中构建cmake 的工程

    第一个问题: cmake 介绍,下载和安装以及使用:https://fukun.org/archives/0421949.html

    cmake是kitware公司以及一些开源开发者在开发几个工具套件(VTK)的过程中所产生的衍生品。后来经过发展,最终形成体系,在2001年成为一个独立的开放源代码项目。其官方网站是www.cmake.org,可以通过访问官方网站来获得更多关于cmake的信息,而且目前官方的英文文档比以前有了很大的改进,可以作为实践中的参考手册。

    cmake的流行离不开KDE4的选择。KDE开发者在使用autotools近10年之后,终于决定为KDE4项目选择一个新的工程构建工具。之所以如此,用KDE开发者们自己话来说,就是:只有少数几个“编译专家”能够掌握KDE现在的构建体系。在经历了unsermake,scons以及cmake的选型和尝试之后,KDE4最终决定使用cmake作为自己的构建系统。在迁移过程中,进展一场的顺利,并获得了cmake开发者的支持。所以,目前的KDE4开发版本已经完全使用cmake来进行构建。

    随着cmake 在KDE4项目中的成功,越来越多的项目正在使用cmake作为其构建工具,这也使得cmake正在成为一个主流的构建体系。

    一、为何要使用项目构建工具?

    为何要使用cmake和autotools之类的项目构建工具? 我想,这恐怕是刚刚接触软件项目的人最应该问的问题之一了。

    “Hello, world!“这个最经典的程序相信我们每个人都写过。无论在什么平台下,编译和运行这个程序都仅需要非常简单的操作。但事实上,hello,world最多只能算是一个实例程序,根本算不上一个真正的软件项目。

    任何一个软件项目,除了写代码之外,还有一个更为重要的任务,就是如何组织和管理这些代码,使项目代码层次结构清晰易读,这对以后的维护工作大有裨益。使想一下,如果把一个像KDE4那么大的项目像hello world那样,把全部代码都放到一个main.cpp文件中,那将会是多么恐怖的一件事情。别说KDE4,就是我们随便一个几千行代码的小项目,也不会有人干这种蠢事。

    决定代码的组织方式及其编译方式,也是程序设计的一部分。因此,我们需要cmake和autotools这样的工具来帮助我们构建并维护项目代码。
    看到这里,也许你会想到makefile,makefile不就是管理代码自动化编译的工具吗?为什么还要用别的构建工具?

    其实,cmake和autotools正是makefile的上层工具,它们的目的正是为了产生可移植的makefile,并简化自己动手写makefile时的巨大工作量。如果你自己动手写过makefile,你会发现,makefile通常依赖于你当前的编译平台,而且编写makefile的工作量比较大,解决依赖关系时也容易出错。因此,对于大多数项目,应当考虑使用更自动化一些的 cmake或者autotools来生成makefile,而不是上来就动手编写。

    总之,项目构建工具能够帮我们在不同平台上更好地组织和管理我们的代码及其编译过程,这是我们使用它的主要原因。

    二、cmake的主要特点:

    cmake和autotools是不同的项目管理工具,有各自的特点和用户群。存在即为合理,因此我们不会对两者进行优劣比较,这里只给出cmake的一些主要特点:
            1.开放源代码,使用类 BSD 许可发布。
            2.跨平台,并可生成 native 编译配置文件,在 Linux/Unix 平台,生成 makefile,在 苹果平台,可以生成 xcode,在 Windows 平台,可以生成 MSVC 的工程文件。
            3.能够管理大型项目,KDE4 就是最好的证明。
            4.简化编译构建过程和编译过程。Cmake 的工具链非常简单:cmake+make。
            5.高效率,按照 KDE 官方说法,CMake 构建 KDE4 的 kdelibs 要比使用 autotools 来 构建 KDE3.5.6 的 kdelibs 快 40%,主要是因为 Cmake 在工具链中没有 libtool。
            6.可扩展,可以为 cmake 编写特定功能的模块,扩充 cmake 功能。

    三、安装cmake

    安装cmake 对任何用户而言都不该再成为一个问题。几乎所有主流的Linux发行版的源中都包含有cmake的安装包,直接从源中添加即可。当然,也可以在官方网站下载源代码自行编译安装。

    对于Windows和Mac用户,cmake的官方网站上有相应的安装包,下载安装即可,无须赘述。

    注:为了能够测试本文中的实例程序,如果读者的Linux系统中所带的cmake版本低于2.6,请从官网下载2.6版本或以上的源代码进行编译并安装。
    在linux下安装cmake

    首先下载源码包
            http://www.cmake.org/cmake/resources/software.html

            这里下载的是cmake-2.6.4.tar.gz

    随便找个目录解压缩

    Example

    1

    2

            tar -xzvf cmake-2.6.4.tar.gz

            cd cmake-2.6.4

            依次执行:

    Example

    1

    2

    3

            ./bootstrap

             make

            make install

            cmake 会默认安装在 /usr/local/bin 下面

    四、从“Hello, world!”开始

    了解cmake的基本原理并在系统中安好cmake后,我们就可以用cmake来演示那个最经典的”Hello, world!”了。

    第一步,我们给这个项目起个名字——就叫HELLO吧。因此,第一部为项目代码建立目录hello,与此项目有关的所有代码和文档都位于此目录下。

    第二步,在hello目录下建立一个main.c文件,其代码如下:

    Example

    1

    2

    3

    4

    5

    6

            #include

            int main(void)

            {

                    printf(”Hello,Worldn”);

                    return 0;

            }

    第三步,在hello目录下建立一个新的文件CMakeLists.txt,它就是 cmake所处理的“代码“。其实,使用cmake管理项目本身也是在编程,所以称之为“代码(或脚本)”并不为过。在CMakeLists.txt文件中输入下面的代码(#后面的内容为代码行注释):
            #cmake最低版本需求,不加入此行会受到警告信息
            CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
            PROJECT(HELLO) #项目名称
            #把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
            AUX_SOURCE_DIRECTORY(. SRC_LIST)
            #生成应用程序 hello (在windows下会自动生成hello.exe)
            ADD_EXECUTABLE(hello ${SRC_LIST})

    至此,整个hello项目就已经构建完毕,可以进行编译了。

    第四步,编译项目。

    为了使用外部编译方式编译项目,需要先在目录hello下新建一个目录build(也可以是其他任何目录名)。现在,项目整体的目录结构为:
            hello/
            |– CMakeLists.txt
             |– build /
            `– main.c

    在windows下,cmake提供了图形界面,设定hello为source目录,build为二进制目录,然后点击configure即可开始构建,之后进入build目录运行make命令编译。

    在linux命令行下,首先进入目录build,然后运行命令(注:后面的“..”不可缺少):

    该命令使cmake检测编译环境,并生成相应的makefile。接着,运行命令make进行编译。编译后,生成的所有中间文件和可执行文件会在build目录下。 下面是我在ubuntu上的运行过程:

            $ ls
            hello
            $ cd hello/build/
            $ ls
            $ cmake ..
            – The C compiler identification is GNU
            – The CXX compiler identification is GNU
            – Check for working C compiler: /usr/bin/gcc
            – Check for working C compiler: /usr/bin/gcc — works
            – Detecting C compiler ABI info
             – Detecting C compiler ABI info - done
            – Check for working CXX compiler: /usr/bin/c++
            – Check for working CXX compiler: /usr/bin/c++ — works
            – Detecting CXX compiler ABI info
            – Detecting CXX compiler ABI info - done
            – Configuring done
            – Generating done
            – Build files have been written to: /home/kermit/Project/cmake/hello/build
            $ make
            Scanning dependencies of target hello
            [100%] Building C object CMakeFiles/hello.dir/main.c.o
            Linking C executable hello
            [100%] Built target hello
            $ ls
            CMakeCache.txt CMakeFiles cmake_install.cmake hello Makefile
            $ ./hello
            Hello,World

    上面,我们提到了一个名词,叫外部编译方式。其实,cmake还可以直接在当前目录进行编译,无须建立build目录。但是,这种做法会将所有生成的中间文件和源代码混在一起,而且cmake生成的makefile无法跟踪所有的中间文件,即无法使用”make distclean”命令将所有的中间文件删除。因此,我们推荐建立build目录进行编译,所有的中间文件都会生成在build目录下,需要删除时直接清空该目录即可。这就是所谓的外部编译方式。

    第二个问题: cmake 的手册详解:http://www.cnblogs.com/coderfenghc/archive/2012/06/16/CMake_ch_01.html

     

    第三个问题:在Linux中使用cmake 构建应用程序: http://www.ibm.com/developerworks/cn/linux/l-cn-cmake/

    CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法。在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:

    1. 编写 CmakeLists.txt
    2. 执行命令cmake PATH或者ccmake PATH生成 Makefile ( PATH  CMakeLists.txt 所在的目录 )
    3. 使用 make 命令进行编译。

    第一个工程

    现假设我们的项目中只有一个源文件 main.cpp

    清单 1 源文件 main.cpp

    1 #include<iostream>
    
    2
    
    3 int main()
    
    4 {
    
    5 std::cout<<"Hello word!"<<std::endl;
    
    6 return 0;
    
    7 }

    为了构建该项目,我们需要编写文件 CMakeLists.txt 并将其与 main.cpp 放在 同一个目录下:

    清单 2 CMakeLists.txt

    1 PROJECT(main)
    
    2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
    
    3 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
    
    4 ADD_EXECUTABLE(main ${DIR_SRCS})

    CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的,符号"#"后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。例如对于清单2的 CMakeLists.txt 文件:第一行是一条命令,名称是 PROJECT ,参数是 main ,该命令表示项目的名称是 main 。第二行的命令限定了 CMake 的版本。第三行使用命令 AUX_SOURCE_DIRECTORY 将当前目录中的源文件名称赋值给变量 DIR_SRCS 。 CMake 手册中对命令 AUX_SOURCE_DIRECTORY 的描述如下:

    aux_source_directory(<dir> <variable>)

    该命令会把参数 <dir> 中所有的源文件名称赋值给参数 <variable> 。 第四行使用命令 ADD_EXECUTABLE 指示变量 DIR_SRCS 中的源文件需要编译 成一个名称为 main 的可执行文件。

    完成了文件 CMakeLists.txt 的编写后需要使用 cmake 或 ccmake 命令生成Makefile 。 ccmake 与命令 cmake 的不同之处在于 ccmake 提供了一个图形化的操作界面。cmake 命令的执行方式如下:

    cmake [options] <path-to-source>

    这里我们进入了 main.cpp 所在的目录后执行 “cmake .” 后就可以得到 Makefile 并使用 make 进行编译,如下图所示。

    图 1. camke 的运行结果

    camke 的运行结果

    处理多源文件目录的方法

    CMake 处理源代码分布在不同目录中的情况也十分简单。现假设我们的源代码分布情况如下:

    图 2. 源代码分布情况

    源代码分布情况

    其中 src 目录下的文件要编译成一个链接库。

    第一步,项目主目录中的 CMakeLists.txt

    在目录 step2 中创建文件 CMakeLists.txt 。文件内容如下:

    清单 3 目录 step2 中的 CMakeLists.txt

    1 PROJECT(main)
    2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 
    3 ADD_SUBDIRECTORY( src )
    4 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
    5 ADD_EXECUTABLE(main ${DIR_SRCS}  )
    6 TARGET_LINK_LIBRARIES( main Test )

    相对于清单 2,该文件添加了下面的内容: 第三行,使用命令 ADD_SUBDIRECTORY 指明本项目包含一个子目录 src 。第六行,使用命令 TARGET_LINK_LIBRARIES 指明可执行文件 main 需要连接一个名为Test的链接库 。

    第二步,子目录中的 CmakeLists.txt

    在子目录 src 中创建 CmakeLists.txt。文件内容如下:

    清单 4. 目录 src 中的 CmakeLists.txt

    1 AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
    2 ADD_LIBRARY ( Test ${DIR_TEST1_SRCS})

    在该文件中使用命令 ADD_LIBRARY 将 src 目录中的源文件编译为共享库。

    第三步,执行 cmake

    至此我们完成了项目中所有 CMakeLists.txt 文件的编写,进入目录 step2 中依次执行命令 “cmake .” 和 “make” 得到结果如下:

    图3. 处理多源文件目录时 cmake 的执行结果

    处理多源文件目录时 cmake 的执行结果

    在执行 cmake 的过程中,首先解析目录 step2 中的 CMakeLists.txt ,当程序执行命令 ADD_SUBDIRECTORY( src ) 时进入目录 src 对其中的 CMakeLists.txt 进行解析。

    在工程中查找并使用其他程序库的方法

    在开发软件的时候我们会用到一些函数库,这些函数库在不同的系统中安装的位置可能不同,编译的时候需要首先找到这些软件包的头文件以及链接库所在的目录以便生成编译选项。例如一个需要使用博克利数据库项目,需要头文件db_cxx.h 和链接库 libdb_cxx.so ,现在该项目中有一个源代码文件 main.cpp ,放在项目的根目录中。

    第一步,程序库说明文件

    在项目的根目录中创建目录 cmake/modules/ ,在 cmake/modules/ 下创建文件 Findlibdb_cxx.cmake ,内容如下:

    清单 5. 文件 Findlibdb_cxx.cmake

    01 MESSAGE(STATUS "Using bundled Findlibdb.cmake...")
    0203 FIND_PATH(
    04   LIBDB_CXX_INCLUDE_DIR
    05   db_cxx.h 
    06   /usr/include/ 
    07   /usr/local/include/ 
    08   )
    09 
    10 FIND_LIBRARY(
    11   LIBDB_CXX_LIBRARIES NAMES  db_cxx
    12   PATHS /usr/lib/ /usr/local/lib/
    13   )

    文件 Findlibdb_cxx.cmake 的命名要符合规范: FindlibNAME.cmake ,其中NAME 是函数库的名称。Findlibdb_cxx.cmake 的语法与 CMakeLists.txt 相同。这里使用了三个命令: MESSAGE , FIND_PATH 和 FIND_LIBRARY 。

    • 命令 MESSAGE 将参数的内容输出到终端
    • 命令 FIND_PATH 指明头文件查找的路径,原型如下
      find_path(<VAR> name1 [path1 path2 ...]) 该命令在参数 path* 指示的目录中查找文件 name1 并将查找到的路径保存在变量 VAR中。清单538行的意思是在 /usr/include/  /usr/local/include/ 中查找文件db_cxx.h ,并将db_cxx.h 所在的路径保存在 LIBDB_CXX_INCLUDE_DIR中。
    • 命令 FIND_LIBRARY  FIND_PATH 类似,用于查找链接库并将结果保存在变量中。清单51013行的意思是在目录 /usr/lib/  /usr/local/lib/ 中寻找名称为 db_cxx 的链接库,并将结果保存在 LIBDB_CXX_LIBRARIES

    第二步, 项目的根目录中的 CmakeList.txt

    在项目的根目录中创建 CmakeList.txt :

    清单 6. 可以查找链接库的 CMakeList.txt

    01 PROJECT(main)
    
    02 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
    
    03 SET(CMAKE_SOURCE_DIR .)
    
    04 SET(CMAKE_MODULE_PATH ${CMAKE_ROOT}/Modules ${CMAKE_SOURCE_DIR}/cmake/modules)
    
    05 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
    
    06 ADD_EXECUTABLE(main ${DIR_SRCS})
    
    0708 FIND_PACKAGE( libdb_cxx REQUIRED)
    
    09 MARK_AS_ADVANCED(
    
    10 LIBDB_CXX_INCLUDE_DIR
    
    11 LIBDB_CXX_LIBRARIES
    
    12 )
    
    13 IF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)
    
    14 MESSAGE(STATUS "Found libdb libraries")
    
    15 INCLUDE_DIRECTORIES(${LIBDB_CXX_INCLUDE_DIR})
    
    16 MESSAGE( ${LIBDB_CXX_LIBRARIES} )
    
    17 TARGET_LINK_LIBRARIES(main ${LIBDB_CXX_LIBRARIES}18 )
    
    19 ENDIF (LIBDB_CXX_INCLUDE_DIR AND LIBDB_CXX_LIBRARIES)

    在该文件中第4行表示到目录 ./cmake/modules 中查找 Findlibdb_cxx.cmake ,8-19 行表示查找链接库和头文件的过程。第8行使用命令 FIND_PACKAGE 进行查找,这条命令执行后 CMake 会到变量 CMAKE_MODULE_PATH 指示的目录中查找文件 Findlibdb_cxx.cmake 并执行。第13-19行是条件判断语句,表示如果 LIBDB_CXX_INCLUDE_DIR 和 LIBDB_CXX_LIBRARIES 都已经被赋值,则设置编译时到 LIBDB_CXX_INCLUDE_DIR 寻找头文件并且设置可执行文件 main 需要与链接库 LIBDB_CXX_LIBRARIES 进行连接。

    第三步,执行 cmake

    完成 Findlibdb_cxx.cmake 和 CMakeList.txt 的编写后在项目的根目录依次执行 “cmake . ” 和 “make ” 可以进行编译,结果如下图所示:

    图 4. 使用其他程序库时 cmake 的执行结果

    使用其他程序库时 cmake 的执行结果

    使用 cmake 生成 debug 版和 release 版的程序

    在 Visual Studio 中我们可以生成 debug 版和 release 版的程序,使用 CMake 我们也可以达到上述效果。debug 版的项目生成的可执行文件需要有调试信息并且不需要进行优化,而 release 版的不需要调试信息但需要优化。这些特性在 gcc/g++ 中是通过编译时的参数来决定的,如果将优化程度调到最高需要设置参数-O3,最低是 -O0 即不做优化;添加调试信息的参数是 -g -ggdb ,如果不添加这个参数,调试信息就不会被包含在生成的二进制文件中。

    CMake 中有一个变量 CMAKE_BUILD_TYPE ,可以的取值是 Debug Release RelWithDebInfo 和 MinSizeRel。当这个变量值为 Debug 的时候,CMake 会使用变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG 中的字符串作为编译选项生成 Makefile ,当这个变量值为 Release 的时候,工程会使用变量 CMAKE_CXX_FLAGS_RELEASE 和 CMAKE_C_FLAGS_RELEASE 选项生成 Makefile。

    现假设项目中只有一个文件 main.cpp ,下面是一个可以选择生成 debug 版和 release 版的程序的 CMakeList.txt :

    清单 7

    1 PROJECT(main)
    2 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
    3 SET(CMAKE_SOURCE_DIR .)
    45 SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
    6 SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
    78 AUX_SOURCE_DIRECTORY(. DIR_SRCS)
    9 ADD_EXECUTABLE(main ${DIR_SRCS})

    第 5 和 6 行设置了两个变量 CMAKE_CXX_FLAGS_DEBUG 和 CMAKE_CXX_FLAGS_RELEASE, 这两个变量是分别用于 debug 和 release 的编译选项。编辑 CMakeList.txt 后需要执行 ccmake 命令生成 Makefile 。在进入项目的根目录,输入 "ccmake ." 进入一个图形化界面,如下图所示:

    图 5. ccmake 的界面

    ccmake 的界面

    按照界面中的提示进行操作,按 "c" 进行 configure ,这时界面中显示出了配置变量 CMAKE_BUILD_TYPE 的条目。如下图所示:

    图 6. 执行了 configure 以后 ccmake 的界面

    执行了 configure 以后 ccmake 的界面

    下面我们首先生成 Debug 版的 Makefile :将变量 CMAKE_BUILD_TYPE 设置为 Debug ,按 "c" 进行 configure ,按 "g" 生成 Makefile 并退出。这时执行命令 find * | xargs grep "O0" 后结果如下:

    清单 8 find * | xargs grep "O0"的执行结果

    CMakeFiles/main.dir/flags.make:CXX_FLAGS = -O0 -Wall -g -ggdb 
    CMakeFiles/main.dir/link.txt:/usr/bin/c++ -O0 -Wall -g -ggdb 
    CMakeFiles/main.dir/main.cpp.o -o main -rdynamic 
    CMakeLists.txt:SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")

    这个结果说明生成的 Makefile 中使用了变量 CMAKE_CXX_FLAGS_DEBUG 作为编译时的参数。

    下面我们将生成 Release 版的 Makefile :再次执行命令 "ccmake ." 将变量CMAKE_BUILD_TYPE 设置为 Release ,生成 Makefile 并退出。执行命令 find * | xargs grep "O0" 后结果如下:

    清单 9 find * | xargs grep "O0"的执行结果

    CMakeLists.txt:SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")

    而执行命令 find * | xargs grep "O3" 后结果如下:

    清单 10. find * | xargs grep "O3"的执行结果

    CMakeCache.txt:CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
    CMakeCache.txt:CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
    CMakeFiles/main.dir/flags.make:CXX_FLAGS = -O3 -Wall 
    CMakeFiles/main.dir/link.txt:/usr/bin/c++ -O3 -Wall 
    CMakeFiles/main.dir/main.cpp.o -o main -rdynamic 
    CMakeLists.txt:SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

    这两个结果说明生成的 Makefile 中使用了变量 CMAKE_CXX_FLAGS_RELEASE 作为编译时的参数。

    转载于:https://blog.csdn.net/appleml/article/details/52829412

    相关文章:https://blog.csdn.net/wzzfeitian/article/details/40963457

                      https://blog.csdn.net/k346k346/article/details/46898635

    语      法:https://www.mawenbao.com/note/cmake.html#fn1

                     https://www.jianshu.com/p/8909efe13308

                     https://gearyyoung.gitbooks.io/cmake-api/content/cmake/CMake%E8%AF%AD%E6%B3%95.html

    展开全文
  • win10+cmake+vs2019编译64位libevent

    万次阅读 2021-01-31 12:33:00
    win10+cmake+vs2019编译64位libevent 概要: 使用平台:win10_64位 使用工具:cmake、vs2019 目的:在windows下编译libevent的库文件 可以实现任意版本的libevent手动编译 工具依赖 1.libevent下载,下载链接: ...
  • CMakecmake的install指令

    万次阅读 多人点赞 2019-10-31 14:34:21
    cmake的时候,最常见的几个步骤就是: mkdir build && cd build cmake .. make make install 那么,make install的时候,是需要我们定义一个install的目标么? 显然并不需要,作为一个经常需要被运行的...
  • 1. 之前使用cmake的时候一直都没有问题,结果今天再次使用的时候,出现了这样的一个错误提示:CMake Error: Could not find CMAKE_ROOT !!!CMake has most likely not been installed correctly. Modules ...
  • 屏蔽编译过程中的警告信息cmake、QT

    万次阅读 2020-04-27 07:19:39
    在 .cmake 中添加add_definitions(-w)
  • cmake-3.17 cmake-3.18.2下载

    千次阅读 多人点赞 2020-03-25 16:28:01
    cmake 官方下载地址https://cmake.org/files/,里面有各个版本,网速的好的小伙伴可自行选择合适的版本下载 但是外国的网上下载太慢,下面分享几个我已经下载好的版本: Linux版本 cmake-3.17.0.tar.gz cmake-3.9.2...
  • 说到cmake,可能最先想到的就是CmakeLists.txt文件,但是在很多情况下,也会看到.cmake文件。也许,你会诧异,.cmake文件是干什么的,甚至会想.cmake文件是不是cmake的正统文件,而CmakeLists.txt并不是。 但其实,...
  • 自行收藏 https://cmake.org/files/
  • CMake官方教程

    万次阅读 多人点赞 2018-04-03 22:00:21
    很好的一个官方教程翻译文档。 CMake简介 ...目前很多开源的项目都可以通过CMake工具来轻松构建工程,例如博客之前分享的openHMD、hidapi、OSVR-Core等等,代码的分享者提供源代码和相应的Cmake配...
  • CMake Error at cmake/OpenCVUtils.cmake:1047 (message): Failed to download . Status= Call Stack (most recent call first): ../opencv_contrib/modules/dnn/cmake/OpenCVFindLibProtobuf.cmake:32 (ocv...
  • cmake practice cmake实践

    千次阅读 2017-03-30 13:42:00
    之前那本书讲得比较难,而且没有具体的示例,需要有对编程有点深入分析才能弄懂,那本书是培养cmake专家的。 所以现在换本简单易行的教材,先理解CMakeLists.txt,然后才可以做深入分析。 学习cmake完全是因为...
  • 一、Android NDK 构建脚本、 二、CMake 构建脚本示例、 三、CMake 命令手册、 1、CMake 脚本命令、 2、CMake 工程命令
  • 运行 cmake …/ 有以下错误 CMake Error at /usr/local/share/cmake-3.15/Modules/FindPackageHandleStandardArgs.cmake:137 (message): Could NOT find PythonInterp: Found unsuitable version “3.5.2”, but ...
  • cmake编译caffe CMake Error

    千次阅读 2018-05-30 09:11:42
    Q: CMake Error at D:/cmake/share/cmake-3.11/Modules/FindPackageHandleStandardArgs.cmake:137 (message): Could NOT find Atlas (missing: Atlas_CLAPACK_INCLUDE_DIR Atlas_CBLAS_LIBRARY Atlas_BLAS_LIBRAR...
  • 当我使用cmake命令时,报图中的错 第一步先移除原有的cmake 然后在cmake网站下载安装包 https://cmake.org/download/ 我使用的是这个包 解压然后编译安装 cd cmake-3.15.2 ./configure make sudo...
  • CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:85 (list)

    千次阅读 多人点赞 2019-08-26 22:05:23
    Ubuntu 18.4 安装opencv-2.4.10时遇到...CMake Error at cmake/OpenCVDetectCXXCompiler.cmake:85 (list): list GET given empty list Call Stack (most recent call first): CMakeLists.txt:77 (include) CMake...
  • CMake源码编译(cmake升级)

    千次阅读 2017-11-22 21:15:04
    LZ今天在试一个开源代码的效果的时候,发现通过sudo apt-get install cmake安装的版本是cmake 2.8版本的,但是开源代码要求最低版本是cmake 3.4,所以就只能源码安装,网上通过个人软件仓安装的方法试过了,但是结果...
  • CMakelist.txt cmake_minimum_required(VERSION 3.5) project(main) #MESSAGE(FATAL_ERROR "${CMAKE_BUILD_TYPE}") if(CMAKE_COMPILER_IS_GNUCC) message("COMPILER IS...
  • CMake Error: Could not find CMAKE_ROOT !!! cmake安装会,不能运行,出现错误。通常出现的原因是,cmake 命令本来存在,然后进行了安装。 类似于缓存导致失败的一样。 "CMake Error: Could not find CMAKE_ROOT !...
  • CMake 进行调试

    千次阅读 2019-09-18 17:42:44
    在 Linux 下开发,可以用 gdb 进行调试,但是如果工程是用 CMake 构建的,那么需要在 CMakeLists.txt 中加入如下代码: CMake 配置 SET(CMAKE_BUILD_TYPE "Debug") SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 ...
  • Windows下CMake安装教程

    万次阅读 多人点赞 2018-05-16 16:36:11
    环境:Windows 64位首先下载CMake官网下载地址:https://cmake.org/download/里面好多版本,根据自己需要版本进行下载。【注意】选择好自己电脑是什么系统,以及是32位还是64位。(P.S.x86指的是32位系统;x64指的是...
  • CMake安装或CMake Error at CMakeLists

    千次阅读 2019-10-02 22:54:04
    CMake安装或CMake Error at CMakeLists 发生情景: 使用cmake命令安装软件时,报如下错误: CMake Error at CMakeLists.txt:4 (CMAKE_MINIMUM_REQUIRED): CMake 3.0.2 or higher is required. You are ...
  • 本文首发于个人博客... cmake with user defined entry Guide FindXXX.cmake in CMAKEMODULEPATH xxx-config.cmake in CMAKEPREFIXPATH cmake default package FindXXX.cmake use...
  • CMake进阶之初识CMake

    千次阅读 多人点赞 2018-08-03 11:21:26
    平时开发中我们已经习惯了让IDE为我们做好一切,大部分...因为自己在Android开发中发现项目中的NDK部分已经抛弃了传统的Android.mk,与时俱进用上了CMake,因此打算静下心来好好学习学习,本文开始对学习CMake的过程...
  • CMake变量

    2018-08-23 14:00:13
    CMake变量 1.提供信息的变量 CMAKE_ARGC 命令行运行cmake的时候传入的参数的个数 CMAKE_ARGV0 命令行运行时的第一个参数,以此类推CMAKE_ARG1 CMAKE_ARG2… CMAKE_AR 编译使用的archive ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,808
精华内容 39,523
热门标签
关键字:

cmake