C++ 在 linux 上链接期间出现“输出上的不可表示部分”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1521859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"Nonrepresentable section on output" error during linking on linux
提问by nagul
I get this error at the linker stage when compiling the webkit-1.1.5 package on my Ubuntu 9.04 box:
在我的 Ubuntu 9.04 机器上编译 webkit-1.1.5 包时,我在链接器阶段收到此错误:
libtool: link: gcc -ansi -fno-strict-aliasing -O2 -Wall -W -Wcast-align -Wchar-subscripts -Wreturn-type -Wformat -Wformat-security -Wno-format-y2k -Wundef -Wmissing-format-attribute -Wpointer-arith -Wwrite-strings -Wno-unused-parameter -Wno-parentheses -fno-exceptions -fvisibility=hidden -D_REENTRANT -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/directfb -I/usr/include/libpng12 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/libsoup-2.4 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -g -O2 -O2 -o Programs/.libs/GtkLauncher WebKitTools/GtkLauncher/Programs_GtkLauncher-main.o -pthread ./.libs/libwebkit-1.0.so /usr/lib/libgtk-x11-2.0.so /usr/lib/libgdk-x11-2.0.so /usr/lib/libatk-1.0.so /usr/lib/libpangoft2-1.0.so /usr/lib/libgdk_pixbuf-2.0.so -lm /usr/lib/libpangocairo-1.0.so /usr/lib/libgio-2.0.so /usr/lib/libcairo.so /usr/lib/libpango-1.0.so /usr/lib/libfreetype.so -lfontconfig /usr/lib/libgmodule-2.0.so /usr/lib/libgobject-2.0.so /usr/lib/libgthread-2.0.so -lrt /usr/lib/libglib-2.0.so -pthread
make[1]: Leaving directory `/home/nagul/build_area/webkit-1.1.5'
WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp: In function ‘NPError webkit_test_plugin_get_value(NPP_t*, NPPVariable, void*)':
WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp:221: warning: deprecated conversion from string constant to ‘char*'
WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp:224: warning: deprecated conversion from string constant to ‘char*'
WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp: In function ‘char* NP_GetMIMEDescription()':
WebKitTools/DumpRenderTree/gtk/TestNetscapePlugin/TestNetscapePlugin.cpp:260: warning: deprecated conversion from string constant to ‘char*'
/usr/bin/ld: Programs/.libs/GtkLauncher: hidden symbol `__stack_chk_fail_local' in /usr/lib/libc_nonshared.a(stack_chk_fail_local.oS) is referenced by DSO
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: ld returned 1 exit status
make[1]: *** [Programs/GtkLauncher] Error 1
make: *** [all] Error 2
I'd like some pointers on how to attack this problem, either by looking into the "hidden sybmol" error or by helping me understand what the "Nonrepresentable section on output" message from the linker actually means.
我想要一些关于如何解决这个问题的指针,要么通过查看“隐藏的 sybmol”错误,要么通过帮助我理解来自链接器的“不可表示的输出部分”消息的实际含义。
I have already checked that this is consistent behaviour that persists across a make clean;make
invocation.
我已经检查过这是在make clean;make
调用中持续存在的一致行为。
回答by phb
I've received the "nonrepresentable section on output" error when crosscompiling for ARM and some of the libraries was not correctly compiled with -fPIC. Pretty sure that's not the error here though...
在为 ARM 进行交叉编译时,我收到了“输出的不可表示部分”错误,并且某些库未使用 -fPIC 正确编译。很确定这不是这里的错误...
回答by Brian Vandenberg
My answer is specific to the combination of the hidden symbol (...) is referenced by DSO
and Nonrepresentable section on output
errors.
我的答案是特定于hidden symbol (...) is referenced by DSO
和Nonrepresentable section on output
错误的组合。
The short answer is: a symbol was marked extern
but also marked hidden (see Visibility (GCC wiki)and How To Write Shared Libraries (Ulrich Drepper)). No objects or archives were linked in to satisfy the dependency, but a shared object waslinked in with a matching symbol.
简短的回答是:一个符号被标记extern
但也被标记为隐藏(参见可见性(GCC wiki)和如何编写共享库(Ulrich Drepper))。没有对象或档案被链接到满足依赖关系,但共享对象被链接到一个匹配的符号。
You probably compiled with -fvisibility=hidden
, and whether it was a compiler-added feature (like stack protector) or something else entirely, the symbol emitted in your code overrode the default visibility of an undefined symbol reference of the same name in libc_nonshared.a
that would normally be satisfied by libc.so
.
您可能使用 进行编译-fvisibility=hidden
,无论它是编译器添加的功能(如堆栈保护器)还是其他任何东西,您代码中发出的符号会覆盖同名未定义符号引用的默认可见性,libc_nonshared.a
通常可以满足以下条件libc.so
.
You can reproduce a similar problem like this:
您可以重现类似的问题:
#include <stdio.h>
extern __attribute__((visibility ("hidden")))
FILE* open_memstream( char**, size_t* );
char* asdf;
size_t mysize;
FILE* blah() {
return open_memstream( &asdf, &mysize );
}
... then compiling it:
...然后编译它:
# with gcc 4.9.2:
~ gcc badcode.c -shared -fPIC -o libbad.so -lc
/tmp/ccC0uG80.o: In function `blah':
badcode.c:(.text+0x19): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Bad value
# with gcc 4.4.7:
~ gcc badcode.c -shared -fPIC -o libbad.so -lc
/tmp/cc2SHUFD.o: In function `blah':
badcode.c:(.text+0x26): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Nonrepresentable section on output
# with oracle solaris studio (still in Linux) 12.3:
~ cc -shared -Kpic -o /tmp/libbad.so badcode.c -lc
badcode.o: In function `blah':
badcode.c:(.text+0x32): undefined reference to `open_memstream'
/usr/bin/ld: /tmp/libbad.so: hidden symbol `open_memstream' isn't defined
/usr/bin/ld: final link failed: Nonrepresentable section on output
In short: I've forward declared the existence of a symbol, marked it hidden, then didn't link in a static library or object file that satisfied the dependency. Since it's marked hidden, the dependency mustbe satisfied, otherwise it's an invalid ELF object.
简而言之:我已经提前声明了一个符号的存在,将其标记为隐藏,然后没有链接到满足依赖关系的静态库或目标文件中。由于它被标记为隐藏,因此必须满足依赖关系,否则它是一个无效的 ELF 对象。
In my specific case, a header was going down the wrong #if
path and causing the above hidden declaration of open_memstream
.
在我的特定情况下,标头走错了#if
路并导致上述隐藏声明open_memstream
.
回答by Robert Obryk
Please try removing the -fvisibility=hidden option from the commandline. It will produce a larger object (with some unnecessary symbols, which won't matter in the end because it is an execultable), but should eliminate the problem. This is not a solution; rather a workaround. Please check (this is just a hunch) if there are no libc version mismatches between libraries and GtkLauncher.o
请尝试从命令行中删除 -fvisibility=hidden 选项。它将产生一个更大的对象(带有一些不必要的符号,最终无关紧要,因为它是可执行的),但应该可以消除问题。这不是解决方案;而是一种解决方法。请检查(这只是一种预感)库和 GtkLauncher.o 之间是否没有 libc 版本不匹配