Cmake使用方法
Cmake使用方法
一、基础编译
- 项目与文件结构
项目结构main.c1
2
3
4
5
6.
├── build
├── CMakeList.txt
├── main.c
├── testFunc.c
└── testFunc.htestFunc.c1
2
3
4
5
6
7
8
int main(void)
{
func(100);
return 0;
}testFunc.h1
2
3
4
5
6
7
8
void func(int data)
{
printf("data is %d\n", data);
}CMakeLists.txt1
2
3
4
5
6
7
void func(int data);1
2
3
4
5
6# CMake最低版本号要求
cmake_minimum_required (VERSION 2.8)
# 项目信息
project (demo)
# 指定生成目标
add_executable(main main.c testFunc.c) - 编译与运行
1
2
3cd build && cmake ../
make -j8
./main - 思考与改进
如果在同一目录下有多个源文件,需要在add_executable里把所有源文件都添加进去,这太不优雅了。因此使用
aux_source_directory(dir var)
把指定目录下所有的源文件存储在一个变量中,第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量名。当程序文件比较多时,我们会进行分类管理,把代码根据功能放在不同的目录下,这样方便查找。这个时候头文件定位需要用以下命令来实现,不够优雅。
1
2#include "xxxxxx/testFunc.h"
#include "xxxxxx/testFunc1.h"因此使用
include_directories
方法添加多个指定头文件的搜索路径,路径之间用空格分隔。源代码随意放置,不够优雅,统一放入src文件夹后要用
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
设置源代码目录。其中**source_dir
指定一个包含CMakeLists.txt和代码文件所在的目录;binary_dir
二进制代码目录执行后的输出文件将会存放在此处;EXCLUDE_FROM_ALL
标记,表示新增加的子目录将会排除在ALL目录之外。**
二、进阶编译
项目与文件结构
项目结构1
2
3
4
5
6
7
8
9
10
11
12
13.
├── bin
├── build
├── CMakeList.txt
├── include1
| └── testFunc1.h
├── include2
| └── testFunc2.h
└── src
├── main.c
├── testFunc1.c
└── testFunc2.cmain.c
1
2
3
4
5
6
7
8
int main(void)
{
func(100);
return 0;
}testFunc.c
1
2
3
4
5
6
7
8
void func(int data)
{
printf("data is %d\n", data);
}testFunc.h
1
2
3
4
5
6
7
void func(int data);CMakeLists.txt
1
2
3
4cmake_minimum_required (VERSION 2.8)
project (demo)
# 设置源代码目录
add_subdirectory (src)这里指定src目录下存放了源文件,当执行cmake时,就会进入src目录下去找src目录下的CMakeLists.txt,所以在src目录下也建立一个CMakeLists.txt,内容如下:
src/CMakeLists.txt1
2
3
4
5
6
7
8# 将当前src/CMakeLists.txt同文件夹下所有文件添加进SRC_LIST变量
aux_source_directory (. SRC_LIST)
# 添加头文件目录
include_directories (../include1 ../include2)
# 制定生成目标
add_executable (main ${SRC_LIST})
# 设定目标二进制可执行文件的存放位置,其中PROJECT_SOURCE_DIR为工程根目录
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)编译与运行
- 编译 这样Makefile会在build目录下生成,二进制程序会在bin目录下生成,然后运行可执行程序:
1
2
3cd build
cmake ..
make -j81
2cd ../bin
./main
- 编译
思考与改进
只使用一个CMakeList.txt,把最外层的CMakeLists.txt内容改成如下
CMakeLists.txt1
2
3
4
5
6cmake_minimum_required (VERSION 2.8)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include1 include2)
add_executable (main ${SRC_LIST})此时还需要把src目录下的CMakeList.txt删除即可
三、生成库文件
项目结构
1
2
3
4
5
6
7
8
9
10
11
12├── bin
├── build
├── CMakeList.txt
├── include1
| └── testFunc1.h
├── include2
| └── testFunc2.h
├── lib
└── src
├── main.c
├── testFunc1.c
└── testFunc2.cCMakeList.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20cmake_minimum_required (VERSION 3.5)
project (demo)
set (SRC_LIST1 ${PROJECT_SOURCE_DIR}/src/testFunc1.c)
set (SRC_LIST2 ${PROJECT_SOURCE_DIR}/src/testFunc2.c)
include_directories (../include1 ../include2)
# add_library:生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
add_library (testFunc_shared1 SHARED ${SRC_LIST1})
add_library (testFunc_shared2 SHARED ${SRC_LIST2})
add_library (testFunc_static1 STATIC ${SRC_LIST1})
add_library (testFunc_static2 STATIC ${SRC_LIST2})
# set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等
set_target_properties (testFunc_shared1 PROPERTIES OUTPUT_NAME "testFunc1")
set_target_properties (testFunc_shared2 PROPERTIES OUTPUT_NAME "testFunc2")
set_target_properties (testFunc_static1 PROPERTIES OUTPUT_NAME "testFunc1")
set_target_properties (testFunc_static2 PROPERTIES OUTPUT_NAME "testFunc2")
# LIBRARY_OUTPUT_PATH: 库文件的默认输出路径,这里设置为工程目录下的lib目录
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)运行查看编译好的库文件
1
2
3
4
5cd build/
cmake ..
make
cd ../lib/
ls最后将会在lib文件夹下生成
libtestFunc.a
和libtestFunc.so
。
四、链接库文件
项目结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16├── bin
├── build
├── CMakeList.txt
├── include1
| └── testFunc1.h
├── include2
| └── testFunc2.h
├── lib
| ├── libtestFunc1.a
| ├── libtestFunc1.so
| ├── libtestFunc2.a
| └── libtestFunc2.so
└── src
├── main.c
├── testFunc1.c
└── testFunc2.cmain.c
1
2
3
4
5
6
7#include <stdio.h>
#include "testFunc.h"
int main(void)
{
func(100);
return 0;
}CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12cmake_minimum_required (VERSION 3.5)
project (demo)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.c)
include_directories (${PROJECT_SOURCE_DIR}/testFunc/inc)
# find_library: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)
add_executable (main ${SRC_LIST})
# target_link_libraries: 把目标文件与库文件进行链接
target_link_libraries (main ${TESTFUNC_LIB})编译与运行
1
2
3
4
5cd build/
cmake ..
make
cd ../bin/
./main