cmake使用

1. C/C++程序编译过程

C/C++程序的编译过程包括四个部分:

  • 预处理:包括头文件、扩展宏;
  • 编译:检查语法,生成汇编代码;
  • 汇编:将汇编代码转换为机器码,生成目标文件;
  • 链接:合并多个目标文件及所需的静态库文件、或包含动态库调用信息,生成可执行文件。

源程序:

#include <iostream>

using namespace std;

int main()
{
	cout << "hello, world!\n";
	return 0;
}

预处理:

[ming@localhost cmake]$ g++ -E -o hello.i hello.cpp
[ming@localhost cmake]$ ls hello.i
hello.i

编译:

[ming@localhost cmake]$ g++ -S hello.i
[ming@localhost cmake]$ ls hello.s
hello.s

汇编:

[ming@localhost cmake]$ g++ -c hello.s
[ming@localhost cmake]$ ls hello.o
hello.o

链接:

[ming@localhost cmake]$ g++ -o hello hello.o
[ming@localhost cmake]$ ls -l hello
-rwxrwxr-x. 1 ming ming 8800 Oct  6 07:58 hello

2. 单目录单文件

  • hello.cpp

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    	cout << "hello, world!\n";
    	return 0;
    }
    
  • CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    project(demo)
    add_executable(demo hello.cpp)
    

    生成可执行文件 demo,依赖于 hello.cpp 源文件。

  • 编译、执行

    [ming@localhost demo1]$ mkdir build && cd build
    [ming@localhost build]$ cmake ..
    ...
    [ming@localhost build]$ make
    ...
    [ming@localhost build]$ ./demo 
    hello, world!
    

3. 单目录多文件

  • main.cpp

    #include <iostream>
    
    using namespace std;
    
    int add(int, int);
    
    int main()
    {
    	cout << add(2, 9) << '\n';
    	return 0;
    }
    
  • add.cpp

    int add(int a, int b)
    {
    	return a + b;
    }
    
  • CMakeLists.txt

    直接添加依赖的源文件:

    cmake_minimum_required(VERSION 2.8)
    project(demo)
    add_executable(demo main.cpp add.cpp)
    

    或者:

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

    aux_source_directory:将指定目录下(此处是 .)的所有源码文件存储到一个变量中(此处是 SRC)。

  • 编译、执行

    [ming@localhost demo2]$ mkdir build && cd build
    [ming@localhost build]$ cmake ..
    ...
    [ming@localhost build]$ make
    ...
    [ming@localhost build]$ ./demo 
    11
    

4. 多目录多文件

  • 工程结构

    [ming@localhost demo3]$ tree .
    .
    ├── add
    │   ├── add.cpp
    │   ├── add.h
    │   └── CMakeLists.txt
    ├── CMakeLists.txt
    └── src
        ├── CMakeLists.txt
        └── main.cpp
    
    2 directories, 6 files
    
  • add/add.h

    #ifndef ADD_H
    #define ADD_H
    
    int add(int a, int b);
    
    #endif
    
  • add/add.cpp

    #include "add.h"
    
    int add(int a, int b)
    {
    	return a + b;
    }
    
  • add/CMakeLists.txt

    set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
    aux_source_directory(. ADD_SRC)
    add_library(myadd STATIC ${ADD_SRC})
    

    此处指定生成静态库(STATIC,动态库使用 SHARED),生成的库文件存于 ${PROJECT_BINARY_DIR}/lib 目录下。

  • src/main.cpp

    #include <iostream>
    #include "add.h"
    
    using namespace std;
    
    int main()
    {
    	cout << add(1, 9) << '\n';
    	return 0;
    }
    
  • src/CMakeLists.txt

    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
    include_directories(${PROJECT_SOURCE_DIR}/add)
    aux_source_directory(. SRC)
    add_executable(demo ${SRC})
    target_link_libraries(demo myadd)
    

    include_directories:将指定目录添加到头文件搜索路径中。
    生成的可执行文件位于 ${PROJECT_BINARY_DIR}/bin 目录中。
    target_link_libraries:链接库文件。

  • CMakeLists.txt

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

    add_subdirectory:添加并构建子目录。

  • 编译、运行

    [ming@localhost demo3]$ mkdir build && cd build
    [ming@localhost build]$ cmake ..
    ...
    [ming@localhost build]$ make
    ...
    [ming@localhost build]$ ls lib/
    libmyadd.a
    [ming@localhost build]$ ls bin/
    demo
    [ming@localhost build]$ bin/demo 
    10
    

5. 设置编译选项

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
...
上一篇:PowerDNS管理工具开发中学习到的DNS知识


下一篇:C#基础视频