cmake-动态库和静态库的编译

本文介绍使用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函数加载的动态库;说明SHAREDMODULE除了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来编译,并依赖外部库,要怎么做呢?

要使用 CMake 编译动态库静态库,你可以按照以下步骤进行操作: 1. 创建一个 CMakeLists.txt 文件,该文件描述了构建过程和项目配置。 2. 在 CMakeLists.txt 文件中,使用 `add_library` 命令来定义要构建的库。使用 `SHARED` 参数来指定动态库,使用 `STATIC` 参数来指定静态库。例如: ```cmake # 构建动态库 add_library(mylib SHARED src/mylib.cpp) # 构建静态库 add_library(mylib_static STATIC src/mylib.cpp) ``` 3. 如果你有多个源文件,可以将它们一起添加到库中: ```cmake # 构建动态库 add_library(mylib SHARED src/mylib.cpp src/other.cpp) # 构建静态库 add_library(mylib_static STATIC src/mylib.cpp src/other.cpp) ``` 4. 如果你想为库定义公共头文件目录,可以使用 `target_include_directories` 命令。例如: ```cmake target_include_directories(mylib PUBLIC include) ``` 5. 如果你希望链接其他库到你的库中,可以使用 `target_link_libraries` 命令。例如: ```cmake target_link_libraries(mylib PUBLIC otherlib) ``` 6. 最后,在 CMakeLists.txt 文件中添加一个 `install` 命令,以便在构建过程完成后安装库文件到指定的目录。例如: ```cmake install(TARGETS mylib DESTINATION lib) install(FILES include/mylib.h DESTINATION include) ``` 7. 运行 CMake 命令来生成构建系统所需的文件: ```shell cmake . ``` 8. 使用生成的构建系统来编译和构建库: ```shell make ``` 在构建过程完成后,你将在指定的目录(例如 `lib`)中找到生成的动态库静态库文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sif_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值