0. 序
最近在B站上学图形学,做作业时不太想用已经搭好的虚拟机,因此我这里需要自己在Ubuntu上搭opencv和vscode的环境。折腾了好久大概把opencv和vscode装好了,还需要自己修改一下作业代码框架中的CMakelist文件。只好再了解一下cmake的基础,毕竟最近装软件的时候也经常用到。
本来是打算看官网的教程的,看了tutorial的第一页,感觉这玩意不太像是入门的,据知乎网友推荐clone了这个教程:https://github.com/ttroy50/cmake-examples,因此算是做一个学习的小笔记吧,以备查阅(虽然是笔记1,也说不定只有这一篇了,哈哈)。
1. 01-basic-A
cmake_minimum_required(VERSION 3.5)
project (hello_cmake)
add_executable(hello_cmake main.cpp)
就是脚本语言的风格嘛,第一个函数用于指定cmake的最低依赖版本,第二个函数用于创建一个名为hello_came的项目,目前并没有看出实际的作用(目前省略掉也没关系)。第三个函数指定一个可执行文件hello_cmake, 依赖于源文件main.cpp。
2. 01-basic-B
cmake_minimum_required(VERSION 3.5)
project (hello_headers)
set(SOURCES
src/Hello.cpp
src/main.cpp
)
add_executable(hello_headers ${SOURCES})
target_include_directories(hello_headers
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
B演示了编译目标文件时如何指定依赖的头文件。set命令用于设置变量,第一个参数是变量名词,后面的参数为变量内容,传入多个参数时得到的变量是用分号隔开的(可以用message函数进行输出,据说用分号隔开其实是一个列表?) target_include_directories函数指定了生成目标文件时的头文件搜索路径,private限制该函数的作用范围,更具体地放在basic-C中进行阐述。PROJECT_SOURCE_DIR是内置的变量,教程的解释是这样
The source directory of the current cmake project.
目前理解为就是目前正在执行的CMakelist的路径吧。 这里不一样的是用的是绝对路径(之前加入源码时用的相对路径), 试了一下, 用相对路径好像也没问题。
3. 01-basic-C
cmake_minimum_required(VERSION 3.5)
project(hello_library)
#Generate the static library from the library sources
add_library(hello_library STATIC
src/Hello.cpp
)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello_library
)
和之前相比,这次多了创建和链接静态库的操作, 这个add_library函数干的事情一看就明白嘛。这里详细说下三种作用域。
- PRIVATE: 只在生成目标文件时加入该链接, 比如B中的目标文件hello_headers, 它依赖于main.cpp和Hello.cpp, 那么在生成main.o和Hello.o时会在编译选项中加入 -I和指定的头文件目录。
- INTERFACE: 当目标文件为link参数时, 在编译目标文件的依赖项时, 加入 -I 选项和指定的头文件, 这个就适用于动态库和静态库的头文件了。
- PUBLIC: 感觉就是上面两个的叠加。
通过target_link_libraries()函数, 指定了这个静态库作为链接时的参数, 那么在编译 hello_binary的依赖项main.cpp的时候, 便会加入 -I ${PROJECT_SOURCE_DIR}/include 的静态库头文件的链接参数了。
当然上面对这个三个作用域的解读是针对头文件来说的, 注意到在指定静态库作为链接参数时也指定了该链接参数的作用域, 对于这种情况, 上面的描述还适用吗?
参考了这一篇博客https://blog.csdn.net/qq_35866736/article/details/107780833 实际上在工程中, 可能这个hello_binary也是一个静态库, 就是说hello_binary这个静态库依赖于静态库hello_library, 如果这里指定链接参数为PUBLIC, 那么比如一个hello文件链接了hello_binary库, 那么还是根据上面的定义, 这时候hello文件的链接参数中也会增加链接 hello_library。(呃, 如果我没理解错的话,…这里已经觉得cmake麻烦起来了)
4. 01-basic-D
cmake_minimum_required(VERSION 3.5)
project(hello_library)
add_library(hello_library SHARED
src/Hello.cpp
)
add_library(hello::library ALIAS hello_library)
target_include_directories(hello_library
PUBLIC
${PROJECT_SOURCE_DIR}/include
)
add_executable(hello_binary
src/main.cpp
)
target_link_libraries( hello_binary
PRIVATE
hello::library
)
和静态库的情况没什么区别, 多了一个别名的使用。
|