如何 link 我的 main.c 文件与我的库 .a 文件?
How to link my main.c file with my library .a file?
我正在尝试制作一个属于我的静态库。假设有两个文件:stack.h
存放了我要存放在./include
文件中的声明,stack.c
实现了定义,main.c
调用了文件中的函数stack.h
.
制作 stack.a
文件,我想将其存储在 ./lib
中,使用这些说明:
>> gcc -c stack.c
>> ar -cq libstack.a stack.o
>> mv stack.h include
>> mv libstack.a lib
如果我想 link main.c
和我的 libstack.a
,我要用 gcc
做什么?我需要把这个库放到路径中吗?如果可以,该怎么做?
如果下一步,我想做我的动态库 .so
文件,谁能给点建议?
C 库
一般来说,库是从许多库源文件创建的,或者构建为归档文件 (libmine.a),静态 linked 到使用它们的可执行文件中,或者构建为共享对象文件(libmine.so) 动态地 linked 到使用它们的可执行文件中。要在这些类型的库中 link,请使用 gcc
命令行选项 -L
作为库文件的路径,并在库中使用 -l
到 link ( .so 或 .a):
-L{path to file containing library} -l${library name}
例如,如果我在 /home/newhall/lib/
中有一个名为 libmine.so 的库,那么我将执行以下操作以 link 它进入我的程序:
$ gcc -o myprog myprog.c -L/home/newhall/lib -lmine
您可能还需要指定并包含路径,以便编译器可以找到库头文件:-I /home/newhall/include
如果您创建了自己的共享对象文件并且没有将它们安装在 /usr/lib
中,那么您需要设置您的 LD_LIBRARY_PATH 环境变量,以便 运行 时间 [=185] =]er 可以找到它们并在 运行 时间加载它们。
例如,如果我将我的 .so 文件放在 home
目录中名为 lib
的目录中,我会将我的 LD_LIBRARY_PATH
环境设置为以下内容:
#如果运行宁bash:
>> export LD_LIBRARY_PATH=/home/newhall/lib:$LD_LIBRARY_PATH
# if 运行ning tcsh:
>> setenv LD_LIBRARY_PATH /home/newhall/lib:$LD_LIBRARY_PATH
使用和链接库代码
使用未被自动 link 编辑到您的程序中的库
编译器,你需要
-
- 在您的 C 源文件中包含库的头文件(下例中的
test.c
)
-
- 告诉编译器link库中的代码
.o
文件到你的可执行文件中:
第 1 步:在程序中添加包含行 (#include "somelib.h")
源文件(例如,test.c)。
第 2 步:Link 程序的 .c 文件和库目标文件
(即指定 somelib.o 文件作为 gcc 的命令行参数):
>> gcc -o myprog test.c somelib.o
生成的可执行文件 (myprog
) 将包含所有的机器代码
test.c 中定义的函数加上调用的任何 mylib 库函数。
创建和使用您自己的图书馆代码
要创建代码库,您需要执行以下操作:
(1) 为您的图书馆创建一个界面:mylib.h
(2) 创建您的库的实现:mylib.c
(3) 创建一个库目标文件 (.o),它可以 link 与使用您的库的程序编辑
3a.或者从许多 .o 文件中创建一个共享对象文件 (.so),这些文件可以动态 link 与使用您的库的程序编辑
3b。或从许多 .o 文件创建一个存档文件 (.a),这些文件可以静态地 link 与使用您的库的程序编辑
(4) 在其他 C 代码中使用库:(a) #include "mylib.h" (b) link in the libary code into a.out file
(5) 设置 LD_LIBRARY_PATH 环境变量,用于在 运行 时间
在非标准位置查找共享对象
详情:
(1) 接口:您的库的头文件应包含您的库导出的所有内容的定义:
带有库函数用户评论的函数原型
您的库导出的类型和全局变量的定义
您应该在头文件的内容周围使用“样板”代码 (#ifndef ... #endif),以确保预处理器仅包含一次 mylib.h 文件。
示例 .h 文件可能如下所示:
#ifndef MYLIB_H_ // _MYLIB_H_ is not allowed.
#define MYLIB_H_
// a constant definition exported by library:
#define MAX_FOO 20
// a type definition exported by library:
struct foo_struct {
int x;
float y;
};
typedef struct foo_struct foo_struct;
// a global variable exported by library
// "extern" means that this is not a variable declaration, it
// just defines that a variable named total_foo of type int
// exits and you can use it (its declaration is in some library source file)
extern int total_foo;
// a function prototype for a function exported by library:
extern int foo(float y, float z); // a very bad function name
#endif
(2) 实现:创建一个 mylib.c 文件,#includes“mylib.h”并包含库中每个函数的实现。
#include "mylib.h"
...
int total_foo;
int foo(float y, float z) {
...
}
(3) 创建一个 LIBRARY OBJECT FILE,它可以 linked 到使用你的库的其他程序中(使用 gcc 的 -c 选项告诉它只创建一个目标文件(a .o文件)而不是可执行文件:
>> gcc -o mylib.o -c mylib.c
然后您可以使用 mylib.o 文件作为“库文件”并将其静态 link 到其他使用它的程序中,或者...
- (3a) 或者,您可以从一个或多个 .o 文件创建一个共享对象文件,这些文件可以 linked 到使用您的库的其他程序中 共享对象文件是一个 Unix 名称动态 linked 库,其代码在 运行 时间加载到 a.out 文件中。要创建 .so 文件,请使用 gcc 的 -shared 标志。以下是示例构建的样子:
>> gcc -shared -o libmylib.so mylib.o blah.o grr.o -lm
- (3b) 您还可以从一个或多个 .o 文件构建一个 ARCHIVE 文件(静态 linked 库,libmylib.a)。如果您 link 使用静态库,其代码会在 运行 时复制到 a.out 文件中。
有关如何构建 .a 和 .so 文件的更多信息,请参阅 gcc 文档。
(4) 在其他程序中使用该库:
第一步:在所有使用库定义的程序源文件中添加一个包含行(#include "mylib.h")(例如,test.c)。
第 2 步:Link程序的 .c 文件和库目标文件
(即指定 mylib.o 文件作为 gcc 的命令行参数):
gcc test.c mylib.o
OR to link in libmylib.so (or libmylib.a):
gcc test.c -lmylib
OR to link with a library not in the standard path:
gcc test.c -L/home/newhall/lib -lmylib
The resulting a.out out will contain machine code for all the functions
defined in test.c plus any mylib library functions that are called by
the test.c code.
(5) 运行 一个可执行文件 link 使用共享目标文件编辑:
如果共享对象文件不在/usr/lib,那么你需要设置你的
LD_LIBRARY_PATH 环境变量,以便 运行 时间 link 人可以找到
并在 运行 时间将您的 .so 文件加载到可执行文件中:
在bash中:
>> export LD_LIBRARY_PATH=/home/newhall/lib:$LD_LIBRARY_PATH
在 tcsh 中:
>> setenv LD_LIBRARY_PATH /home/newhall/lib:$LD_LIBRARY_PATH
还有一个有用的link:demo for making libraries
我正在尝试制作一个属于我的静态库。假设有两个文件:stack.h
存放了我要存放在./include
文件中的声明,stack.c
实现了定义,main.c
调用了文件中的函数stack.h
.
制作 stack.a
文件,我想将其存储在 ./lib
中,使用这些说明:
>> gcc -c stack.c
>> ar -cq libstack.a stack.o
>> mv stack.h include
>> mv libstack.a lib
如果我想 link main.c
和我的 libstack.a
,我要用 gcc
做什么?我需要把这个库放到路径中吗?如果可以,该怎么做?
如果下一步,我想做我的动态库 .so
文件,谁能给点建议?
C 库
一般来说,库是从许多库源文件创建的,或者构建为归档文件 (libmine.a),静态 linked 到使用它们的可执行文件中,或者构建为共享对象文件(libmine.so) 动态地 linked 到使用它们的可执行文件中。要在这些类型的库中 link,请使用 gcc
命令行选项 -L
作为库文件的路径,并在库中使用 -l
到 link ( .so 或 .a):
-L{path to file containing library} -l${library name}
例如,如果我在 /home/newhall/lib/
中有一个名为 libmine.so 的库,那么我将执行以下操作以 link 它进入我的程序:
$ gcc -o myprog myprog.c -L/home/newhall/lib -lmine
您可能还需要指定并包含路径,以便编译器可以找到库头文件:-I /home/newhall/include
如果您创建了自己的共享对象文件并且没有将它们安装在 /usr/lib
中,那么您需要设置您的 LD_LIBRARY_PATH 环境变量,以便 运行 时间 [=185] =]er 可以找到它们并在 运行 时间加载它们。
例如,如果我将我的 .so 文件放在 home
目录中名为 lib
的目录中,我会将我的 LD_LIBRARY_PATH
环境设置为以下内容:
#如果运行宁bash:
>> export LD_LIBRARY_PATH=/home/newhall/lib:$LD_LIBRARY_PATH
# if 运行ning tcsh:
>> setenv LD_LIBRARY_PATH /home/newhall/lib:$LD_LIBRARY_PATH
使用和链接库代码
使用未被自动 link 编辑到您的程序中的库 编译器,你需要
-
- 在您的 C 源文件中包含库的头文件(下例中的
test.c
)
- 在您的 C 源文件中包含库的头文件(下例中的
-
- 告诉编译器link库中的代码
.o
文件到你的可执行文件中:
第 1 步:在程序中添加包含行 (#include "somelib.h") 源文件(例如,test.c)。
第 2 步:Link 程序的 .c 文件和库目标文件 (即指定 somelib.o 文件作为 gcc 的命令行参数):
>> gcc -o myprog test.c somelib.o
生成的可执行文件 (
myprog
) 将包含所有的机器代码 test.c 中定义的函数加上调用的任何 mylib 库函数。 - 告诉编译器link库中的代码
创建和使用您自己的图书馆代码
要创建代码库,您需要执行以下操作:
(1) 为您的图书馆创建一个界面:mylib.h
(2) 创建您的库的实现:mylib.c
(3) 创建一个库目标文件 (.o),它可以 link 与使用您的库的程序编辑
3a.或者从许多 .o 文件中创建一个共享对象文件 (.so),这些文件可以动态 link 与使用您的库的程序编辑
3b。或从许多 .o 文件创建一个存档文件 (.a),这些文件可以静态地 link 与使用您的库的程序编辑
(4) 在其他 C 代码中使用库:(a) #include "mylib.h" (b) link in the libary code into a.out file
(5) 设置 LD_LIBRARY_PATH 环境变量,用于在 运行 时间
在非标准位置查找共享对象详情:
(1) 接口:您的库的头文件应包含您的库导出的所有内容的定义:
带有库函数用户评论的函数原型
您的库导出的类型和全局变量的定义
您应该在头文件的内容周围使用“样板”代码 (#ifndef ... #endif),以确保预处理器仅包含一次 mylib.h 文件。
示例 .h 文件可能如下所示:
#ifndef MYLIB_H_ // _MYLIB_H_ is not allowed.
#define MYLIB_H_
// a constant definition exported by library:
#define MAX_FOO 20
// a type definition exported by library:
struct foo_struct {
int x;
float y;
};
typedef struct foo_struct foo_struct;
// a global variable exported by library
// "extern" means that this is not a variable declaration, it
// just defines that a variable named total_foo of type int
// exits and you can use it (its declaration is in some library source file)
extern int total_foo;
// a function prototype for a function exported by library:
extern int foo(float y, float z); // a very bad function name
#endif
(2) 实现:创建一个 mylib.c 文件,#includes“mylib.h”并包含库中每个函数的实现。
#include "mylib.h"
...
int total_foo;
int foo(float y, float z) {
...
}
(3) 创建一个 LIBRARY OBJECT FILE,它可以 linked 到使用你的库的其他程序中(使用 gcc 的 -c 选项告诉它只创建一个目标文件(a .o文件)而不是可执行文件:
>> gcc -o mylib.o -c mylib.c
然后您可以使用 mylib.o 文件作为“库文件”并将其静态 link 到其他使用它的程序中,或者...
- (3a) 或者,您可以从一个或多个 .o 文件创建一个共享对象文件,这些文件可以 linked 到使用您的库的其他程序中 共享对象文件是一个 Unix 名称动态 linked 库,其代码在 运行 时间加载到 a.out 文件中。要创建 .so 文件,请使用 gcc 的 -shared 标志。以下是示例构建的样子:
>> gcc -shared -o libmylib.so mylib.o blah.o grr.o -lm
- (3b) 您还可以从一个或多个 .o 文件构建一个 ARCHIVE 文件(静态 linked 库,libmylib.a)。如果您 link 使用静态库,其代码会在 运行 时复制到 a.out 文件中。 有关如何构建 .a 和 .so 文件的更多信息,请参阅 gcc 文档。
(4) 在其他程序中使用该库:
第一步:在所有使用库定义的程序源文件中添加一个包含行(#include "mylib.h")(例如,test.c)。
第 2 步:Link程序的 .c 文件和库目标文件 (即指定 mylib.o 文件作为 gcc 的命令行参数):
gcc test.c mylib.o OR to link in libmylib.so (or libmylib.a): gcc test.c -lmylib OR to link with a library not in the standard path: gcc test.c -L/home/newhall/lib -lmylib The resulting a.out out will contain machine code for all the functions defined in test.c plus any mylib library functions that are called by the test.c code.
(5) 运行 一个可执行文件 link 使用共享目标文件编辑:
如果共享对象文件不在/usr/lib,那么你需要设置你的 LD_LIBRARY_PATH 环境变量,以便 运行 时间 link 人可以找到 并在 运行 时间将您的 .so 文件加载到可执行文件中:
在bash中:
>> export LD_LIBRARY_PATH=/home/newhall/lib:$LD_LIBRARY_PATH
在 tcsh 中:
>> setenv LD_LIBRARY_PATH /home/newhall/lib:$LD_LIBRARY_PATH
还有一个有用的link:demo for making libraries