CMake基础(3)静态库

简介: CMake基础(3)静态库

0x01 介绍

在 CMake 中,静态库是一种特殊的目标文件,它与共享库和可执行文件不同,在链接时需要手动添加。静态库通常以 .a 或 .lib 结尾,可以通过 CMake 的 add_library() 命令添加。

0x01以下内容为补充知识点 , 学习静态库只看0x02示例就行。

add_library

CMake 还提供了一些其他的库类型,例如共享库(.so 或 .dll)、模块库(.mod)和对象库(.o)。可以根据实际需求选择适当的库类型。在 CMake 中,你可以使用 add_library() 命令来添加不同类型的库

# 添加静态库

add_library(MyStaticLib STATIC src/MyStaticLib.cpp)

# 添加共享库

add_library(MySharedLib SHARED src/MySharedLib.cpp)

# 添加模块库

add_library(MyModuleLib MODULE src/MyModuleLib.cpp)

# 添加对象库

add_library(MyObjectLib OBJECT src/MyObjectLib.cpp)

target_link_libraries

添加完库之后 , 可以通过 target_link_libraries() 命令添加链接。使用静态库的优点是可以将代码和库文件打包在一起,避免了动态库版本的冲突问题。

静态库可以在链接时使用绝对路径或者相对路径来指定,例如:

MyApp 是要链接静态库的目标文件,/path/to/MyLib、../lib/MyLib 和 $ENV{MY_LIB_PATH} 是静态库的路径。

# 使用绝对路径链接静态库

target_link_libraries(MyApp /path/to/MyLib)

# 使用相对路径链接静态库

target_link_libraries(MyApp ../lib/MyLib)

# 使用环境变量链接静态库

# 在系统的环境变量中设置 MY_LIB_PATH 变量,并在 CMake 中使用 $ENV{MY_LIB_PATH} 来引用该变量。

target_link_libraries(MyApp $ENV{MY_LIB_PATH})

link_directories

可以通过 link_directories() 命令来指定静态库的搜索路径,例如:

# 添加静态库的搜索路径,

link_directories(/usr/local/lib)

# 使用静态库的名称链接静态库

target_link_libraries(MyApp MyLib)

/usr/local/lib是静态库的搜索路径,MyLib 是静态库的名称。通过使用 link_directories() 命令,可

以避免在 target_link_libraries() 中指定完整的静态库路径。

0x02 示例

下面是一个简单的demo,使用 CMake 构建一个静态库:

本教程中的文件如下:

ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03$ tree
.
├── CMakeLists.txt
├── build
├── include
│   └── static
│       └── Hello.h
└── src
    ├── Hello.cpp
    └── main.cpp
 
4 directories, 4 files
 
cmake_minimum_required(VERSION 3.1)
 
project(hello_library)
 
 
# 定义库的名称为 hello_library
#>>>>>>> hello_library 是库的名称,STATIC 表示构建静态库,src/Hello.cpp 是库文件的路径。
add_library(hello_library STATIC src/Hello.cpp)
 
# 添加头文件目录
target_include_directories(hello_library PUBLIC ${PROJECT_SOURCE_DIR}/include)
 
# 定义一个可执行文件
add_executable(hello_binary src/main.cpp)
 
message(STATUS ${hello_binary})
 
# 安装静态库到 /usr/local/lib 目录
install(TARGETS hello_library DESTINATION /usr/local/lib)
 
# 安装可执行文件到 /usr/local/bin 目录
install(TARGETS hello_binary DESTINATION /usr/local/bin)
 
# 将静态库 MyLib 链接到可执行文件 MyApp 上
target_link_libraries(hello_binary PRIVATE hello_library)

hello_binary 是可执行文件的名称,src/main.cpp 是可执行文件的源文件,通过 target_link_libraries() 命令将静态库 hello_library 链静态库可以通过 add_library() 命令添加,并在链接时通过 target_link_libraries() 命令添加链接。

使用静态库的优点是可以将代码和库文件打包在一起,避免了动态库版本的冲突问题。

例如,应用程序依赖于多个库时,如果使用静态库,你可以将这些库打包到应用程序中,这样用户可以直接下载应用程序并运行,不需要额外的安装和配置。

同时,静态库也有一些缺点,比如体积会比动态库大,链接时间会比动态库长。使用静态库的优点是可以将代码和库文件打包在一起,避免了动态库版本的冲突问题。

#ifndef __HELLO_H__
#define __HELLO_H__
 
class Hello
{
public:
void print();
};
 
#endif
 
 
 
#include <iostream>
 
#include "static/Hello.h"
 
void Hello::print()
{
    std::cout << "Hello Static Library!" << std::endl;
}
 
 
#include "static/Hello.h"
 
int main(int argc, char *argv[])
{
    Hello hi;
    hi.print();
    return 0;
}

执行 cmake .. && make -j24 VERBOSE=1

ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$ cmake .. && make -j24 VERBOSE=1
--
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/Project/Cmake_examples/cmake_basics_03/build
/usr/bin/cmake -S/mnt/d/Project/Cmake_examples/cmake_basics_03 -B/mnt/d/Project/Cmake_examples/cmake_basics_03/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles /mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
make -f CMakeFiles/hello_library.dir/build.make CMakeFiles/hello_library.dir/depend
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
cd /mnt/d/Project/Cmake_examples/cmake_basics_03/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/d/Project/Cmake_examples/cmake_basics_03 /mnt/d/Project/Cmake_examples/cmake_basics_03 /mnt/d/Project/Cmake_examples/cmake_basics_03/build /mnt/d/Project/Cmake_examples/cmake_basics_03/build /mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_library.dir/DependInfo.cmake --color=
Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_library.dir/DependInfo.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_library.dir/depend.internal".
Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_library.dir/depend.internal".
Scanning dependencies of target hello_library
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
make -f CMakeFiles/hello_library.dir/build.make CMakeFiles/hello_library.dir/build
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
[ 25%] Building CXX object CMakeFiles/hello_library.dir/src/Hello.cpp.o
/usr/bin/c++   -I/mnt/d/Project/Cmake_examples/cmake_basics_03/include   -o CMakeFiles/hello_library.dir/src/Hello.cpp.o -c /mnt/d/Project/Cmake_examples/cmake_basics_03/src/Hello.cpp
[ 50%] Linking CXX static library libhello_library.a
/usr/bin/cmake -P CMakeFiles/hello_library.dir/cmake_clean_target.cmake
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_library.dir/link.txt --verbose=1
/usr/bin/ar qc libhello_library.a  CMakeFiles/hello_library.dir/src/Hello.cpp.o
/usr/bin/ranlib libhello_library.a
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
[ 50%] Built target hello_library
make -f CMakeFiles/hello_binary.dir/build.make CMakeFiles/hello_binary.dir/depend
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
cd /mnt/d/Project/Cmake_examples/cmake_basics_03/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /mnt/d/Project/Cmake_examples/cmake_basics_03 /mnt/d/Project/Cmake_examples/cmake_basics_03 /mnt/d/Project/Cmake_examples/cmake_basics_03/build /mnt/d/Project/Cmake_examples/cmake_basics_03/build /mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_binary.dir/DependInfo.cmake --color=
Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_binary.dir/DependInfo.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_binary.dir/depend.internal".
Dependee "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles/hello_binary.dir/depend.internal".
Scanning dependencies of target hello_binary
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
make -f CMakeFiles/hello_binary.dir/build.make CMakeFiles/hello_binary.dir/build
make[2]: Entering directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
[ 75%] Building CXX object CMakeFiles/hello_binary.dir/src/main.cpp.o
/usr/bin/c++   -I/mnt/d/Project/Cmake_examples/cmake_basics_03/include   -o CMakeFiles/hello_binary.dir/src/main.cpp.o -c /mnt/d/Project/Cmake_examples/cmake_basics_03/src/main.cpp
[100%] Linking CXX executable hello_binary
/usr/bin/cmake -E cmake_link_script CMakeFiles/hello_binary.dir/link.txt --verbose=1
/usr/bin/c++    -rdynamic CMakeFiles/hello_binary.dir/src/main.cpp.o  -o hello_binary  libhello_library.a
make[2]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
[100%] Built target hello_binary
make[1]: Leaving directory '/mnt/d/Project/Cmake_examples/cmake_basics_03/build'
/usr/bin/cmake -E cmake_progress_start /mnt/d/Project/Cmake_examples/cmake_basics_03/build/CMakeFiles 0
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$

最终得到hello_binary和 libhello_library.a, 执行编译出的可执行文件

ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$ ls
CMakeCache.txt  CMakeFiles  Makefile  cmake_install.cmake  hello_binary  libhello_library.a
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$ ./hello_binary
Hello Static Library!

在 CMake 中,你可以使用 install() 命令将静态库安装到 /usr/local/lib 目录,例如:

修改CMakeLists.txt文件增加以下内容

# 安装静态库到 /usr/local/lib 目录
install(TARGETS hello_library DESTINATION /usr/local/lib)
 
# 安装可执行文件到 /usr/local/bin 目录
install(TARGETS hello_binary DESTINATION /usr/local/bin)

在上面的例子中,hello_library 是静态库的名称,/usr/local/lib 是安装目录。通过 install() 命令,可以将静态库安装到指定的目录中。

在执行 cmake 命令时,CMake 会根据你的 CMakeLists.txt 文件中的内容生成安装脚本。你可以通过 make install 命令来安装静态库。例如,你可以运行下面的命令:

cmake .. && make -j24 install 主要是install , 但这个make install没有权限需要加sudo , 重新来执行以下

cmake .. && sudo make -j24 install看到了吗 , 生成文件到指定路径下了 , 你可以在不同的目录下执行hello_binary了。

Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libhello_library.a
-- Installing: /usr/local/bin/hello_binary
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$ cmake .. && make -j24 install
--
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/Project/Cmake_examples/cmake_basics_03/build
[ 50%] Built target hello_library
[100%] Built target hello_binary
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libhello_library.a
CMake Error at cmake_install.cmake:49 (file):
  file INSTALL cannot copy file
  "/mnt/d/Project/Cmake_examples/cmake_basics_03/build/libhello_library.a" to
  "/usr/local/lib/libhello_library.a": Permission denied.
 
 
make: *** [Makefile:86: install] Error 1
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$  cmake .. && sudo make -j24 install
--
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/d/Project/Cmake_examples/cmake_basics_03/build
[sudo] password for ln28:
[ 50%] Built target hello_library
[100%] Built target hello_binary
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libhello_library.a
-- Installing: /usr/local/bin/hello_binary
ln28@DESKTOP-FS9U3GT:/mnt/d/Project/Cmake_examples/cmake_basics_03/build$

轻轻松松搞定 ~

相关文章
|
6月前
CMake基础(4)动态库
CMake基础(4)动态库
63 1
|
6月前
|
存储 自然语言处理 Linux
CMake基础(1)初识CMake
CMake基础(1)初识CMake
53 0
|
3月前
|
前端开发 C语言
gcc动态库升级
gcc动态库升级
|
6月前
|
编译器 C语言 C++
CMake基础(9)使用Clang编译
CMake基础(9)使用Clang编译
461 0
|
6月前
|
编译器 Linux 开发者
【cmake 交叉编译配置设置】CMAKE_TOOLCHAIN_FILE:跨平台编译的秘密武器
【cmake 交叉编译配置设置】CMAKE_TOOLCHAIN_FILE:跨平台编译的秘密武器
584 0
|
11月前
|
并行计算 编译器 Linux
CMake基础
CMake基础
|
存储 Cloud Native Linux
CMake学习之静态库动态库
CMake学习之静态库动态库
|
编译器 Linux vr&ar
MinGW编译静态库
MinGW编译静态库
377 0
|
XML 并行计算 Linux
MSVC编译静态库
MSVC编译静态库
328 0
|
缓存 Unix Linux
linux系统编程(三)gcc常用技巧与静态库与动态库制作
linux系统编程(三)gcc常用技巧与静态库与动态库制作
270 0
linux系统编程(三)gcc常用技巧与静态库与动态库制作