views:

14

answers:

1

I had some problems linking the static library stxxl into a shared library as outlined in my question Linking a static library into Boost Python (shared library) - Import Error

The command I was using was

g++ -Wall -pthread -march=i686 -I/home/zenna/Downloads/stxxl-1.3.0/include -include stxxl/bits/defines.h -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -I /home/zenna/local/include/ -I /usr/include/python2.6/ -fPIC -c partition.cpp -o obj/Partition_wrap.o

and to link:

g++  -shared -lboost_python -L/home/zenna/local/lib/ -L/home/zenna/Downloads/stxxl-1.3.0/lib/bk/ -Wall -pthread -L/home/zenna/Downloads/stxxl-1.3.0/lib -lstxxl -o lib/fast_parts.so obj/Partition_wrap.o 

Using nm I found the missing symbols was in the final output shared object library, but had type "U" for undefined.

I then changed the linking command to not only use -lstxxl but also add the entire archive file as another input to the linker

such that the new command was (difference at end)

++ -shared -lboost_python -L/home/zenna/local/lib/ -L/home/zenna/Downloads/stxxl-1.3.0/lib/bk/ -Wall -pthread -L/home/zenna/Downloads/stxxl-1.3.0/lib -lstxxl -o lib/fast_parts.so obj/Partition_wrap.o obj/libstxxl.a

This fixed the problem as far as I can tell.

My question is then what is the difference between using the -l flag and adding the archive as an input and why did former method result in undefined symbols?

+1  A: 

I think the problem in your case was that you specified -lstxxl before the object files. When you put libstxxl.a at the end, the symbols from it are read again and the undefined symbols are resolved. You could try moving it before obj/Partition_wrap.o and check if it will result in undefined symbols.

From man ld

ld -o /lib/crt0.o hello.o -lc

This tells ld to produce a file called output as the result of linking the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which will come from the standard search directories. (See the discussion of the -l option below.)

Some of the command-line options to ld may be specified at any point in the command line. However, options which refer to files, such as -l or -T, cause the file to be read at the point at which the option appears in the command line, relative to the object files and other file options.

Non-option arguments are object files or archives which are to be linked together. They may follow, precede, or be mixed in with command-line options, except that an object file argument may not be placed between an option and its argument.

-l namespec

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

Although it's not mentioned very clear there doesn't seem to be any difference between the 2 ways of giving the linker the files to link.

Dmitry Yudakov