gcc-u符号编译器选项
我们什么时候使用gcc-u编译器选项? 你能再举个例子吗 他说: 假设符号未定义,以强制链接库 模块来定义它。您可以在不同的情况下多次使用“-u” 强制加载附加库模块的符号gcc-u符号编译器选项,c,gcc,compiler-flags,C,Gcc,Compiler Flags,我们什么时候使用gcc-u编译器选项? 你能再举个例子吗 他说: 假设符号未定义,以强制链接库 模块来定义它。您可以在不同的情况下多次使用“-u” 强制加载附加库模块的符号 通常,在对象链接期间,将搜索提供的模块(即,来自已编译归档文件和其他对象文件的模块)以查找未定义的符号,并且仅从提供的模块中提取所需的符号,以最低限度地满足整组未定义的符号 这在实践中意味着,如果在对象文件中有一个函数foo(),除非在最终链接产品的其他地方使用foo(),否则将不包括它。这通常是理想的行为 如果您有一个模
通常,在对象链接期间,将搜索提供的模块(即,来自已编译归档文件和其他对象文件的模块)以查找未定义的符号,并且仅从提供的模块中提取所需的符号,以最低限度地满足整组未定义的符号 这在实践中意味着,如果在对象文件中有一个函数foo(),除非在最终链接产品的其他地方使用foo(),否则将不包括它。这通常是理想的行为 如果您有一个模块提供一些功能,这些功能在最终链接产品的其他地方没有被引用,但您仍然希望包含这些功能,那么这种情况又如何呢?(例如,这些函数可能设计为直接从调试器调用)。这就是
-u
选项派上用场的地方。它有效地告诉链接器存在对foo()的不满意引用,从而触发将其包含到最终链接产品中,尽管代码中没有引用符号
例子:
foo.h:
void foo(void);
foo.c:
void foo(void) { }
B.h:
void bar(void);
B.c:
void bar(void) { }
主要条款c:
#include "foo.h"
#include "bar.h"
int main(int argc, char** argv) {
foo();
return 0;
}
建造:
gcc -c foo.c bar.c main.c
ar -r libfoo.a foo.o
ar -r libbar.a bar.o
# For macOS, replace -shared with -dylib
ld -shared main.o -L . -lfoo -lbar
nm -g --defined-only a.out
> T _main
> T _foo
# For macOS, replace -shared with -dylib
ld -shared -u _bar main.o -L . -lfoo -lbar
nm -g --defined-only a.out
> T _main
> T _foo
> T _bar
我们不使用它——几乎从不使用它。(AFAICR,在过去的30年里,我不需要使用它。)当你需要它时,你就会知道该怎么做。在那之前,别担心。GCC还有很多其他类似的选项——如果你需要做一些神秘的事情,它们是非常宝贵的,但是99.99%的时间都是不相关的。@JonathanLeffler,我现在确实需要它,我一辈子都不知道如何让它工作。我正在尝试构建一个动态库,该库在头文件中有一个函数,需要来自静态库的单个符号,但是由于它在头文件中,它不会自动为我链接静态库,因为从技术上讲,当我编译库时,符号还没有被使用。这意味着我的库的客户必须知道如何链接静态库。。。您知道如何使“-u”选项起作用吗?或者更好你有更好的解决方案吗?@tjwrona1992:我想我可能会创建一个文件
libname.c
,其中包含#include“header.h”
,然后使用通常的规则在你的平台上构建一个共享库,可能会在创建共享库的命令行上列出静态库。我不相信这会奏效;共享库从静态库调用符号可能意味着静态库必须链接到可执行文件中,共享库才能找到符号。这就是共享库和静态库的区别;您不能只按需加载静态对象。您可能需要使用:gcc-u staticlibsymbol-o prog obj1.o…-ldynamic-lstatic…
(其中libdynamic.so
或共享对象的任何内容,libstatic.a
是静态库),这可能会导致静态库中的symbolstaticlibsymbol
链接到可执行文件中,以便在运行时可供动态库使用。如果您已经尝试过了,那么您可能需要使用MCVE()在SO上提出一个新问题。它可以合理地交叉引用这个问题-我几乎说了Q&A,但这里没有正式的A。这个问题中的链接是一个古老版本的编译器。但是,您可以从上的GCC 8.2.0手册中获得大致相同的信息。