1.概述
2.创建过程 共享库、动态链接库
1.举例 在Linux下创建C++类库(通常是共享库或静态库)涉及到几个步骤。以下是一个基本的指南,展示了如何创建一个简单的共享库。
1. 编写源代码
首先,你需要编写你的C++类库的源代码。例如,我们有一个简单的MyClass.h
和MyClass.cpp
文件。
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
public:
MyClass();
~MyClass();
void doSomething();
};
#endif // MYCLASS_H
MyClass.cpp
2. 编译为共享库
使用g++
编译器,你可以将你的代码编译为一个共享库(在Linux上通常是.so
文件)。
g++ -fPIC -shared -o libmyclass.so MyClass.cpp |
这里:
-fPIC
:位置无关代码(Position Independent Code),这对于共享库是必需的。-shared
:指示g++生成一个共享库。-o libmyclass.so
:指定输出文件的名称。
3. 使用你的库
现在,你可以在其他C++程序中使用你的库了。你需要包含你的头文件,并在编译时链接到你的库。
main.cpp
#include "MyClass.h"
int main() {
MyClass myObj;
myObj.doSomething();
return 0;
}
编译并链接:
g++ main.cpp -L. -lmyclass -o myprogram |
这里:
-L.
:指定库文件的搜索路径(在当前目录)。-lmyclass
:链接到libmyclass.so
库(注意不需要前缀lib
和后缀.so
)。-o myprogram
:指定输出文件的名称。
4. 运行你的程序
最后,运行你的程序:
./myprogram |
你应该能看到你的类库中的代码正在运行。
注意事项:
- 确保你的头文件和库文件在编译时是可用的。你可以使用
-I
选项来指定头文件的搜索路径。 - 在生产环境中,你可能希望将你的库文件安装到标准位置(如
/usr/local/lib
),并使用包管理工具(如dpkg
或rpm
)来管理它们。 - 对于更复杂的项目,你可能希望使用构建系统(如
Makefile
、CMake
或Bazel
)来自动化编译和链接过程。
2.linux 下 c++ 类库有几种
在Linux下,C++类库主要分为几大类,这些类库为开发者提供了丰富的功能和工具,以支持各种应用程序的开发。以下是对这些类库的简要介绍和分类:
- 标准库(Standard Library)
- C++标准库是C++编程语言的一部分,包含了大量的类和函数,用于支持各种常见的编程任务。它包括了STL(Standard Template Library)容器、算法、迭代器等,以及一些基础的输入输出流、字符串处理、时间和日期等。
- 网络通信库
- ACE(Adaptive Communication Environment):一个开源的、跨平台的框架,提供了用于并发通信软件的核心模式。ACE提供了一组丰富的可复用C++包装外观(Wrapper Facade)和框架组件。
- Boost.Asio:一个基于Boost的异步I/O库,封装了对Socket的常用操作,简化了基于Socket程序的开发。
- libevent:一个用C语言编写的网络库,主要支持类Linux操作系统,也支持Windows的IOCP。
- 跨平台GUI库
- Qt:一个跨平台的应用程序和用户界面框架,广泛用于开发GUI应用程序。
- JUCE:一个包含万象的C++类库,用于开发跨平台软件。
- 科学计算与并行处理库
- ROOT:一个面向对象的框架,可以高效地处理和分析大量的数据,常用于科学计算。
- 其他可能包括一些专门针对并行计算和科学计算的库,如OpenMP、Intel TBB等。
- XML和JSON处理库
- 这些库提供了对XML和JSON数据的解析和生成功能,使得在C++中处理这些数据格式变得简单。
- 其他专用库
- 根据应用程序的具体需求,可能还需要使用到一些专用的库,如加密库(OpenSSL)、数据库连接库(如MySQL Connector/C++)、图像处理库(如OpenCV)等。
- 静态库与动态库
- 在Linux下,C++库通常以静态库(.a文件)或动态库(.so文件)的形式存在。静态库在编译时被直接链接到可执行文件中,而动态库则在运行时被加载。
需要注意的是,以上只是C++类库的一个大致分类,实际上还有许多其他的库和框架可供选择。在选择使用哪个库时,需要根据项目的具体需求和开发者的偏好来决定。
2.linux 下静态库、动态库、共享库是什么关系
在Linux下,静态库、动态库和共享库之间的关系和概念可以概括如下:
- 静态库(Static Library)
- 扩展名:通常以
.a
作为文件扩展名。 - 链接方式:在编译时被链接到目标代码中的库文件,即被复制到可执行程序中。每个使用静态库的程序都会有库的一个副本。
- 优缺点:
- 优点:加载速度快,因为库已经被嵌入到可执行文件中;发布程序时无需额外提供库文件,因为库已经被包含在应用程序中。
- 缺点:会导致可执行文件体积变大,浪费磁盘空间和内存资源;更新、部署、发布麻烦,因为每次修改库都需要重新编译和链接所有使用该库的程序。
- 扩展名:通常以
- 动态库(Dynamic Link Library, DLL)
- 在Linux上,动态库通常被称为共享库(Shared Library)。
- 扩展名:在Linux系统中,动态库或共享库的文件名通常以
.so
(Shared Object)结尾。 - 链接方式:在程序编译的时候并不会被链接到目标代码中,而是在程序运行的时候才被载入。多个程序可以共享使用同一个动态库,节省了内存。
- 优缺点:
- 优点:链接时不复制,程序运行时由系统动态加载到内存,供程序调用;系统只加载一次,多个程序可以共用,节省内存;程序升级简单,只需要更新库文件,而无需重新编译和链接使用该库的程序。
- 缺点:运行时需要依赖外部的动态库文件,如果库文件缺失或版本不匹配,可能会导致程序无法正常运行。
- 总结
- 关系:动态库和共享库在Linux系统中是同一个概念的不同称呼,都指的是在程序运行时加载的库文件,可以被多个程序共享使用。而静态库则是在编译时被链接到目标代码中的库文件。
- 选择:开发者在选择使用静态库还是动态库时,需要根据项目的具体需求来决定。如果项目需要独立运行,不依赖外部库文件,或者对性能有较高要求,可以选择使用静态库;如果需要提高代码的复用性和可维护性,或者需要节省磁盘空间和内存资源,可以选择使用动态库。
在Linux系统中,合理地使用静态库和动态库,可以提高程序的运行效率和灵活性,同时也方便开发者进行代码的管理和维护。
3.linux 编译的时候 类库的搜索范围是什么
在Linux下编译C++程序时,类库的搜索范围主要取决于几个关键因素,这些因素共同决定了链接器在何处查找所需的库文件。以下是类库搜索范围的详细解释:
- 编译器参数(如-L):
- 使用
-L
参数可以指定链接器在编译时搜索库文件的目录。例如,如果你有一个库文件位于/home/user/libs
目录下,你可以使用-L/home/user/libs
来告诉链接器在那里查找库。
- 使用
- 环境变量LIBRARY_PATH:
LIBRARY_PATH
环境变量指定了链接器在编译时搜索库文件的路径。这个环境变量可以包含多个由冒号分隔的目录。链接器会首先搜索这些目录中的库文件。
- 内定目录:
- 链接器还会搜索一些内定的目录,这些目录是在编译GCC时写入程序内的。对于大多数Linux系统,这些目录通常包括
/lib
、/usr/lib
和/usr/local/lib
。
- 链接器还会搜索一些内定的目录,这些目录是在编译GCC时写入程序内的。对于大多数Linux系统,这些目录通常包括
- 链接器参数-rpath和-rpath-link:
-rpath
参数允许你指定在程序运行时链接器应该搜索的库文件路径。这些路径会被嵌入到可执行文件中,因此在运行时,链接器会首先在这些路径中查找库文件。-rpath-link
参数与-rpath
类似,但它仅用于编译时解析依赖关系,并不会影响运行时库文件的搜索路径。
- 环境变量LD_LIBRARY_PATH:
LD_LIBRARY_PATH
环境变量用于指定在程序运行时动态链接器应该搜索的库文件路径。这个环境变量主要用于在运行时覆盖默认的库文件搜索路径。然而,需要注意的是,虽然LD_LIBRARY_PATH
很有用,但它可能会引入不可预测的行为或性能问题,因此在使用时需要谨慎。
- 配置文件/etc/ld.so.conf和/etc/ld.so.cache:
/etc/ld.so.conf
文件包含了动态链接器在运行时搜索库文件的目录列表。这些目录会被/sbin/ldconfig
命令读取并生成一个缓存文件/etc/ld.so.cache
,以提高动态链接器的搜索效率。- 当你修改了
/etc/ld.so.conf
文件或添加了新的库文件目录后,需要运行/sbin/ldconfig
命令来更新/etc/ld.so.cache
文件。
综上所述,Linux编译时类库的搜索范围包括编译器参数指定的目录、环境变量LIBRARY_PATH指定的目录、内定目录、链接器参数-rpath和-rpath-link指定的目录、环境变量LD_LIBRARY_PATH指定的目录以及配置文件/etc/ld.so.conf和/etc/ld.so.cache中指定的目录。这些搜索路径共同构成了链接器在编译和运行时查找库文件的范围。
4.c 编译动态链接库
在C语言中,你可以创建一个动态链接库(也称为共享库),这允许你在多个程序之间共享代码。以下是在Unix-like系统(如Linux或macOS)上使用GCC编译器创建动态链接库的基本步骤:
- 编写源代码
首先,你需要编写你的C源代码。例如,我们创建一个简单的函数,该函数接受两个整数参数并返回它们的和。将此代码保存为mylib.c
。
#ifndef MYLIB_H
#define MYLIB_H
int add(int a, int b);
#endif //MYLIB_H
同时,你需要一个头文件(例如mylib.h
)来声明这个函数:
#include "mylib.h"
int add(int a, int b) {
return a + b;
}
- 编译为动态链接库
使用GCC编译器,你可以通过以下命令将源代码编译为动态链接库:
gcc -shared -o libmylib.so mylib.c |
这里,-shared
选项告诉GCC你要创建一个共享库,-o libmylib.so
指定输出文件的名称(在这种情况下是libmylib.so
)。你可以根据需要更改这个名称。
3. 使用动态链接库
一旦你有了动态链接库,你就可以在其他C程序中使用它。为此,你需要在编译时包含库,并在运行时确保库在系统的库路径中或指定库的路径。
例如,如果你有一个名为main.c
的程序,它使用了你的库中的函数,你可以这样编译它:
gcc -o main main.c -L. -lmylib |
在这里,-L.
告诉GCC在当前目录中查找库,-lmylib
指定要链接的库(注意,-l
选项后面的库名应去掉前面的lib
和后缀.so
)。
4. 运行程序
在运行程序之前,确保动态链接库在系统的库路径中,或者你可以通过设置LD_LIBRARY_PATH
环境变量来指定库的路径。例如:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH | |
./main |
这将把当前目录添加到库路径中,然后你可以运行你的程序。
请注意,上述步骤是针对Unix-like系统的。如果你在Windows上,过程会有所不同,特别是库的命名和编译选项。在Windows上,你可能会使用.dll
作为动态链接库的后缀,并使用不同的编译器选项来创建它们。
5.c 如何使用自定义的动态链接库
在C语言中,使用自定义的动态链接库(也称为共享库)涉及几个步骤。这里是一个基本的指南,展示了如何在Unix-like系统(如Linux或macOS)上创建和使用自定义的动态链接库。
1. 编写源代码
首先,你需要编写库的源代码和头文件。
mylib.h
(头文件):
#ifndef MYLIB_H
#define MYLIB_H
int add(int a, int b);
#endif //MYLIB_H
mylib.c
(源文件):
#include "mylib.h"
int add(int a, int b) {
return a + b;
}
2. 编译动态链接库
使用GCC编译器将源代码编译为动态链接库。
gcc -shared -o libmylib.so mylib.c |
3. 编写使用库的程序
现在,你可以编写一个C程序来使用这个库。
main.c
(使用库的程序):
#include <stdio.h>
#include "mylib.h"
int main() {
int sum = add(2, 3);
printf("The sum is: %d\n", sum);
return 0;
}
4. 编译并链接到动态链接库
编译你的程序时,需要链接到你的动态链接库。你需要告诉编译器在哪里找到库文件(使用-L
选项),以及要链接的库名(使用-l
选项,注意去掉lib
前缀和.so
后缀)。
gcc -o main main.c -L. -lmylib |
这里,-L.
告诉编译器在当前目录中查找库。
5. 运行程序
在运行程序之前,你需要确保动态链接库在系统的库路径中,或者你可以通过设置LD_LIBRARY_PATH
环境变量来指定库的路径。
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH | |
./main |
这里,:$LD_LIBRARY_PATH
确保你不会覆盖现有的库路径。
如果你不想设置LD_LIBRARY_PATH
,你可以将库文件复制到系统的标准库路径中,如/usr/local/lib
(可能需要root权限)。或者,你可以在编译时使用-Wl,-rpath
选项来指定运行时库的搜索路径。
6. 清理
在开发过程中,你可能想要清理生成的文件。你可以使用make
工具或简单地使用rm
命令来删除它们。
rm -f libmylib.so main |
然后,你可以重新编译和链接你的库和程序。
6.export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 啥意思
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
是一个在 Unix 和类 Unix 系统(如 Linux 和 macOS)上用于设置动态链接器(如 ld.so
或 ld-linux.so
)在运行时查找共享库(动态链接库)的目录的 shell 命令。
这个命令做了以下几件事:
- 设置环境变量:
export
命令用于设置或导出环境变量,这样它们就可以被子进程(如你启动的程序)所访问。 - 指定新的
LD_LIBRARY_PATH
值:这里,我们为LD_LIBRARY_PATH
分配了一个新的值。 .
(当前目录)::
前面的.
表示当前目录。当你执行./some_program
来运行一个程序时,它通常位于当前目录中。将.
添加到LD_LIBRARY_PATH
允许程序在当前目录中查找所需的共享库。$LD_LIBRARY_PATH
:这是一个环境变量引用,表示LD_LIBRARY_PATH
的当前值。在将.
添加到LD_LIBRARY_PATH
时,我们不想覆盖其现有的值(如果有的话),所以我们使用$LD_LIBRARY_PATH
来保留它。:
作为分隔符:在LD_LIBRARY_PATH
中,多个目录由冒号(:
)分隔。
因此,export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
的意思是:“将当前目录添加到 LD_LIBRARY_PATH
的开始位置,但保留 LD_LIBRARY_PATH
的任何其他现有值”。
这样做的一个常见原因是你正在测试或开发一个共享库,并且该库位于你当前的工作目录中。通过设置 LD_LIBRARY_PATH
,你可以确保你的程序在运行时能够找到并使用这个库,而无需将其复制到系统的标准库目录中。
但请注意,依赖于 LD_LIBRARY_PATH
来找到共享库通常不是一个好主意,因为它使得程序的运行依赖于特定的环境设置。在生产环境中,你通常应该安装共享库到标准的系统库目录(如 /usr/lib
或 /usr/local/lib
),或者使用其他方法来指定库的位置(如 ldconfig
或 -Wl,-rpath
链接器选项)。
7.c 编译时指定动态链接库的路径
在编译C程序时,如果你想指定动态链接库(共享库)的路径,你可以使用-L
选项来告诉编译器在链接阶段到哪里查找库文件,并使用-l
选项来指定要链接的库名(不包括前缀lib
和后缀.so
或.a
)。
但是,-L
选项只影响编译时的库搜索路径,不会影响程序运行时动态链接器查找库文件的路径。如果你想在运行时指定库文件的搜索路径,你需要设置LD_LIBRARY_PATH
环境变量。
编译时指定库路径
假设你的动态链接库文件是libmylib.so
,并且它位于/path/to/libs
目录下,你可以这样编译你的程序:
gcc -o myprogram main.c -L/path/to/libs -lmylib |
这条命令告诉编译器在/path/to/libs
目录下查找名为libmylib.so
的库文件,并将其链接到你的程序myprogram
中。
运行时指定库路径
如果你的程序在运行时找不到动态链接库,你可以通过设置LD_LIBRARY_PATH
环境变量来指定库文件的搜索路径。例如:
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH | |
./myprogram |
这条命令将/path/to/libs
添加到LD_LIBRARY_PATH
环境变量的开始位置,以确保你的程序在运行时能够找到libmylib.so
库文件。
使用-Wl,-rpath
选项
另外,你还可以使用-Wl,-rpath
选项来在编译时指定程序运行时库文件的搜索路径。这个选项将路径嵌入到可执行文件中,这样程序在运行时就会知道到哪里查找库文件。例如:
gcc -o myprogram main.c -L/path/to/libs -lmylib -Wl,-rpath,/path/to/libs |
这条命令会在编译时将/path/to/libs
路径嵌入到myprogram
可执行文件中,这样程序在运行时就会首先在这个路径下查找libmylib.so
库文件。注意,这种方式不依赖于LD_LIBRARY_PATH
环境变量。
3.创建过程 静态链接库
1.c 静态链接库试验
在C语言中,静态链接库(static library)是一种包含多个目标文件(object files)的归档文件,这些目标文件是编译器编译源代码后产生的。静态链接库在编译时会被完全嵌入到最终的可执行文件中,因此最终的可执行文件不依赖于外部库文件。
下面是一个简单的步骤,演示如何创建一个C静态链接库,并使用它:
1. 编写源代码
首先,我们需要编写一些源代码。假设我们有两个源文件:lib_add.c
和 lib_sub.c
,它们分别实现了加法和减法功能。
lib_add.c
:
#include "lib_add.h"
int add(int a, int b) {
return a + b;
}
lib_add.h
:
#ifndef LIB_ADD_H
#define LIB_ADD_H
int add(int a, int b);
#endif // LIB_ADD_H
lib_sub.c
:
#include "lib_sub.h"
int sub(int a, int b) {
return a - b;
}
lib_sub.h
:
#ifndef LIB_SUB_H
#define LIB_SUB_H
int sub(int a, int b);
#endif // LIB_SUB_H
2. 编译为目标文件
使用gcc编译器将源代码编译为目标文件:
gcc -c lib_add.c -o lib_add.o | |
gcc -c lib_sub.c -o lib_sub.o |
这将会生成两个目标文件:lib_add.o
和 lib_sub.o
。
3. 创建静态链接库
使用ar命令将目标文件归档为静态链接库:
ar rcs libmath.a lib_add.o lib_sub.o |
这将会生成一个名为libmath.a
的静态链接库。
4. 编写主程序
现在我们可以编写一个主程序来使用这个静态链接库:
main.c
:
#include <stdio.h>
#include "lib_add.h"
#include "lib_sub.h"
int main() {
int a = 5, b = 3;
printf("Addition: %d\n", add(a, b));
printf("Subtraction: %d\n", sub(a, b));
return 0;
}
5. 链接静态库并编译主程序
使用gcc编译器链接静态库并编译主程序:
gcc main.c -L. -lmath -o main |
注意-L.
告诉gcc在当前目录下搜索库文件,-lmath
告诉gcc链接名为math
的库(即libmath.a
)。
6. 运行程序
现在我们可以运行程序了:
./main |
如果一切正常,你应该会看到如下输出:
Addition: 8 | |
Subtraction: 2 |
这表示你的静态链接库已经成功创建,并且你的主程序已经成功链接并使用了它。
4.关联工具
1.拷贝文件到指定路径
在Unix-like系统(如Linux或macOS)中,你可以使用cp
命令来拷贝文件到指定路径。以下是如何使用cp
命令的基本示例:
拷贝单个文件
如果你想将文件source.txt
拷贝到/path/to/destination/
目录下,并且保持文件名不变,你可以这样做:
cp source.txt /path/to/destination/ |
拷贝文件并重命名
如果你想在拷贝时重命名文件,你可以指定新的文件名作为目标路径的一部分:
cp source.txt /path/to/destination/new_name.txt |
拷贝目录及其内容
如果你想拷贝一个目录及其所有内容到另一个位置,你需要使用-r
(或-R
,它们是等价的)选项来递归地拷贝目录:
cp -r source_directory /path/to/destination/ |
这会将source_directory
目录及其所有子目录和文件拷贝到/path/to/destination/
下。如果目标位置已经存在同名目录,你可能会收到一些警告或错误,具体取决于你的系统和cp
命令的版本。
注意事项
- 确保目标路径存在。如果目标路径不存在,
cp
命令可能会失败或创建目标路径(如果你使用了像-p
这样的选项来保持源文件的属性)。 - 如果你没有权限写入目标位置,
cp
命令会失败。你可能需要使用sudo
来获取必要的权限。 - 在使用
cp
命令时,要小心不要覆盖重要文件。你可以使用-i
选项来提示确认覆盖。
例如,以下命令会在覆盖文件之前提示你:
cp -i source.txt /path/to/destination/ |
2.linux 创建目录
在Linux中,你可以使用mkdir
命令来创建目录(也称为文件夹)。以下是一些基本的用法:
- 创建单个目录
如果你想要创建一个名为mydir
的目录,你可以这样做:
mkdir mydir |
- 创建多个目录
使用mkdir
命令一次创建多个目录,你可以使用空格分隔目录名:
mkdir dir1 dir2 dir3 |
- 递归创建目录
如果你想要创建一个目录树,其中包含嵌套的子目录,你可以使用-p
选项。例如,要创建/path/to/mydir
,即使/path
和/path/to
还不存在,你也可以这样做:
mkdir -p /path/to/mydir |
-p`选项会确保在创建新目录之前,所有必要的父目录都存在。
4. 设置目录权限
你可以使用-m
选项来指定新目录的权限。例如,要创建一个权限为755
的目录,你可以这样做:
mkdir -m 755 mydir |
注意:在Linux中,权限通常表示为三位数的八进制数,其中第一个数字代表所有者的权限,第二个数字代表组的权限,第三个数字代表其他用户的权限。755
意味着所有者有读、写、执行权限,组和其他用户只有读和执行权限。
5. 显示创建目录的详细信息
使用-v
选项(verbose)可以在创建目录时显示详细信息:
mkdir -v mydir |
这将在创建目录时显示一条消息,告诉你目录已被创建。
2.显示当前路径
在Linux中,你可以使用pwd
(Print Working Directory)命令来显示当前路径。在终端中输入pwd
并按下回车键,系统将输出你当前所在的目录路径。
例如:
$ pwd | |
/home/username |
在这个例子中,/home/username
是当前用户的家目录路径。$
是命令提示符,它表示你可以在这里输入命令。当你输入pwd
并按下回车键后,命令提示符会移动到下一行,显示当前目录的路径。
3.”/usr/bin/ld: -lib1没有找到:没有这样的文件和目录“ 这里"/usr/bin/ld"是啥意思
注意:不包括前缀 lib
和后缀 .so
或 .a
在Linux系统中,/usr/bin/ld
通常是链接器(linker)的路径,链接器是用于将编译后的目标文件(object files)和库文件(library files)组合成最终的可执行文件或共享库的工具。当你看到错误消息:
/usr/bin/ld: -lib1没有找到:没有这样的文件和目录 |
这通常意味着链接器在尝试链接你的程序时,找不到名为 lib1
的库文件或相关参数传递有误。这里的 -lib1
很可能是一个链接器选项或参数的一部分,但它被错误地解释了。
这个问题可能有几个原因:
-
拼写或路径错误:你可能想要链接的库文件名或路径拼写错误,或者没有正确地指定库的路径。
-
链接器选项格式错误:如果你想要链接一个库,你应该使用
-l
选项(小写L),后面跟着库名(不包括前缀lib
和后缀.so
或.a
)。例如,要链接名为libexample.so
的库,你应该使用-lexample
。 -
库文件不存在:指定的库文件可能不存在于你告诉链接器的位置。
为了解决这个问题,你可以:
- 检查库文件的名称和路径是否正确。
- 使用正确的链接器选项格式。
- 确保库文件存在于你告诉链接器的位置,或者确保库文件的路径已经被添加到库搜索路径中(例如,通过
LD_LIBRARY_PATH
环境变量或链接器的-L
选项)。
如果你确实想要链接一个名为 lib1
的库,并且该库文件位于标准库路径下(如 /usr/lib
或 /usr/local/lib
),你应该使用 -l1
(注意是小写L和数字1,而不是 -lib1
)。如果库文件不在标准路径下,你需要使用 -L
选项指定库文件的路径。例如:
gcc -o myprogram main.o -L/path/to/libs -l1 |
在这个例子中,-L/path/to/libs
告诉链接器在 /path/to/libs
目录下查找库文件,而 -l1
则告诉链接器链接名为 lib1
的库(即查找 lib1.so
或 lib1.a
)。