学习使用cmake 生成及使用库,使用cmake 生成 .lib 静态库 及动态库(.dll)。及linux 下使用的静态库 .a 和 动态库(.so, 也称为共享库)
开发工具: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(
[EXCLUDE_FROM_ALL]
[source1] [source2] [...])
添加名为target_sources()
后续指定
生成的library名会根据STATIC
或SHARED及 生成平台
成为name.a/name.lib 或 name.so/.dll
windows下,如果dll没有export任何信息,则不能使用SHARED
,要标识为MODULE
MODULE: 在使用 dyId 的系统有效,如果不支持dyid, 则被当做shared对待
EXCLUDE_FROM_ALL: 这个库不会被默认构建,除非有其他的组件或者手工构建
开始尝试使用 vs 2019 建立的 cmake 项目生成 静态库。一直未找到生成入口。(生成windows 静态库仅仅只是想尝试使用 cmake生成 .lib 静态库, 更简单的方式是 vs .sln 解决方案中直接设置,或直接新建 生成静态库解决方案)。
偶然终于找到怎么生成 使用 cmake 生成解决方案。然运行解决方案生成 库。
项目右键 打开终端
使用 cmake 生成解决方案
j命令: cmake .
结果:
打开解决方案:
生成:
如果用此种方式生成动态库 貌似 只生成dll,不生成调用 dll 所需的静态库
修改:add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)
其他步骤一致
打开项目文件夹
设置 Clion 中的 visual studio 环境
打开设置:
新增工具链
改为 64 位
新增cmake 环境
选择debug 或者 release
查看文件夹下 是否出现 visual studio 相应的文件夹
如果没有 打开 cmake reset 或 刷新
选择相应环境 构建
生成结果
新建一个调用文件 xxx.cpp
- #include
-
- 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(${PROJECT_SOURCE_DIR}/3dPart/lib/MyMathFunctions.lib) #使用link_libraries链接MyMathFunctions.lib
运行结果:
target_link_libraries:指定目标链接的库
target_link_directories: 指定目标包含的头文件路径
target_compile_options:指定目标编译选项
- target_link_libraries(
- <PRIVATE|PUBLIC|INTERFACE>
- ...
- [<PRIVATE|PUBLIC|INTERFACE>
- ...]...)
可以链接多个库: 例如:
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(../3dPart/lib)
- target_link_libraries(cPlusPlusTestProject MyMathFunctions)#直接写库的名称
结果:
使用 extern 上述代码不引入头文件 使用 extern 声明
引入头文件:
- #include
- #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;
- }
例如:
无法解析的外部符号 "double __cdecl mySqrt(double)"
遇到的坑,把 .a 当成 .lib 用了
.a 库的使用与 .lib 相差无几。
使用全路径是与 lib 相同(使用库的全名):例如:
target_link_libraries(cPlusPlusTestProject ${PROJECT_SOURCE_DIR}/3dPart/lib/libMyMathFunctions.a)
需要注意的是,生成的.a 有前缀 lib. 例如: libxxxx.a, 去掉前缀使用 例如:
link_directories(${PROJECT_SOURCE_DIR}/3dPart/lib)
target_link_libraries(cPlusPlusTestProject MyMathFunctions)
使用 mingw 与 cmake 生成的是 xxx.dll 与 xxx.dll.a
修改生成库类型:
add_library(MyMathFunctions SHARED ./source/myMathSquare.cpp)
选择配置好的 winGW 环境
生成 动态库 .dll 及静态库 .dll.a
使用 :
linux
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
- #include "sharedLibTest.h"
- #include "myMathSquare.h"
-
- void test(){
- double x = 8;
- double d = mySqrt(x);
- std::cout << "x 的平方是: " << d << std::endl;
-
- }
-
main.cpp
- #include
- #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)
运行结果: