本文介绍使用cmake来编译动态库和静态库,源码非常简单,重点是掌握文件的组织方式以及cmake的使用。
文章目录
目录结构
.
|-- build
|-- CMakeLists.txt
|-- inc
| `-- add.h
|-- lib # 动态库的输出目录
|-- out # 静态库的输出目录
`-- src
`-- add.c
add.c
#include "add.h"
int add(int a, int b)
{
return (a+b);
}
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
cmake_policy(SET CMP0048 NEW)
project(test04 VERSION "1.0.0.0")
include_directories(./inc)
# 设置静态库的输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out)
# 设置动态库的输出目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
add_library(add_static ${PROJECT_SOURCE_DIR}/src/add.c)
add_library(add SHARED ${PROJECT_SOURCE_DIR}/src/add.c)
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
Where to put all the ARCHIVE target files when built.
CMAKE_ARCHIVE_OUTPUT_DIRECTORY是cmake的变量(variable),通过set()命令来指定’ARCHIVE target files’的输出路径,'ARCHIVE target files’可以理解为静态库文件。
CMAKE_LIBRARY_OUTPUT_DIRECTORY
Where to put all the LIBRARY target files when built.
CMAKE_LIBRARY_OUTPUT_DIRECTORY是cmake的变量(variable),通过set()命令来指定’LIBRARY target files’的输出路径,LIBRARY target files’可以理解为动态库文件。
add_library
Add a library to the project using the specified source files.
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] [source1] [source2 ...])
简单讲,add_library的作用就是生成库文件。如果指定了STATIC
,就是生成静态库;如果指定了SHARED
,就是生成动态库;如果指定了MODULE
,就是使用类dl-open函数加载的动态库;说明SHARED
和MODULE
除了MAC OS外,作用是相同的。我的cmake系列文章都是以linux系统作为运行环境。
需要注意的是 <name>
必须是全局唯一的。例如,上述CMakeLists.txt的第13、14行的add_library的name设置为相同的add
,cmake将会报错。报错信息如下:
CMake Error at CMakeLists.txt:14 (add_library):
add_library cannot create target "add" because another target with the same
name already exists. The existing target is a static library created in
source directory "/xxxx/test04". See
documentation for policy CMP0002 for more details.
-- Configuring incomplete, errors occurred!
编译
cd build
cmake ..
make
编译后的目录结构:
|-- build
| |-- CMakeCache.txt
| |-- CMakeFiles
| |-- cmake_install.cmake
| `-- Makefile
|-- CMakeLists.txt
|-- inc
| `-- add.h
|-- lib
| `-- libadd.so
|-- out
| `-- libadd_static.a
|-- src
| `-- add.c
为了验证生成的库是否可用,我们可以简单验证一下。
main.c
#include <stdio.h>
#include <stdlib.h>
#include "add.h"
int main(int argc, char** argv)
{
int a = 1;
int b = 2;
printf("%d+%d=%d\n", a, b, add(a,b));
return 0;
}
libadd.so
$ gcc main.c -I inc -L ./lib -ladd -o test
$ ./test #如果执行时,报找不到库,export LD_LIBRARY_PATH=your real lib path:$LD_LIBRARY_PATH
1+2=3
libadd_static.a
$ gcc main.c -I inc out/libadd_static.a -o test
$ ./test
1+2=3
这里我直接使用了gcc进行编译。试想一下,如果使用cmake来编译,并依赖外部库,要怎么做呢?