1、新建项目
新建项目t4,目录结构如下:
该程序引入了自建的hello.h程序库包含了函数func();main.c的内容如下所示:
//main.c
#include <hello.h>
int main()
{
func();
return 0 ;
}
2、导入第三方头文件
hello.h 位于/root/cpp_test/backup/cmake_test/t4/include/hello目录中,并没有位于系统标准的头文件路径,为了让我们的工程能够找到 hello.h 头文件,我们需要引入一个新的指令 INCLUDE_DIRECTORIES,其完整语法为:
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径中包含了空格,可以使用双引号将它括起来,默认的行为是追加到当前的头文件搜索路径的后面,你可以通过两种方式来进行控制搜索路径添加的方式:
现在我们在 src/CMakeLists.txt 中添加一个头文件搜索路径,方式很简单,加入:
INCLUDE_DIRECTORIES(/root/cpp_test/backup/cmake_test/t4/include/hello)
进入 build 目录,重新进行构建,这是找不到 hello.h 的错误已经消失,但是出现了一个新的错误:
main.c:(.text+0x12): undefined reference to `func' 因为我们并没有 link 到共享库 libhello 上。
3、为 target 添加共享库
我们现在需要完成的任务是将目标文件链接到 libhello,这里我们需要引入两个新的指令 LINK_DIRECTORIES 和 TARGET_LINK_LIBRARIES
LINK_DIRECTORIES 的全部语法是:
LINK_DIRECTORIES(directory1 directory2 ...)
这个指令非常简单,添加非标准的共享库搜索路径,比如,在工程内部同时存在共享库和可 执行二进制,在编译时就需要指定一下这些共享库的路径。这个例子中我们没有用到这个指令而是使用TARGET_LINK_LIBRARIES 。 TARGET_LINK_LIBRARIES 的全部语法是:
TARGET_LINK_LIBRARIES(target library1 <debug | optimized> library2 ...)
这个指令可以用来为 target 添加需要链接的共享库,本例中是一个可执行文件,但是同样可以用于为自己编写的共享库添加共享库链接,libhello.so.1.2共享库的路径为/root/cpp_test/backup/cmake_test/t4/thirdPath/libhello.so.1.2。 为了解决我们前面遇到的 func 未定义错误,我们需要作的是向
src/CMakeLists.txt 中添加如下指令:
TARGET_LINK_LIBRARIES(main /root/cpp_test/backup/cmake_test/t4/thirdPath/libhello.so.1.2)
接下来进行编译:
mkdir build
cd build
cmake ..
make
这是我们就得到了一个连接到 libhello 的可执行程序 main,位于 build/bin目录,运 行 main 的结果是输出:
bin/main
#输出 hello world!
4、查看执行文链接库的情况
让我们来检查一下 main 的链接情况,输入命令:
ldd bin/main
得到的输出如下:
可以清楚的看到 main 确实链接了共享库 libhello,而且链接的是动态库 libhello.so.1
5、变更为链接到静态库
将 TARGET_LINK_LIBRRARIES 指令修改为:
TARGET_LINK_LIBRARIES(main /root/cpp_test/backup/cmake_test/t4/thirdPath/libhello.a)
重新构建后再来看一下 main 的链接情况 ldd src/main
说明,main 确实链接到了静态库 libhello.a
6、总结
通过(1-6)节的学习,我们几乎掌握了如下CMakeLists.txt指令的基本操作:
#命名项目
PROJECT (HELLO)
#添加生成可执行二进制文件
ADD_EXECUTABLE(hello main.c)
#在主CMakeLists.txt添加子执行文件
ADD_SUBDIRECTORY(src bin)
SET(LIBHELLO_SRC hello.c)
#添加共享库
ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
#添加静态库
ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})
#重命名静态库
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
#清除功能开启
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
#设置版本号
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
#安装文件及可执行文件
INSTALL(TARGETS hello hello_static
LIBRARY DESTINATION thirdPath
ARCHIVE DESTINATION thirdPath)
INSTALL(FILES hello.h DESTINATION include/hello)
#导入第三方库头文件
INCLUDE_DIRECTORIES(/root/cpp_test/backup/cmake_test/t4/include/hello)
#导入第三方静态库
TARGET_LINK_LIBRARIES(main /root/cpp_test/backup/cmake_test/t4/thirdPath/libhello.a)
#导入第三方动态库
TARGET_LINK_LIBRARIES(main /root/cpp_test/backup/cmake_test/t4/thirdPath/libhello.so.1.2)
到此为止,基本可以使用 cmake 工作了,但是还有很多高级的语法有待探讨。