Boost logo

Boost-Build :

Subject: Re: [Boost-build] Linking static library against shared library
From: Anthony Foglia (AFoglia_at_[hidden])
Date: 2010-05-14 11:15:29


Gevorg Voskanyan wrote:
> Anthony Foglia wrote:
>> We're trying to build our custom libraries statically, but they use librt, which
>> (on Ubuntu Intrepid) apparently needs to be linked dynamically. Our jam
>> file for the library looks like:
>
>
>> lib utilities
>> : [ glob src/*.cpp ]
>> /sysdefs//boost-program-options
>> /sysdefs//boost-filesystem
>> /sysdefs//lib-real-time
>> : <include>./include
>> <link>static
>> :
>> : <include>./include
>> <link>static
>> ;
>
> Do you really want to force other libraries that happen to use lib utilities to become statically linked?

Yes. It's only used by our code, and we try to have our executables are
pegged to a single version of the repository. Plus for our production
runs, the final production run, we want as much statically linked as
possible. (We're building a trading algorithm that are running on
computers administered by the order execution people, so the simpler to
install, the better.)

>> And librt is defined as lib-real-time in a file sysdefs.jam with the following lines:
>>
>> lib lib-real-time #FOR: librt (implicit for threading)
>> :
>> : <threading>single <name>rt
>> ;
>>
>> alias lib-real-time : : ;
>>
>> Compiling a simple test program, this links librt statically,
>> which fails (undefined reference to `_dl_cpuclock_offset').
>>
>> Now I would think the correct change would be to change the first lib-real-time definition to reflect that librt
>> must be linked dynamically, like so
>>
>> lib lib-real-time #FOR: librt (implicit for threading)
>> :
>> : <threading>single <name>rt : : <link>shared
>> ;
>>
>> But this causes libutilites to be linked to dynamically (libutilities.so is created).
>> Despite using <link>static in the requirements and the usage requirements of utilities,
>> for some reason bjam is ignoring them and still wants to build utilities shared.
>
> This is because you specified <link>shared in the usage requirements section of lib-real-time, so it becomes a requirement for libutilities which uses lib-real-time.

But, I've also put <link>static in the requirements for utilities. Why
should the usage requirements of a source _override_ the requirements of
the dependent target? I could understand if I get an error saying they
conflicted, and a failure to build. At least then you'd find the error
earlier. But that doesn't happen. What are "requirements" if not required?

> Just move it to the requirements section like this:
>
> lib lib-real-time #FOR: librt (implicit for threading)
> :
> : <threading>single <name>rt <link>shared
> ;

I had tried that, and that doesn't work either. In that case, librt
doesn't appear in the linker command at all, and I get undefined
references. Here's the linker command for a test program I made:

--==--

     "g++" -L"/usr/lib64" -Wl,-R -Wl,"/usr/lib64" -Wl,-rpath-link
-Wl,"/usr/lib64" -o
"utilities/tests/RealTimeStopWatch-01/bin/RealTimeStopWatch-01.test/gcc-4.3.2/release/debug-symbols-on/tree-vec-off/RealTimeStopWatch-01"
-Wl,--start-group
"utilities/tests/RealTimeStopWatch-01/bin/RealTimeStopWatch-01.test/gcc-4.3.2/release/debug-symbols-on/tree-vec-off/testMain.o"
"utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/libutilities.a"
  -Wl,-Bstatic -lboost_filesystem -lboost_system -Wl,-Bdynamic
-Wl,--end-group -g

--==--

I need a "-lrt" after the -Wl,-Bdynamic to get it to compile.

The link command (and output) for the original, with "<link>shared" in
the definition of lib-real-time is:

--==--

"g++" -L"/usr/lib64" -Wl,-R -Wl,"/usr/lib64" -Wl,-rpath-link
-Wl,"/usr/lib64" -o
"utilities/tests/RealTimeStopWatch-01/bin/RealTimeStopWatch-01.test/gcc-4.3.2/release/debug-symbols-on/tree-vec-off/RealTimeStopWatch-01"
-Wl,--start-group
"utilities/tests/RealTimeStopWatch-01/bin/RealTimeStopWatch-01.test/gcc-4.3.2/release/debug-symbols-on/tree-vec-off/testMain.o"
"utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/libutilities.a"
  -Wl,-Bstatic -lrt -lboost_filesystem -lboost_system -Wl,-Bdynamic
-Wl,--end-group -g

/usr/lib64/librt.a(clock_gettime.o): In function `hp_timing_gettime':
(.text+0x6a): undefined reference to `_dl_cpuclock_offset'
collect2: ld returned 1 exit status

--==--

If I put <link>shared in the usage requirements of lib-real-time, I get:

--==--

gcc.link.dll
utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/libutilities.so

     "g++" -L"/usr/lib64" -o
"utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/libutilities.so"
-Wl,-h -Wl,libutilities.so -shared -Wl,--start-group
"utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/FaultHandling.o"
"utilities/bin/gcc-4.3.2/release/debug-symbols-on/link-static/tree-vec-off/Path.o"
  -Wl,-Bstatic -lrt -lboost_filesystem -lboost_system -Wl,-Bdynamic
-Wl,--end-group -g

/usr/bin/ld: /usr/lib64/libboost_system.a(error_code.o): relocation
R_X86_64_32 against `a local symbol' can not be used when making a
shared object; recompile with -fPIC
/usr/lib64/libboost_system.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

--==--

It's trying to build a shared library, by linking statically to the sources.

I've pared the code down to a handful of files. I'll ask for permission
to send a tarball to the list.

> Also I think you can get away with just one alternative of lib-real-time if it is defined as
>
> lib lib-real-time
> :
> : <link>shared <threading>single:<name>rt
> ;
>
> and then "alias lib-real-time : : ;" would no longer be needed.

Probably. But it also might end up trying to link to a library named
lib-real-time in multithreaded builds. The documentation is not clear.
  Those lines were written a while ago and have been working, and I'm
not eager to go looking for trouble trying to change them.

-- 
Anthony Foglia
Princeton Consultants
(609) 987-8787 x233

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk