make
- 预处理(宏替换,删除注释和多余的空白字符,条件编译,文件包含),hello.c到hello.i
- 编译(gcc检查代码规范性,是否有语法错误,生成汇编),hello.i到hello.s
- 汇编(生成极其可识别代码),hello.s到hello.o
- 链接(生成可执行文件或库文件)
在成功编译后,就进入了链接的阶段,这里涉及到一个重要的概念:函数库查看上面的小程序会发现里面并没有定义printf函数的实现,并且在预编译阶段包含进去的“stdio.h”里面也只有它的声明,而没有定义函数的实现。那么printf实在哪里实现的呢?
其实系统把对这些函数的实现都做到名字为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的路径“/user/lib”下面进行查找,并且链接到lib.so.6库函数中去,这样就能实现printf函数了,这也就是链接的作用。
函数库分为两种:静态库和动态库。静态库是指在编译链接时将库文件的代码全部加入到可执行文件里,因此生成的文件比较大,但在执行过程中就不会再用到库文件了,后缀名一般为.a;动态库和它相反,在编译链接过程中并没有将库文件加入到可执行文件里面去,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销,后缀名一般为.so。上面提到的libc.so.6就是动态库,所以也就可以得到gcc在编译时默认使用动态库。完成链接过程,gcc就可以生成可执行文件main了。
cmake
CMake:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等。
-
库提供了Config-file包
- 通常存放在lib/cmake/中,包含Config.cmake和ConfigVersion.cmake(可选,用来给CMake确认第三方库的版本是否满足find_package()命令中对版本的要求。)如果config.cmake文件找到了,并且库版本满足需求,CMake find_package()命令认为包找到了。include()
- 如果库没有安装在默认位置。The CMAKE_PREFIX_PATH variable may be set when invoking CMake. It is treated as a list of paths to search for Config-file Packages. A package installed in /opt/somepackage will typically install config files such as /opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake. In that case, /opt/somepackage should be added to CMAKE_PREFIX_PATH.
Often the third-party package documentation will point out the names of imported targets available after a successful find_package for a library. Those imported target names can be used with the target_link_libraries() command.
-
库没有提供config-file包
仍然可以使用find_package()命令,如果FindSomePackage.cmake文件可以找到。- 它们不应由第三方提供,除非可能以文档形式提供
- Find .cmake文件的可用性并不表示二进制文件本身的可用性。
- CMake不会在CMAKE_PREFIX_PATH中搜索Find .cmake文件。 而是CMake在CMAKE_MODULE_PATH变量中搜索此类文件。 用户通常在运行CMake时设置CMAKE_MODULE_PATH,并且将CMake项目附加到CMAKE_MODULE_PATH以允许使用本地模块文件包也很常见。
- CMake为某些第三方程序包提供了Find .cmake文件,以便在第三方不直接提供配置文件程序包的情况下提供方便。 这些文件是CMake的维护负担,因此通常不再将新的Find模块添加到CMake中。 第三方应提供配置文件包,而不是依靠CMake提供的查找模块。
An Introduction to Modern CMake
cmake支持多种编译器,并且可以跨平台,支持多种IDE
在cmake中,如何测试编译器是否为Clang?
CMake指定编译器的命令
SET(CMAKE_C_COMPILER /usr/bin/gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/g++)
一定要写在project指令之前,否则无效。