典型的.a
静态库只是常规.o
对象的集合
因此,从概念上讲,您通常可以在命令行上将 替换为.a
完全相同的.o
文件列表,这些文件不需要可重定位。
例如,考虑这个最小的可运行示例:
交流
#include "a.h"
int a(void) { return 1; }
啊
#ifndef A_H
#define A_H
int a(void);
#endif
公元前
#include "b.h"
int b(void) { return 2; }
bh
#ifndef B_H
#define B_H
int b(void);
#endif
主程序
#include <assert.h>
#include <stdlib.h>
#include "a.h"
#include "b.h"
int main(void) {
assert(a() == 1);
assert(b() == 2);
return EXIT_SUCCESS;
}
编译并运行:
gcc -ggdb3 -std=c89 -Wall -Wextra -pedantic-errors -fPIC -c 'main.c' -o 'main.o'
gcc -ggdb3 -std=c89 -Wall -Wextra -pedantic-errors -fPIC -c 'a.c' -o 'a.o'
gcc -ggdb3 -std=c89 -Wall -Wextra -pedantic-errors -fPIC -c 'b.c' -o 'b.o'
ar rcs ab.a a.o b.o
gcc -ggdb3 -std=c89 -Wall -Wextra -pedantic-errors main.o ab.a -o maina.out
./maina.out
从这里我们清楚地看到,ar
简单地打包a.o
并b.o
放入ab.a
.
因此,以下命令也有效:
gcc -ggdb3 -std=c89 -Wall -Wextra -pedantic-errors main.o a.o b.o -o maina.out
由此应该希望清楚的是,通常不需要使.a
存档内的目标文件与位置无关。
例如,如果您想将它们链接到共享库中,您可以使它们与位置无关。一切都像以前一样适用:.a
只是包含它们而不修改它们。
这个答案可能也很有趣:gcc 和 ld 中与位置无关的可执行文件的 -fPIE 选项是什么?
在 Ubuntu 20.04 上测试。