Skip to content
Search

Ld:Troubleshooting

lastmod 2024-10-23created 2016-04-197 edits

A summary of problems that can occur while using ld.

undefined reference to 'xxx'

Compilation succeeds, but linking produces a link error like the following.

undefined reference to `xxx' (xxx는 함수명 또는 전역변수명)

When linking .a files, besides -l(library), you can also link them directly in the form lib(어쩌구저쩌구).a. There is no need to use the -L(path) -l(라이브러리) style. In other words,

gcc -o execfile obj1.o obj2.o obj3.o firstlib.a secondlib.a

can also be used this way.

It can be solved by changing the order in which you list them when linking. It seems the order matters in the process of finding symbols during linking.
It can also be solved as follows.

gcc -o exefile -Xlinker --start-group libmod1.a libmod2.a libmod3.a -Xlinker --end-group

-Xlinker is an option that passes the following option to the linker (ld). The linker options --start-group and --end-group do the following.

"The specified archives are searched repeatedly until no new undefined references are created."

Why is My Global or Static Constructor not Called

Explains why global variables are not called when linking statically.

Recall that a static linker’s purpose is to look through a compilation unit for symbols marked as unresolved and then copy code from a library to define the symbol. Consider what happens if your program does not directly reference any symbol in a compilation unit contained in a given library. The linker never sees an unresolved reference to code in that object file and so it assumes that no code from that particular compilation unit is used, and therefore will ignore any global or static constructors in that file as well. In order to ensure that the global or static constructors of a compilation unit are called, you must directly reference some symbol in the compilation unit object file defining the global constructor. Note that this is a reference to an object file used to build the library, not a symbol in the library file. This means that you must have knowledge of the files that were used to build the library to make this work. For example, consider a situation where you have a static library called libnode.a; and that library is made from a number of object files.

The solution is to use the --whole-archive option.

undefined hidden symbol '__init_array_end'

A link error like the following may occur.

/usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0xd): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
make: *** [libKeynect.so] Error 1

In this case, add the static library flags between -Wl,--whole-archive and -Wl,--no-whole-archive.

Static library into the shared library

Use the --whole-archive option of GCC.

$ g++ -Wl,--whole-archive some_static_lib.a -Wl,--no-whole-archive

There is also the -Wl,-all_load option for clang.

When the LD_LIBRARY_PATH environment variable cannot be set

From Ubuntu wiki help page

Note: You can only set this environment variable inside an interactive shell.
[ie a terminal ] Since Ubuntu 9.04 Jaunty Jackalope, LD_LIBRARY_PATH cannot be set in $HOME/.profile,
/etc/profile, nor /etc/environment files. You must use /etc/ld.so.conf.d/*.conf configuration files.
See Launchpad bug #366728 for more information.

How to fix it:

cd /etc/ld.so.conf.d

Make a file with the .conf extension here

sudo nano cuda.conf

Add the paths to it as two lines

/usr/local/cuda-7.5/lib64
/usr/lib/nvidia-361

Save and exit. Check with ls -l that the file has the same ownership and permissions as others in the directory, they should be:

-rw-r--r-- 1 root root

Then run

ldconfig

This doesn't set the env variable, but includes the libraries appropriately so CUDA works

Direct access to weak symbols

ld: warning: direct access in function {A} from file {B} to global weak symbol {C} from file {D} means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

When a library cannot be found but is reported as installed as a package

Advanced Package Tool#When a library cannot be found but is reported as installed as a package

See also

author Zer0 sitemap