文章目录
- 1、语法
- 2、实践
- 2.1 编写代码
- 2.2 编译
- 3、总结
有时我们只需要编译出动态库,静态库,然后等着让其它程序去使用。这种情况下我们需要使用add_library函数。
1、语法
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2] [...])
<name>
- 表示库文件的名字,该库文件会根据命令里列出的源文件来创建。
- < name>对应于逻辑目标名称,并且在项目中必须是全局唯一的。
- 构建的库的实际文件名是基于本机平台的约定(如lib< name>.a或< name>.lib)构建的。
[STATIC | SHARED | MODULE]
指定要创建的库的类型
- SHARED:
- 动态库。动态库是动态链接并在运行时加载的
- 如果库不导出任何符号,则不能将其声明为SHARED库
- STATIC:静态库。静态库是在链接其他目标时使用的目标文件存档
- MODULE:
- 模块库是没有链接到其他目标的插件,但可以在运行时使用类似dlopen的功能动态加载
- 在使用 dl 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。
EXCLUDE_FROM_ALL
:这个库不会被默认构建(排除到默认目标all之外),除非有其他的组件依赖或者手工构建。
[source1] [source2] [...]
:指定生成库的源文件
当我们使用CMake构建项目时,可以通过设置BUILD_SHARED_LIBS变量来决定是否构建共享库(SHARED)或静态库(STATIC)。如果BUILD_SHARED_LIBS变量的值为ON,则构建的库类型为SHARED;如果为OFF,则构建的库类型为STATIC。
另外,在构建SHARED和MODULE库时,CMake会自动设置POSITION_INDEPENDENT_CODE目标属性为ON。这个属性表示生成的库是否包含了位置无关代码(Position Independent Code),这对于共享库和动态链接库是必要的。位置无关代码的特点是可以在内存中的任意位置加载和执行,这使得共享库能够在不同的进程地址空间中重用。
2、实践
2.1 编写代码
项目结构如下:
/*
** testFunc.c
*/
#include <stdio.h>
#include "testFunc.h"
void func(int data)
{
printf("data is %d\n", data);
}
/*
** testFunc.h
*/
#ifndef _TEST_FUNC_H_
#define _TEST_FUNC_H_
void func(int data);
#endif
最外层的CMakeLists.txt内容如下:
cmake_minimum_required (VERSION 2.8)
project (demo)
#向当前工程添加存放源文件的子目录
add_subdirectory (lib_testFunc)
lib_testFunc目录下的CMakeLists.txt如下:
aux_source_directory (. SRC_LIST)
# 使用${SRC_LIST}为原材料生成一个叫做testFunc_shared 的动态库
add_library (testFunc_shared SHARED ${SRC_LIST})
# 使用${SRC_LIST}为原材料生成一个叫做testFunc_static 的静态库
add_library (testFunc_static STATIC ${SRC_LIST})
# 将testFunc_shared 重新命名为 libtestFunc.so
set_target_properties (testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
# 将testFunc_static 重新命名为 libtestFunc.a
set_target_properties (testFunc_static PROPERTIES OUTPUT_NAME "testFunc")
# 设置 库文件的默认输出路径
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
命令:
-
add_library
: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件) -
set_target_properties
: 设置输出的名称,还有其它功能,如设置库的版本号等等。
预定义变量:
-
LIBRARY_OUTPUT_PATH
: 库文件的默认输出路径,这里设置为工程目录下的lib目录
2.2 编译
现在,让我们进入build目录下运行cmake …,成功后再运行make:
cd到lib目录下进行查看,发现已经成功生成了动态库和静态库,
ps:可以看出前面使用set_target_properties重新定义了库的输出名字,如果不用set_target_properties也可以,那么库的名字就是add_library里定义的名字,只是我们连续2次使用add_library指定库名字时,这个名字不能相同,而set_target_properties可以把名字设置为相同,只是最终生成的库文件后缀不同,这样相对来说会好看点。
3、总结
命令总结:
命令 | 说明 | 示例 |
| 生成动态库或静态库 |
|
set_target_properties | 设置目标属性 |
|
预定义变量总结:
预定义变量 | 说明 |
| 库文件的默认输出路径 |
库路径不设置的话,默认放在BINARY_DIR下,即构建时执行cmake命令的目录下。