学习使用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
项目结构:
声明库函数 .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 生成解决方案。然运行解决方案生成 库。
项目右键 打开终端
使用 cmake 生成解决方案
j命令: cmake .
结果:
打开解决方案:
生成:
如果用此种方式生成动态库 貌似 只生成dll,不生成调用 dll 所需的静态库
修改:add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)
其他步骤一致
使用Clion 生成静态库(windows .lib)
打开项目文件夹
设置 Clion 中的 visual studio 环境
打开设置:
新增工具链
改为 64 位
新增cmake 环境
选择debug 或者 release
查看文件夹下 是否出现 visual studio 相应的文件夹
如果没有 打开 cmake reset 或 刷新
选择相应环境 构建
生成结果
使用静态库(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
运行结果:
使用 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)#直接写库的名称
结果:
引入头文件(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;
}
例如:
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 环境
生成 动态库 .dll 及静态库 .dll.a
生成共享库
Linux 动态链接库,共享库只生成 .so
共享库的使用
将共享库复制第第三方库中,同时复制头文件:如
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)# 共享库可以调用全名,也可以调用项目名称
运行结果:
aux_source_directory 的使用
在目录中查找所有源文件。
收集指定目录中所有源文件的名称,并将列表存储在提供的变量中。即将某目录下的所有的源码文件设定一个变量名称,便于后期使用变量名代替所有的源码文件,比如与add_library生成静态库一并使用,以便指定子构建系统的构建的库类型和名称。
aux_source_directory 引用文件
例如:一个文件夹包含所有头文件,源文件。
aux_source_directory(. DIR_SR)
add_executable(testAuxSource ${DIR_SR})
文件目录
当头文件和源文件不在同一个目录时:
文件目录:
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)
运行结果:
aux_source_directory 生成库
思考: 是否可以将头文件一起生存到库中?
aux_source_directory(. DIR_LIB_SRC)
add_library(MyMathFunctions SHARED ${DIR_LIB_SRC})
生成库的其它步骤不变
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)