Linux中g++将C++代码编译为动态库.so文件
前言
GCC(GNU Compiler Collection)
是一个由 GNU 项目开发的编译器,支持多种编程语言,包括 C、C++、Objective-C、Fortran、Ada、Go 等。GCC 主要用于将源代码编译成机器码或中间代码。
Make
是一种广泛用于 Unix 和类 Unix 系统中的自动化构建工具。它通过分析 Makefile
文件中的规则,自动判断哪些文件需要重新编译,并执行相应的编译命令。
- gcc: 适用于直接编译单个或少量源文件。
- make: 适用于大型项目,特别是涉及大量源文件和复杂依赖关系的项目。通过
Makefile
,可以清晰地定义项目结构,简化编译过程。
目标:将 C++ 文件生成动态库 .so 文件
在 Linux 中,要将 C++
代码编译成动态链接库(.so 文件),需要使用 g++ 的 -shared
和 -fPIC
选项。这些选项会告诉编译器生成位置无关的代码(PIC),以便共享库在不同内存地址加载。
示例 1:单个 C++ 文件编译成 .so 文件
假设你有以下文件:
header1.h
: 包含Class1
的声明source1.cpp
: 包含Class1
的实现
header1.h
#ifndef HEADER1_H
#define HEADER1_H
class Class1 {
public:
void method1();
};
#endif
source1.cpp
#include "header1.h"
#include <iostream>
void Class1::method1() {
std::cout << "Class1's method1 called" << std::endl;
}
编译命令
在终端中使用以下命令编译成 .so
文件:
g++ -shared -fPIC -o libclass1.so source1.cpp
-shared
: 生成共享对象文件。-fPIC
: 确保生成的位置无关代码。-o libclass1.so
: 指定输出文件名。
注意: 头文件和
.cpp
文件通常位于同一路径,无需在命令行中指定头文件。
示例 2:多个 C++ 文件编译成 .so 文件
假设你有以下文件:
header1.h
: 包含Class1
的声明source1.cpp
: 包含Class1
的实现header2.h
: 包含Class2
的声明source2.cpp
: 包含Class2
的实现
编译命令
在终端中使用以下命令编译:
g++ -shared -fPIC -o libmylibrary.so source1.cpp source2.cpp
此命令将 source1.cpp
和 source2.cpp
编译并链接为一个名为 libmylibrary.so
的共享库文件。
注意事项
- 确保头文件正确包含在
.cpp
文件中。 - 模板类或内联函数的实现应放在头文件中。
- 如遇未定义的引用错误,检查是否所有声明的函数或变量都已定义。
- 确保链接时程序能找到
.so
文件(可通过-L
和-l
选项指定库路径和名称)。
使用 .so 文件
生成 .so
文件后,可以在其他 C++ 程序中通过动态链接使用它。假设你有一个使用 Class1
的程序 main.cpp
,可使用以下命令编译:
g++ main.cpp -L. -lclass1 -o my_program
-L.
: 告诉编译器在当前目录查找库文件。-lclass1
: 指定库名称(省略lib
前缀和.so
后缀)。
运行程序前,确保动态链接器能找到 .so
文件。可以通过设置 LD_LIBRARY_PATH
环境变量,或将库文件安装到标准路径下:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
./my_program
或者,将库文件复制到 /usr/local/lib
等标准路径下,并更新系统库缓存:
sudo ldconfig
这样无需再指定库路径,系统会自动查找标准库路径。