如果我想让可执行文件也与静态库 lib.a 链接,我该怎么做?
简短的回答是:只需将库包含在 gcc 命令中使用
gcc src/project/test.c -o test libstuff.a
或者使用
gcc src/project/test.c -o test -lstuff -Llibfolder
-L 将libfolder 添加到完成库搜索的文件夹列表中。库的文件夹搜索顺序类似于#include 处理所发生的情况。
回去制作
我将展示一个最小的示例,说明如何在 Linux Ubuntu 20 下使用 C 语言构建和使用静态库,并通过一个非常短的 makefile 管理其使用。
这是最小的,仅用于演示目的。有更好的方法来写这个,但我希望这样写会让你更容易遵循逻辑。
注意:ar 是Linux 中的存档器,就像Windows 中的LIB。管理库创建的程序。
示例
把这4个文件放在一个文件夹里
Makefile myLib.c myLib.h testing.c
我们想从myLib.c 构建一个库libmyLib.a 并在testing 中使用它
C 源代码
对于图书馆:
// myLib.h
int twice(int);
// myLib.c
#include <stdio.h>
int twice(int value) { return value + value; }
测试程序
// testing.c
#include <stdio.h>
#include "myLib.h"
int main(void)
{ int x = 42;
printf("x = %d, twice(%d) = %d\n", x, x, twice(x) );
return 0;
}
测试输出
testing 只是调用twice(42) 并输出84
x = 42, twice(42) = 84
使用makefile
我们想输入 make 并构建 libmyLib.a,编译 testing.c 并生成 testing。
类似的东西(make 输出现在被抑制):
so_user@DSK-2009:~/projects/so0802$ ls -ltr
total 32
-rw-r--r-- 1 so_user so_user 266 Aug 2 17:46 Makefile
-rw-r--r-- 1 so_user so_user 26 Aug 2 18:23 myLib.h
-rw-r--r-- 1 so_user so_user 155 Aug 2 18:23 testing.c
-rw-r--r-- 1 so_user so_user 79 Aug 2 18:23 myLib.c
so_user@DSK-2009:~/projects/so0802$ make
// supressed output //
so_user@DSK-2009:~/projects/so0802$ ls -ltr
total 44
-rw-r--r-- 1 so_user so_user 266 Aug 2 17:46 Makefile
-rw-r--r-- 1 so_user so_user 26 Aug 2 18:23 myLib.h
-rw-r--r-- 1 so_user so_user 155 Aug 2 18:23 testing.c
-rw-r--r-- 1 so_user so_user 79 Aug 2 18:23 myLib.c
-rw-r--r-- 1 so_user so_user 1792 Aug 2 18:42 testing.o
-rw-r--r-- 1 so_user so_user 1368 Aug 2 18:42 myLib.o
-rw-r--r-- 1 so_user so_user 1510 Aug 2 18:42 libmyLib.a
-rwxr-xr-x 1 so_user so_user 16760 Aug 2 18:42 testing
so_user@DSK-2009:~/projects/so0802$ ./testing
x = 42, twice(42) = 84
so_user@DSK-2009:~/projects/so0802$
make 是一个非常聪明的程序,它考虑了文件的最后修改时间,是的,使 内容保持最新。 make 基于所谓的 makefile,其名称默认为 Makefile。在 makefile 中要更新的东西称为targets。
makefile,即使是一个简短的项目,也可能是一件复杂的事情。但总比不使用要容易。
make 运行会做什么?
您可以将所谓的targets 呈现给make。如果您只输入make,程序将搜索名为Makefile 的文件,并在该文件中搜索名为all 的目标。
下面的第一个命令只更新库,而第二个将尝试目标all
make libMylib.a
make
make -n
您可以随时尝试-n 和make 将列出程序将执行哪些更新目标。
按照上面的例子...
so_user@DSK-2009:~/projects/so0802$ make -n
make: Nothing to be done for 'all'.
so_user@DSK-2009:~/projects/so0802$
由于目标都已更新。现在假设 testing.c 已更改:
so_user@DSK-2009:~/projects/so0802$ touch testing.c
so_user@DSK-2009:~/projects/so0802$ ls -ltr
total 44
-rw-r--r-- 1 so_user so_user 266 Aug 2 17:46 Makefile
-rw-r--r-- 1 so_user so_user 26 Aug 2 18:23 myLib.h
-rw-r--r-- 1 so_user so_user 79 Aug 2 18:23 myLib.c
-rw-r--r-- 1 so_user so_user 1792 Aug 2 18:42 testing.o
-rw-r--r-- 1 so_user so_user 1368 Aug 2 18:42 myLib.o
-rw-r--r-- 1 so_user so_user 1510 Aug 2 18:42 libmyLib.a
-rwxr-xr-x 1 so_user so_user 16760 Aug 2 18:42 testing
-rw-r--r-- 1 so_user so_user 155 Aug 2 18:57 testing.c
so_user@DSK-2009:~/projects/so0802$ make -n
gcc -c -Wall testing.c
gcc -o testing testing.o libmyLib.a
so_user@DSK-2009:~/projects/so0802$
你看到了,因为testing.c比较新,但是由于库没有改变,我们需要编译程序并将它与库链接:
-rw-r--r-- 1 toninho toninho 266 Aug 2 17:46 Makefile
-rw-r--r-- 1 toninho toninho 26 Aug 2 18:23 myLib.h
-rw-r--r-- 1 toninho toninho 79 Aug 2 18:23 myLib.c
-rw-r--r-- 1 toninho toninho 1368 Aug 2 18:42 myLib.o
-rw-r--r-- 1 toninho toninho 1510 Aug 2 18:42 libmyLib.a
-rw-r--r-- 1 toninho toninho 155 Aug 2 18:57 testing.c
-rw-r--r-- 1 toninho toninho 1792 Aug 2 19:00 testing.o
-rwxr-xr-x 1 toninho toninho 16760 Aug 2 19:00 testing
但现在我们更改myLib.c 并尝试make -n:
so_user@DSK-2009:~/projects/so0802$ touch myLib.c
so_user@DSK-2009:~/projects/so0802$ make -n
gcc -c -Wall testing.c
gcc -c -Wall myLib.c
ar rcs libmyLib.a myLib.o
gcc -o testing testing.o libmyLib.a
so_user@DSK-2009:~/projects/so0802$
由于库改变了,头文件也可能改变了,所以我们也需要编译testing.c。并调用ar 重建库,然后生成新的testing 可执行文件。
这里使用的makefile
all: testing
clean:
rm *.o
rm *.a
rm testing
testing: testing.o libmyLib.a
gcc -o testing testing.o libmyLib.a
testing.o: testing.c myLib.c myLib.h
gcc -c -Wall testing.c
myLib.o: myLib.c myLib.h
gcc -c -Wall myLib.c
libmyLib.a: myLib.o
ar rcs libmyLib.a myLib.o
我希望大家对make 的情况有所了解。请随时回问。
: 之前的东西是目标
-
clean 目标很常见,您在这里看到它只是删除了一些东西
- 目标之后列出的内容称为依赖项,这很有意义:如果任何依赖项比目标更新,则运行依赖项行下方的命令。
-
make 在搜索要更新的目标时深度递归