Cmake
简易工程学习
cmake 是一个跨平台的自动构建工具 ,用来生成Makefile,不用动手编写Makefile。
对于一个初始的C语言程序来说使用cmke进行构建。
1 2 3 4 5
| #include <stdio.h> int main(void) { printf("hello world"); }
|
创建CMakeLists.txt文件,CMakeLists.txt文件会被cmake工具解析 ,写入内容
1 2
| project(HELLO) add_executable(hello ./main.c)
|
执行cmake命令
之后就会生成makefile文件,可以使用make进行编译。
使用out-of-source方式进行构建,来将工程生成的文件何源文件分离开。
然后在工程目录下创建一个 build 目录
1 2 3
| cd build/ cmake ../ make
|
这样 cmake 生成的中间文件以及 make 编译生成的可执行文件就全部在 build 目录下了,如果要清理工程,直接删除 build 目录即可,这样就方便多了。
当对应的源文件是多个文件时候,例如main.c hello.c
1
| add_executable(hello main.c hello.c)
|
编译动态库/静态库
动态库:以.so作为后缀
静态库:通常以.a或.la作为后缀。
1 2 3
| add_library(libhello SHARED hello.c) add_library(libhello STATIC hello.c) target_link_libraries(hello libhello)
|
这时生成的库名字是liblibhello.a,可以通过set_target_properties 来修改工程的名字。
1
| set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")
|
通过 set_target_properties 命令对 libhello 目标的OUTPUT_NAME 属性进行了设置,将其设置为 hello
大工程分层存储文件夹
使用add_subdirectory来添加子目录并构建子目录。
当前目录为
1 2 3 4 5 6 7 8 9
| ├── build #build 目录 ├── CMakeLists.txt ├── libhello │ ├── CMakeLists.txt │ ├── hello.c │ └── hello.h └── src ├── CMakeLists.txt └── main.c
|
顶层 CMakeLists.txt
1 2 3
| project(HELLO) add_subdirectory(libhello) add_subdirectory(src)
|
src 目录下的 CMakeLists.txt
1 2 3 4
| include_directories(${PROJECT_SOURCE_DIR}/libhello) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) add_executable(hello main.c) target_link_libraries(hello libhello)
|
libhello 目录下的 CMakeLists.txt
1 2 3
| set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) add_library(libhello hello.c) set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")
|
最终得到:
1 2 3 4 5 6 7 8 9 10 11 12 13
| ├── build │ ├── bin │ │ └── hello │ └── lib │ └── libhello.a ├── CMakeLists.txt ├── libhello │ ├── CMakeLists.txt │ ├── hello.c │ └── hello.h └─ src ├── CMakeLists.txt └── main.c
|
基础指令
全部命令查看官方文档https://cmake.org/cmake/help/v3.5/manual/cmake-commands.7.html
参数间隔用空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| add_executable(<name> source1 source2...)
add_library(<name> [STATIC | SHARED | MODULE] source1 source2 ...])
add_subdirectory(source_dir [binary_dir])
aux_source_directory(<dir> <variable>)
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])
include_directories(AFTER include)
include_directories(BEFORE include) link_directories(directory1 directory2 ...)
link_libraries([item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
link_libraries(hello)
link_libraries(libhello.so) message([<mode>] "message to display" ...)
|
| mode |
说明 |
| none(无) |
重要信息、普通信息 |
| STATUS |
附带信息 |
| WARNING |
CMake警告,继续处理 |
| AUTHOR_WARNINIG |
CMake警告(开发),继续处理 |
| SEND_ERROR |
CMake错误,继续处理,但跳过生成 |
| FALTAL_ERROR |
CMake错误,停止处理和生成 |
| DEPRECATION |
如 果 变 量 CMAKE_ERROR_DEPRECATED 或CMAKE_WARN_DEPRECATED 分别启用, 则 CMake 弃用错 |
| 误或警告,否则没有消息。 |
|
1 2 3 4 5 6 7 8 9
| project(HELLO)
set(<variable> <value>... [PARENT_SCOPE])
target_include_directories(<target> [SYSTEM] [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
|
eg:
写一个指针的斐波那契数列(非递归指针方式实现)
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> #include "function.h" int main(void) { int a = 1, b = 1 ; int *ptr1, *ptr2; ptr1 = &a; ptr2 = &b; feibo_arr( ptr1, ptr2);
return 0; }
|
function.c
1 2 3 4 5 6 7 8 9 10 11 12
| #include <stdio.h> int feibo_arr(int *a, int *b) { int temp ; for( int i = 0; i < 10; i++) { temp = *a + *b; *a = *b; *b = temp; printf("%d\n", *b); } }
|
function.h
1 2 3 4
| #ifndef _TEST_H #define _TEST_H int feibo_arr(int *a, int *b); #endif
|

1 2 3 4 5
| add_executable(feibo main.c) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) include_directories(${PROJECT_SOURCE_DIR}/libfeibo) target_link_libraries(feibo libfeibo)
|
1 2 3 4
| add_library(libfeibo function.c) set_target_properties(libfeibo PROPERTIES OUTPUT_NAME "feibo") set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
1 2 3 4 5
| cmake_minimum_required(VERSION 3.5) project(feibo) add_subdirectory(src) add_subdirectory(libfeibo)
|