学习使用cmake 生成及使用库,使用cmake 生成 .lib 静态库 及动态库(.dll)。及linux 下使用的静态库 .a 和 动态库(.so, 也称为共享库)
目录
使用工具
生成库(导入库)
add_library()
生成静态库(Windows)
使用 vs 2019 生成静态库
使用Clion 生成静态库(windows .lib)
使用静态库(Windows)
方式一:使用 link_libraries()
使用 target_link_libraries()
使用全路径
使用 link_directories + target_link_libraries
引入头文件(include_directories)不与不引入头文件
error LNK2019:
静态库(.a) 的使用
仅不同是使用 link_directories + target_link_libraries
动态链接库
使用mingw与cmake 生成 .dll
生成共享库
共享库的使用
aux_source_directory 的使用
aux_source_directory 引用文件
aux_source_directory 生成库
使用工具
开发工具:clion、cmake
平台: win
生成库(导入库)
add_library 除了生成导入库,还可生成对象库,接口库等
使用 cmake CMakeList.txt
项目结构:
![](https://img-blog.csdnimg.cn/5dda05aa1a274c1d85c7b7a5e5221369.png)
声明库函数 .h
#pragma once
double mySqrt(double x);
定义库函数 .cpp
#include "myMathSquare.h"
double mySqrt(double x)
{
return (x * x);
}
CMakeLists.txt
# CMakeList.txt: MyLibraryTest 的 CMake 项目,在此处包括源代码并定义
# 项目特定的逻辑。
#
#注意:cmake的语法支持大小、小写和大小写混合上边的代码中我们使用的cmake语法是小写的.
cmake_minimum_required (VERSION 3.8)
project ("MyLibraryTest")
# 设置系统自带变量
set(cmake_cxx_standard 11)
set(myHeadPath "${CMAKE_CURRENT_SOURCE_DIR}/header")
include_directories(${myHeadPath})
add_library(MyMathFunctions STATIC ./source/myMathSquare.cpp)
# TODO: 如有需要,请添加测试并安装目标。
add_library()
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2] [...])
添加名为<name>的库,库的源文件可指定,也可用target_sources()
后续指定
<name>属性必须全局唯一
生成的library名会根据STATIC
或SHARED及 生成平台
成为name.a/name.lib 或 name.so/.dll
windows下,如果dll没有export任何信息,则不能使用SHARED
,要标识为MODULE
MODULE: 在使用 dyId 的系统有效,如果不支持dyid, 则被当做shared对待
EXCLUDE_FROM_ALL: 这个库不会被默认构建,除非有其他的组件或者手工构建
生成静态库(Windows)
使用 vs 2019 生成静态库
开始尝试使用 vs 2019 建立的 cmake 项目生成 静态库。一直未找到生成入口。(生成windows 静态库仅仅只是想尝试使用 cmake生成 .lib 静态库, 更简单的方式是 vs .sln 解决方案中直接设置,或直接新建 生成静态库解决方案)。
偶然终于找到怎么生成 使用 cmake 生成解决方案。然运行解决方案生成 库。
项目右键 打开终端
![](https://img-blog.csdnimg.cn/72ac9fdaf3fa4a4abea9779a764f63d2.png)
使用 cmake 生成解决方案
j命令: cmake .
![](https://img-blog.csdnimg.cn/9765ed45e69a4bff8f14aa5a93a1a286.png)
结果:
![](https://img-blog.csdnimg.cn/34600b6bfb90472ba92f1024fead2ab0.png)
打开解决方案:
![](https://img-blog.csdnimg.cn/2e6bc830b5294fc69de382c19f4f7793.png)
生成:
![](https://img-blog.csdnimg.cn/d8089649a0474c1a82dca987f65900d7.png)
如果用此种方式生成动态库 貌似 只生成dll,不生成调用 dll 所需的静态库
修改:add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)
其他步骤一致
使用Clion 生成静态库(windows .lib)
打开项目文件夹
![](https://img-blog.csdnimg.cn/2ee536715ade438d97a88bda38847743.png)
设置 Clion 中的 visual studio 环境
打开设置:
![](https://img-blog.csdnimg.cn/9a210290284b443d9b6f368eeab84692.png)
新增工具链
![](https://img-blog.csdnimg.cn/f213bd158d814c0a999e228fdeeb9a1d.png)
改为 64 位
![](https://img-blog.csdnimg.cn/80bf35074fed4091a35098c105fef510.png)
新增cmake 环境
![](https://img-blog.csdnimg.cn/e2099370a87e4a5e8b60c27488edc2bd.png)
选择debug 或者 release
![](https://img-blog.csdnimg.cn/529ed096c6c249a8ab5254af34b68dae.png)
查看文件夹下 是否出现 visual studio 相应的文件夹![](https://img-blog.csdnimg.cn/376cbe45ce7443248967dc08da473cc9.png)
如果没有 打开 cmake reset 或 刷新
![](https://img-blog.csdnimg.cn/c29980550cf343168f58d528ee5d662f.png)
选择相应环境 构建
![](https://img-blog.csdnimg.cn/894e0a2f2694438bbb4019417eac7c5e.png)
生成结果![](https://img-blog.csdnimg.cn/f58179dfb1894d839d25079583a1aa08.png)
使用静态库(Windows)
新建一个调用文件 xxx.cpp
#include <iostream>
using namespace std;
extern double mySqrt(double x);
extern void hello();
void customLibTest() {
double x = 8;
double res = mySqrt(x);
cout << "输入x: " << x << "的平方是" << res << endl;
}
int main()
{
#ifdef MyDebug
cout << "获取版本:" << cPlusPlusTest_version_major << endl;
#else
cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
#endif // DEBUG
customLibTest();
hello();
return 0;
}
方式一:使用 link_libraries()
link_libraries(${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib)
#使用link_libraries链接MyMathFunctions.lib
![](https://img-blog.csdnimg.cn/484a00c8df2649ceb9c0d7b42c6b2df9.png)
运行结果:
![](https://img-blog.csdnimg.cn/14769e9b68b34347bffe9bf97e7c385f.png)
使用 target_link_libraries()
target_link_libraries:指定目标链接的库
target_link_directories: 指定目标包含的头文件路径
target_compile_options:指定目标编译选项
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
可以链接多个库: 例如:
target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib ${PROJECT_SOURCE_DIR}/3dPart/lib/LibTest.lib)
target_link_libraries(target target1 target2)
target_link_libraries(target3 target target4)
PUBLI:表示target能够使用target1&target2库中的内容,target3 能够使用target1 & target2中定义的内容;默认状态为PUBLIC;
PRIVATE:表示target能够使用target1&target2库中的内容,target3不能使用target1&target2中定义的内容,只能使用target中定义的内容;
INTERFACE:表示target无法使用target1&target2的内容,但是target3 能够使用target1 & target2;
使用全路径
target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib)
使用 link_directories + target_link_libraries
link_directories(../3dPart/lib)
target_link_libraries(cPlusPlusTestProject MyMathFunctions)#直接写库的名称
结果:
![](https://img-blog.csdnimg.cn/073e22c1ec294edf8a308eab79159212.png)
引入头文件(include_directories)不与不引入头文件
使用 extern 上述代码不引入头文件 使用 extern 声明
引入头文件:
#include <iostream>
#include "myMathSquare.h"
using namespace std;
extern void hello();
void customLibTest() {
double x = 8;
double res = mySqrt(x);
cout << "输入x: " << x << "的平方是" << res << endl;
}
int main()
{
#ifdef MyDebug
cout << "获取版本:" << cPlusPlusTest_version_major << endl;
#else
cout << "获取版本: " << cPlusPlusTest_version_minor << endl;
#endif // DEBUG
customLibTest();
hello();
return 0;
}
例如:
![](https://img-blog.csdnimg.cn/c6c790f4a0d547caab4783b53b2f3a68.png)
error LNK2019:
无法解析的外部符号 "double __cdecl mySqrt(double)"
遇到的坑,把 .a 当成 .lib 用了
静态库(.a) 的使用
.a 库的使用与 .lib 相差无几。
使用全路径是与 lib 相同(使用库的全名):例如:
target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/libMyMathFunctions.a)
仅不同是使用 link_directories + target_link_libraries
需要注意的是,生成的.a 有前缀 lib. 例如: libxxxx.a, 去掉前缀使用 例如:
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)
target_link_libraries(cPlusPlusTestProject MyMathFunctions)
动态链接库
使用mingw与cmake 生成 .dll
使用 mingw 与 cmake 生成的是 xxx.dll 与 xxx.dll.a
修改生成库类型:
add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)
选择配置好的 winGW 环境
![](https://img-blog.csdnimg.cn/12412a7e7b034ff6ba2793143c3b73d2.png)
生成 动态库 .dll 及静态库 .dll.a
生成共享库
![](https://img-blog.csdnimg.cn/b1183d899b7746af9a027349706e5bab.png)
Linux 动态链接库,共享库只生成 .so
共享库的使用
将共享库复制第第三方库中,同时复制头文件:如
![](https://img-blog.csdnimg.cn/e748c3b1ecb049ef87c5ade1232b1af9.png)
sharedLibTest.h
//
// Created by ly on 2022/7/21.
//
#ifndef SHAREDLIBTEST_SHAREDLIBTEST_H
#define SHAREDLIBTEST_SHAREDLIBTEST_H
void test();
#endif //SHAREDLIBTEST_SHAREDLIBTEST_H
sharedLibTest.cpp
//
// Created by ly on 2022/7/21.
//
#include <iostream>
#include "sharedLibTest.h"
#include "myMathSquare.h"
void test(){
double x = 8;
double d = mySqrt(x);
std::cout << "x 的平方是: " << d << std::endl;
}
main.cpp
#include <iostream>
#include "sharedLibTest.h"
int main() {
std::cout << "Hello, World!" << std::endl;
test();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(sharedLibTest)
set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/3dPart/include)
include_directories(${PROJECT_SOURCE_DIR}/header)
#link_directories(3dPart/lib)
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)
add_executable(sharedLibTest
header/sharedLibTest.h
source/sharedLibTest.cpp
main.cpp)
target_link_libraries(sharedLibTest libMyMathFunctions.so)
方式1:target_link_libraries(testAuxSource MyMathFunctions)
方式2:target_link_libraries(testAuxSource libMyMathFunctions.so)
#target_link_libraries(testAuxSource MyMathFunctions)# 共享库可以调用全名,也可以调用项目名称
运行结果:
![](https://img-blog.csdnimg.cn/2b45c1f34bd449dfa8ea057c6fb56fdb.png)
aux_source_directory 的使用
在目录中查找所有源文件。
收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。即将某目录下的所有的源码文件设定一个变量名称,便于后期使用变量名代替所有的源码文件,比如与add_library生成静态库一并使用,以便指定子构建系统的构建的库类型和名称。
aux_source_directory 引用文件
例如:一个文件夹包含所有头文件,源文件。
aux_source_directory(. DIR_SR)
add_executable(testAuxSource ${DIR_SR})
文件目录
![](https://img-blog.csdnimg.cn/489faef160034abcba8e79f876f06241.png)
![](https://img-blog.csdnimg.cn/f817eab87f38493b9dca865ab62757d8.png)
当头文件和源文件不在同一个目录时:
文件目录:
![](https://img-blog.csdnimg.cn/ea8c01ab4dc1424db314c401db75444e.png)
cmakelist.txt 文件内容:
cmake_minimum_required(VERSION 3.17)
project(sharedLibTest)
set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/3dPart/include)
include_directories(${PROJECT_SOURCE_DIR}/header)
#link_directories(3dPart/lib)
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)
aux_source_directory(${PROJECT_SOURCE_DIR}/header/ DIR_SR)
aux_source_directory(${PROJECT_SOURCE_DIR}/source/ DIR_SRS)
aux_source_directory(. DIR_SRS_MAIN)
#add_executable(sharedLibTest
# header/sharedLibTest.h
# source/sharedLibTest.cpp
# main.cpp)
SET (MyCode ${DIR_SR} ${DIR_SRS} ${DIR_SRS_MAIN})
#add_executable(sharedLibTest ${DIR_SR} ${DIR_SRS} ${DIR_SRS_MAIN})
add_executable(sharedLibTest ${MyCode})
target_link_libraries(sharedLibTest libMyMathFunctions.so)
![](https://img-blog.csdnimg.cn/bade79cd851c4949a4a303bfc879cec5.png)
运行结果:
![](https://img-blog.csdnimg.cn/f4634a2f592447169d6fdc06441d9e68.png)
aux_source_directory 生成库
思考: 是否可以将头文件一起生存到库中?
aux_source_directory(. DIR_LIB_SRC)
add_library(MyMathFunctions SHARED ${DIR_LIB_SRC})
生成库的其它步骤不变
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)