编译
编译过程
- 预处理(通常是以 .i 结尾的文件)
写好的高级语言的程序文本比如 hello.c,预处理器根据 #开头的命令,修改原始的程序,如#include<stdio.h> 将把系统中的头文件插入到程序文本中
g++ -E hello.cpp -o hello.i
- 编译-Compiling
编译器将 hello.i 文件翻译成文本文件hello.s,这个是汇编语言程序。高级语言是源程序。所以注意概念之间的区别。汇编语言程序是每条语句都以标准的文本格式确切描述一条低级机器语言指令。不同的高级语言翻译的汇编语言相同。
g++ -S hello.i -o hello.s
- 汇编-Assembing
汇编器将 hello.s 翻译成机器语言指令。把这些指令打包成可重定位目标程序,即 .o文件。hello.o是一个二进制文件,它的字节码是机器语言指令,不再是字符。前面两个阶段都还有字符。
g++ -c hello.s -o hello.o
- 链接-Linking
比如 hello 程序调用 printf 程序,它是每个 C 编译器都会提供的标准库 C 的函数。这个函数存在于一个名叫 printf.o 的单独编译好的目标文件中,这个文件将以某种方式合并到 hello.o 中。链接器就负责这种合并。得到的是可执行目标文件。
g++ hello.o -o hello
生成库文件并编译
生成静态库
Linux中以 .a 结尾,Windows中以 .lib 结尾
// 汇编,生成Swap.o文件
g++ -c Swap.cpp
// 生成静态库 libSwap.a
ar rs libSwap.a Swap.o
// 链接,生成可执行文件main
g++ main.cpp -lSwap -o main // -l会省略前缀和后缀
生成动态库
Linux中以 .so 结尾,Windows中以 .dll 结尾
// 生成动态库libSwap.so
g++ -c Swap.cpp
g++ -shared -o libSwap.so Swap.o
g++ main.cpp -lSwap -o main
CMake
Cmake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)
基本语法格式
- 参数使用括号括起,参数之间使用空格或分号分开。
- 指令是大小写无关,参数和变量是大小写相关的。
- 变量使用${}方式取值,但是在IF语句中是直接使用变量名。
重要指令
// 指定CMake的最小版本要求:
cmake_minimum_required(VERSION 2.8.3)
// 定义工程名称,并指定工程支持的语言
project(helloworld)
// 显式地定义变量
set(SRC sayhello.cpp hello.cpp) // 定义SRC变量,值为sayhello.cpp和hello.cpp
// 向工程添加多个特定的头文件搜索路径(相当于g++编译器的-I参数)
include_directories(usr/include/my ./include) //将usr/include/my和./include添加到头文件搜索路径
// 向工程添加多个特定的库文件搜索路径(相当于g++编译器的-L参数)
link_directories(usr/lib/my ./lib) //将usr/lib/my和./lib添加到库文件搜索路径
// 生成库文件
add_library(hello SHARED ${SRC}) //通过变量SRC生成libhello.so动态库
add_library(hello STATIC ${SRC}) //生成静态库
// 添加编译参数
add_compile_options(-Wall -std=c++11 -o2)
// 生成可执行文件
add_executable(main main.cpp)
// 为targe添加需要链接的共享库(相当于g++的-l参数)
target_link_libraries(main hello)
// 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
add_subdirectory(src) //添加子目录src
// 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
aux_source_directory(. SRC) // 定义SRC变量,其值为当前目录下所有的源代码文件
常用变量
CMAKE_C_FLAGS // gcc编译选项
CMAKE_CXX_FLAGS // g++编译选项
// 在CMAKE_CXX_FLAGS编译选项后追加-std=c++11
set(CMAKE_CXX_FLAGS "{CMAKE_CXX_FLAGS}" -std=c++11")
CMake目录结构
项目主目录存在一个CMakeList.txt
- 如果包含文件夹的子文件夹中有CMakeList.txt文件,主目录的CMakeList.txt通过add_subdirectory添加。
- 如果包含文件夹的子文件夹中没有CMakeList.txt文件,子目录编译规则体现在主目录的CMakeList.txt中。
流程
- 手动编写CMakeList.txt。
- 执行命令cmake PATH生成Makefile(PATH是顶层CMakeList.txt所在的目录)。
- 执行命令make进行编译。
外部构建:
//创建一个build文件
cd build
cmake ..
make