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")
...