cmake制作并链接动静态库
- 制作静态库
- add_library(库名称 STATIC 源文件1 [源文件2] ...)
- LIBRARY_OUTPUT_PATH指定库的生成路径
- 制作动态库
- add_library(库名称 SHARED 源文件1 [源文件2] ...)
- 连接动静态库
- link_libraries连接静态库
- link_directories到哪个路径去找库
- target_link_libraries连接动态库
- find_library
之前我们已经了解了cmake的一些基本操作,如果还有小伙伴不了解cmake是什么,可以点击这里:
(https://blog.csdn.net/qq_67693066/article/details/136658388)[https://blog.csdn.net/qq_67693066/article/details/136658388]
今天我们要了解的如何利用cmake制作动静态库并链接他们:
制作静态库
首先我们先制作一些头文件:
#pragma once
#include<iostream>
int add(int x,int y);
#pragma once
#include<iostream>
int my_div(int x,int y);
#pragma once
#include<iostream>
int mul(int x,int y);
#pragma once
#include<iostream>
int sub(int x,int y);
然后在对应的cpp文件中实现:
#include"my_add.h"
int add(int x,int y)
{
return x + y;
}
#include"my_div.h"
int my_div(int x,int y)
{
if(y == 0)
{
perror("y is zero");
exit(EXIT_FAILURE);
}
return x / y;
}
#include"my_mul.h"
int mul(int x,int y)
{
return x * y;
}
#include"my_sub.h"
int sub(int x,int y)
{
return x - y;
}
这里注意一下,我们制作动静态库不需要对应的入口函数,只需要对应头文件和相应的实现。
然后我们编写一个基本的CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(Mylibrary)
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件
include_directories(include) # 包括头文件
add_library(库名称 STATIC 源文件1 [源文件2] …)
add_library(库名称 STATIC 源文件1 [源文件2] ...)
是用来制作静态库的命令:
cmake_minimum_required(VERSION 3.0)
project(Mylibrary)
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件
include_directories(include) # 包括头文件
add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取
我们来运行一下:
这个时候,我们的build目录下会多一个libcalc.a的静态库:
LIBRARY_OUTPUT_PATH指定库的生成路径
我们可以用LIBRARY_OUTPUT_PATH指定库的生成路径:
cmake_minimum_required(VERSION 3.0)
project(Mylibrary)
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件
include_directories(include) # 包括头文件
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) # 库生成在根目录下的lib目录下
add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取
我们可以到lib目录下找到我们的库文件:
制作动态库
add_library(库名称 SHARED 源文件1 [源文件2] …)
其实和静态库的方法差不多,只不过把STATIC换成了SHARED:
cmake_minimum_required(VERSION 3.0)
project(Mylibrary)
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件
include_directories(include) # 包括头文件
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) # 库生成在根目录下的lib目录下
add_library(calc SHARED ${MY_SRC}) # 生成动态库
# add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取
连接动静态库
首先我们创建一个新的文件夹,然后进去:
使用对应的库的时候要首先把它对应的头文件包括进来,所以我们把对应的头文件拷贝到这个新的文件夹下:
然后把对应的库拿过来:
然后我们创建自己的src文件,build文件来管理:
还有CMakeLists.txt:
首先我们要在CMakeLists.txt中包括我们的头文件,因为这是我们自己写的第三方库,所以我们要显示的写:
project(MyTest)
include_directories(${PROJECT_SOURCE_DIR}/include) # 包括头文件
link_libraries连接静态库
我们可以用link_libraries连接静态库,这里静态库的名字可以是全名 libxxx.a
也可以是掐头(lib)去尾(.a)之后的名字 xxx:
link_libraries(<static lib> [<static lib>...])
project(MyTest)
include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件
# 连接静态库
link_libraries(calc)
但是这个是我们自己写的第三方库,可能出现找不到的情况,所以我们要告诉cmake到哪里去找:
link_directories到哪个路径去找库
我这里的库是放在lib下的,所以可以这样写:
project(MyTest)
include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件
# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)
# 到这个路径下找库
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 连接静态库
link_libraries(calc)
# 生成可执行文件
add_executable(mytest ${MY_SRC})
然后在main函数里编写:
#include"my_add.h"
int main()
{
std::cout << add(2,3) << std::endl;
return 0;
}
我们可以测试一下:
target_link_libraries连接动态库
动态库的链接和静态库是完全不同的:
target_link_libraries(
<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存
因此,在cmake中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后,同时,这是我们自己写的第三方库,所以也要告诉cmake到哪里去找库:
project(MyTest)
include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件
# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)
# 到这个路径下找库
link_directories(${PROJECT_SOURCE_DIR}/lib)
# 连接静态库
#link_libraries(calc)
# 生成可执行文件
add_executable(mytest ${MY_SRC})
# 链接动态库
target_link_libraries(mytest calc) # 将calc链接到mytest中
find_library
寻找库文件,不仅可以用link_directories还可用find_library:
find_library() 是 CMake 中的一个内置命令,用于在系统中查找指定库文件的路径。这个命令主要用于那些不提供标准 CMake 配置文件(如 calcConfig.cmake 或 calc-config.cmake)的库,或者在需要更精细控制库查找过程的场景中。以下是 find_library() 命令的基本用法、参数和示例:
find_library(<variable>
NAMES <name1> [<name2> ...]
HINTS <hint1> [<hint2> ...]
PATHS <path1> [<path2> ...]
...])
<variable>
: 存储找到的库文件路径的变量名。如果找到库,该变量将被设置为库文件的全路径;否则,变量将保留未定义状态或被设置为空字符串。NAMES
: 指定要查找的库文件名。通常包括库的基础名称(如calc
)和可能的后缀(如.a
、.so
、.dll
等)。可以指定多个备选名称。HINTS
、PATHS
: 提供查找库文件的额外路径提示或直接路径。HINTS
的优先级高于PATHS
。这些路径将被添加到 CMake 的默认查找路径中。
project(MyTest)
include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件
# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)
# 到这个路径下找库
# link_directories(${PROJECT_SOURCE_DIR}/lib)
find_library(CALC_LIBRARY NAMES calc PATHS "${PROJECT_SOURCE_DIR}/lib")
# 连接静态库
#link_libraries(calc)
# 生成可执行文件
add_executable(mytest ${MY_SRC})
# 链接动态库
target_link_libraries(mytest ${CALC_LIBRARY})