当前位置: 首页> 游戏> 单机 > g++制作C++动态库的简洁例程

g++制作C++动态库的简洁例程

时间:2025/7/12 10:50:04来源:https://blog.csdn.net/weixin_43297891/article/details/139909776 浏览次数:0次

g++制作C++动态库的简洁例程

在这里插入图片描述

code review!

文章目录

  • g\++制作C++动态库的简洁例程
    • 1. 创建 C++ 动态库
      • 1.1 动态库源文件
      • 1.2 编译动态库
    • 2. 使用动态库
      • 2.1 命令行编译链接然后运行
      • 2.2 使用 CMake 编译链接然后运行
    • 3.附加笔记:关于运行时是否能找到libmylib.so的问题汇总
      • 3.1.`g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib `详解
        • 命令详解
          • 1. `g++`
          • 2. `-L.`
          • 3. `-Wl,-rpath=.`
          • 4. `-o main`
          • 5. `main.cpp`
          • 6. `-lmylib`
        • 总结
        • 为什么需要这些选项
      • 3.2.`g++ -o main main.cpp -lmylib`直接这样可以编译成功吗?
        • 具体情况分析
          • 1. 默认库路径
          • 2. 当前目录下的库文件
        • 推荐的命令
      • 3.3.`g++ -o main main.cpp -L. -lmylib`直接这样可以编译成功吗?
        • 命令详解
        • 编译阶段
        • 运行阶段
        • 解决方法
        • 推荐的命令
      • 3.4.通过cmake编译,运行时不需要先`export LD_LIBRARY_PATH=.`,直接`./main`可以运行成功吗?
        • 主要问题
        • 解决方法
        • 修改后的 `CMakeLists.txt`
        • 步骤
        • 解释
    • 4.补充笔记:创建一个包含类的C++动态库,并分别使用命令行和CMake进行编译、链接和运行
      • 4.1. 创建C++动态库
        • 4.1.1 文件结构
        • 4.1.2 MyClass.h
        • 4.1.3 MyClass.cpp
        • 4.1.4 main.cpp
      • 4.2. 使用命令行编译和链接
        • 4.2.1 编译动态库
        • 4.2.2 编译主程序并链接动态库
        • 4.2.3 运行主程序
      • 4.3. 使用CMake编译和链接
        • 4.3.1 创建CMakeLists.txt
        • 4.3.2 编译项目
        • 4.3.3 运行主程序

下面是一个使用 g++ 制作 C++ 动态库的完整简洁例子,并展示了如何通过命令行和 CMake 使用该动态库。

1. 创建 C++ 动态库

1.1 动态库源文件

首先,我们创建一个简单的 C++ 动态库。假设我们有一个库文件 mylib.cpp

// mylib.cpp
#include <iostream>void say_hello() {std::cout << "Hello, world!" << std::endl;
}

对应的头文件 mylib.h

// mylib.h
#ifndef MYLIB_H
#define MYLIB_Hvoid say_hello();#endif // MYLIB_H

1.2 编译动态库

使用 g++ 编译并创建动态库 libmylib.so

g++ -shared -fPIC -o libmylib.so mylib.cpp

2. 使用动态库

2.1 命令行编译链接然后运行

首先,创建一个使用该库的应用程序 main.cpp

// main.cpp
#include "mylib.h"int main() {say_hello();return 0;
}

编译并链接应用程序:

g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib

运行应用程序:

./main

2.2 使用 CMake 编译链接然后运行

首先,创建一个 CMake 项目文件 CMakeLists.txt

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyApp)# 添加库的路径
link_directories(${CMAKE_SOURCE_DIR})# 添加头文件路径
include_directories(${CMAKE_SOURCE_DIR})# 添加可执行文件
add_executable(main main.cpp)# 链接动态库
target_link_libraries(main mylib)

然后,在项目目录下创建 main.cpp

// main.cpp
#include "mylib.h"int main() {say_hello();return 0;
}

编译并运行应用程序:

# 创建构建目录
mkdir build
cd build# 运行 CMake 配置
cmake ..# 编译项目
make# 运行应用程序
./main

3.附加笔记:关于运行时是否能找到libmylib.so的问题汇总

3.1.g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib 详解

下面是对命令 g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib 的详细解释:

命令详解
g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib
1. g++

g++ 是 GNU 编译器集合(GCC)中用于编译 C++ 代码的编译器。

2. -L.

-L 选项指定链接器搜索库文件的目录。. 表示当前目录。这意味着链接器将在当前目录中查找库文件。

3. -Wl,-rpath=.

-Wl 选项将参数传递给链接器(ld)。-rpath 选项指定运行时库搜索路径。. 表示当前目录。这意味着在运行时,程序会在当前目录中查找动态库。

4. -o main

-o 选项指定输出文件的名称。在这个例子中,输出文件名为 main,即生成的可执行文件名为 main

5. main.cpp

这是源文件的名称,包含 main 函数。在这个例子中,main.cpp 是要编译的源文件。

6. -lmylib

-l 选项用于指定要链接的库。mylib 是库的名称,链接器会寻找名为 libmylib.so 的动态库文件进行链接。

总结

综上所述,这个命令的作用是:

  1. 使用 g++ 编译 main.cpp
  2. 在当前目录中搜索库文件(-L.)。
  3. 在生成的可执行文件中指定运行时库搜索路径为当前目录(-Wl,-rpath=.)。
  4. 输出文件名为 main-o main)。
  5. 链接名为 libmylib.so 的动态库(-lmylib)。
为什么需要这些选项
  • -L.-lmylib:确保编译器能够找到并链接 libmylib.so 动态库。
  • -Wl,-rpath=.:确保生成的可执行文件在运行时能够找到并加载 libmylib.so 动态库。运行时库路径指定为当前目录,这对于开发和测试环境很有用,但在生产环境中通常会使用更安全和标准的库路径。

通过这些选项,确保了在编译和运行时都能正确找到和使用动态库。

3.2.g++ -o main main.cpp -lmylib直接这样可以编译成功吗?

g++ -o main main.cpp -lmylib 这个命令在某些情况下可能会编译成功,但通常还需要指定库文件的搜索路径以及运行时库路径,特别是在使用自定义库(如当前目录下的 libmylib.so)时。

具体情况分析
1. 默认库路径

如果 libmylib.so 位于系统的默认库路径(例如 /usr/lib/usr/local/lib),那么这个命令可能会成功,因为链接器能够自动找到库文件。

2. 当前目录下的库文件

如果 libmylib.so 位于当前目录,则需要显式告诉链接器在哪里查找库文件,以及在运行时如何找到动态库。为了确保编译和运行成功,建议使用以下更完整的命令:

推荐的命令
g++ -L. -Wl,-rpath=. -o main main.cpp -lmylib

这条命令确保了编译器和运行时都能正确找到库文件。具体解释如下:

  • -L.:指定链接器在当前目录查找库文件。
  • -Wl,-rpath=.:告诉运行时加载器在当前目录查找动态库。
  • -o main:指定生成的可执行文件名为 main
  • main.cpp:要编译的源文件。
  • -lmylib:指定要链接的库 libmylib.so

虽然 g++ -o main main.cpp -lmylib 在某些特定情况下可能会成功,但通常需要指定库文件的搜索路径和运行时路径,以确保编译和运行时都能正确找到库文件。推荐使用更完整的命令来避免潜在的问题。

3.3.g++ -o main main.cpp -L. -lmylib直接这样可以编译成功吗?

g++ -o main main.cpp -L. -lmylib 这个命令可以在编译阶段成功,但在运行时可能会遇到问题,特别是如果 libmylib.so 位于当前目录且未包含在系统默认的库路径中。

命令详解
g++ -o main main.cpp -L. -lmylib
  • g++:使用 GNU 编译器编译 C++ 代码。
  • -o main:指定输出文件的名称为 main
  • main.cpp:要编译的源文件。
  • -L.:指定链接器在当前目录查找库文件。
  • -lmylib:指定要链接的库 libmylib.so
编译阶段

在编译阶段,这个命令会成功,因为 -L. 告诉链接器在当前目录查找库文件 libmylib.so

运行阶段

在运行阶段,生成的可执行文件需要找到并加载 libmylib.so。如果 libmylib.so 不在系统默认的库路径中(例如 /usr/lib/usr/local/lib),运行时会出现类似以下错误:

./main: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
解决方法

为了在运行时能够找到 libmylib.so,有几种方法:

  1. 使用 LD_LIBRARY_PATH 环境变量

    在运行程序之前,将当前目录添加到 LD_LIBRARY_PATH 环境变量:

    export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
    ./main
    
  2. 使用 -Wl,-rpath 链接选项

    在编译时指定运行时库路径:

    g++ -o main main.cpp -L. -lmylib -Wl,-rpath=.
    
  3. 将库文件移动到系统默认库路径

    libmylib.so 移动到系统默认的库路径,如 /usr/lib/usr/local/lib,并运行 ldconfig 来更新库缓存。

推荐的命令

为了确保编译和运行都能顺利进行,推荐使用以下命令:

g++ -o main main.cpp -L. -lmylib -Wl,-rpath=.

虽然 g++ -o main main.cpp -L. -lmylib 可以在编译阶段成功,但为了确保在运行时也能找到动态库,建议使用 -Wl,-rpath=. 链接选项,或者在运行时设置 LD_LIBRARY_PATH 环境变量。

3.4.通过cmake编译,运行时不需要先export LD_LIBRARY_PATH=.,直接./main可以运行成功吗?

直接使用提供的 CMakeLists.txt 文件,生成的可执行文件 main 在运行时是否需要设置 LD_LIBRARY_PATH 环境变量,取决于系统和 CMake 的配置。

主要问题

默认情况下,CMake 生成的可执行文件并不会自动包含运行时库路径(rpath)。因此,如果 libmylib.so 不在系统默认的库路径中,运行时会找不到这个库,导致无法运行。

解决方法

为了确保生成的可执行文件可以在运行时找到 libmylib.so,需要在 CMakeLists.txt 中显式设置 rpath

修改后的 CMakeLists.txt

可以修改 CMakeLists.txt 文件来包含运行时库路径信息。以下是修改后的版本:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(MyApp)# 添加库的路径
link_directories(${CMAKE_SOURCE_DIR})# 添加头文件路径
include_directories(${CMAKE_SOURCE_DIR})# 添加可执行文件
add_executable(main main.cpp)# 链接动态库
target_link_libraries(main mylib)# 设置运行时库路径(rpath)
set_target_properties(main PROPERTIESBUILD_RPATH "${CMAKE_SOURCE_DIR}"INSTALL_RPATH "${CMAKE_SOURCE_DIR}"INSTALL_RPATH_USE_LINK_PATH TRUE
)
步骤
  1. 创建构建目录并进入

    mkdir build
    cd build
    
  2. 运行 CMake 配置

    cmake ..
    
  3. 编译项目

    make
    
  4. 运行应用程序

    ./main
    
解释
  • set_target_properties:为目标 main 设置属性。
    • BUILD_RPATH:设置构建时的 rpath,即在编译生成的可执行文件中包含的库路径。
    • INSTALL_RPATH:设置安装时的 rpath,对于这个示例,设置与 BUILD_RPATH 相同。
    • INSTALL_RPATH_USE_LINK_PATH:确保安装时使用链接路径。

通过这种方式,生成的可执行文件将包含运行时库路径信息,不需要在运行时设置 LD_LIBRARY_PATH 环境变量,直接运行 ./main 即可找到并加载 libmylib.so

通过在 CMakeLists.txt 中设置 rpath,可以确保生成的可执行文件在运行时能够找到所需的动态库,不需要额外设置 LD_LIBRARY_PATH 环境变量。这种方法对于开发和测试环境非常方便。

4.补充笔记:创建一个包含类的C++动态库,并分别使用命令行和CMake进行编译、链接和运行

4.1. 创建C++动态库

4.1.1 文件结构
├── MyLibrary
│   ├── MyClass.h
│   └── MyClass.cpp
├── main.cpp
├── build (编译输出目录)
4.1.2 MyClass.h
// MyClass.h#ifndef MYCLASS_H
#define MYCLASS_Hclass MyClass {
public:MyClass();void sayHello();
};#endif // MYCLASS_H
4.1.3 MyClass.cpp
// MyClass.cpp#include "MyClass.h"
#include <iostream>MyClass::MyClass() {}void MyClass::sayHello() {std::cout << "Hello from MyClass!" << std::endl;
}
4.1.4 main.cpp
// main.cpp#include "MyClass.h"int main() {MyClass myClass;myClass.sayHello();return 0;
}

4.2. 使用命令行编译和链接

4.2.1 编译动态库
g++ -fPIC -shared -o build/libMyClass.so MyLibrary/MyClass.cpp
4.2.2 编译主程序并链接动态库
g++ -o build/main main.cpp -Lbuild -lMyClass
4.2.3 运行主程序
LD_LIBRARY_PATH=build ./build/main

4.3. 使用CMake编译和链接

4.3.1 创建CMakeLists.txt

在项目根目录下创建 CMakeLists.txt 文件。

cmake_minimum_required(VERSION 3.10)
project(MyProject)# 设置C++版本
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)# 添加库
add_library(MyClass SHARED MyLibrary/MyClass.cpp)# 添加可执行文件
add_executable(main main.cpp)# 链接库
target_link_libraries(main MyClass)
4.3.2 编译项目
mkdir -p build
cd build
cmake ..
make
4.3.3 运行主程序
LD_LIBRARY_PATH=. ./main
关键字:g++制作C++动态库的简洁例程

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: