- 这里我引入的依赖库是ncurses, 用的是ncurses的HelloWorld例子. (具体的编译ncurses过程这里不再赘述)
- 先把目录结构罗列下.
- 深层次的我就不继续展开了, 都是编译生成的头文件和库文件.
- 接下来先看下我们的HelloWorld.c
-
1 /* 2 * Filename : HelloWorld.c 3 * Description : a CMake ncurses demo 4 * Author : loop0day 5 * Created : 2018 Apr 04 08:42:58 PM 6 * Modified : 2018 Apr 04 08:42:58 PM 7 */ 8 9 #include <ncurses/ncurses.h> 10 11 /* main */ 12 int main(); 13 14 int 15 main() 16 { 17 /* start cursor mode */ 18 initscr(); 19 /* print */ 20 printw("Hello World!"); 21 /* flush buffer */ 22 refresh(); 23 /* wait user input */ 24 getch(); 25 /* end cursor mode */ 26 endwin(); 27 28 return 0; 29 }
- 基本上没什么好说的, 注意一下我们包含头文件的时候使用的是尖括号.
- 接下来看CMakeLists.txt
-
1 # set cmake minimum required version cmake to build this project 2 cmake_minimum_required(VERSION 3.9) 3 4 # set project name 5 project(HelloWorld) 6 7 # add MACRO for ncurse 8 add_definitions(-D_GNU_SOURCE -D_DEFAULT_SOURCE) 9 10 # search ncurse headers 11 find_path(NCURSES_PATH ncurses/ncurses.h) 12 13 # search ncurses library 14 find_library(NCURSES_LIB ncurses HINTS ncurses) 15 16 # define a executable target 17 add_executable(HelloWorld HelloWorld.c) 18 19 # include with ncurses 20 target_include_directories(HelloWorld PRIVATE ${NCURSES_PATH}) 21 22 # link with ncurses 23 target_link_libraries(HelloWorld ${NCURSES_LIB}
- 第一个命令依旧指定构建这个项目所需要的最小CMake版本.
- 第二个命令指定项目的名称.
- 第三个命令是指定相关的预编译宏, 这些宏用于配置ncurses库.
- 第四个命令 find_path 用于在指定目录查找目标头文件, 然后扩展成绝对路径赋值给第一个变量参数, 这个指定目录可以用 cmake -DCMAKE_PREFIX_PATH=<path> 进行覆盖, 如果没有找到就到默认的地方查找, 这里由于我将ncurses的头文件存放在了include目录下的ncurses目录中, 但是指定的CMAKE_PREFIX_PATH却是项目的最顶层, 所以需要在查找的时候添加一个子目录, 这样查找就会被扩展成${CMAKE_PREFIX_PATH}/include/ncurses/ncurses.h.
- find_library 类似, 用于查找所需要的库.
- 然后我通过HINTS指定子目录(不知道为什么不能直接在name上指定子目录, cmake不通过, 网上也没有查找到原因, 还望知道的朋友告知下, 谢谢了).
- 然后 add_executable 指定一个可执行的目标, 这样这个目标才能对下面的链接操作可见.
- target_include_directories 用于给目标添加头文件目录,不过这里多了一个必须指定的限定符, 限定符的种类有
INTERFACE
, PRIVATE, PUBLIC. 具体区别如下(摘自https://stackoverflow.com/questions/26037954/cmake-target-link-libraries-interface-dependencies). -
If you are creating a shared library and your source cpp files #include the headers of another library (Say, QtNetwork for example), but your header files don‘t include QtNetwork headers, then QtNetwork is a
PRIVATE
dependency.If your source files and your headers include the headers of another library, then it is a
PUBLIC
dependency.If your header files but not your source files include the headers of another library, then it is an
INTERFACE
dependency. - target_link_libraries 指定链接的库, 默认是链接动态库, 不过可以强制指定静态库.
- 老方法, 进入build目录进行构建.
- 注意的是, 构建的时候使用 cmake -DCMAKE_PREFIX_PATH=. .. , CMAKE_PREFIX_PATH的当前目录是相对于cmake的工作目录的, 这里的工作目录是父目录, 所以CMAKE_PREFIX_PATH的当前目录就是上一级目录.
- 最后执行.