public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Linking dependencies into static library / Partial linking
@ 2008-01-08 13:26 Philip K.F. Hölzenspies
  2008-01-10 19:23 ` Nick Clifton
  0 siblings, 1 reply; 6+ messages in thread
From: Philip K.F. Hölzenspies @ 2008-01-08 13:26 UTC (permalink / raw)
  To: binutils

L.S.,

This may be a newbe question and it may already have been answered on this 
mailing lists, in which case I may have used the wrong search terms. If this 
is the case, I would be very satisfied with a reference to the relevant 
thread. The problem is the following.

I am currently developing a program in C called RTSM. Someone else has written 
a program, called HEBE, in C++. RTSM should use some of the code from HEBE. 
To develop independently, I would like to write a C wrapper for HEBE and 
compile HEBE with this wrapper to a static library to which I could link my 
RTSM. For reasons I will not bore you with too much, I would really like to 
have HEBE as a single static library with no further link dependencies. HEBE 
links with glpk, so I would like to link in libglpk.a in some way. When I 
compile HEBE as

gcc <misc_options> -lglpk *.cc -o hebe.o

the resulting object file still contains undefined symbols from glpk, i.e. nm 
reports (randomly selected line for example):

U _glp_lpx_add_cols

whereas "nm /usr/local/lib/libglpk.a | grep x_add_cols" outputs:

         U _glp_lpx_add_cols
         U _glp_lpx_add_cols
00001020 T _glp_lpx_add_cols
         U _glp_lpx_add_cols
         U _glp_lpx_add_cols
         U _glp_lpx_add_cols
         U _glp_lpx_add_cols

I would expect there to be some "XXX T _glp_lpx_add_cols" in hebe.o, but there 
isn't.

In the end, I would really like to have a libhebe.a file that only exports the 
symbols of the wrapper AND does not contain unresolved / undefined symbols 
that impose linker dependencies. Is this at all possible?

Regards,
Philip

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linking dependencies into static library / Partial linking
  2008-01-08 13:26 Linking dependencies into static library / Partial linking Philip K.F. Hölzenspies
@ 2008-01-10 19:23 ` Nick Clifton
  2008-01-12 19:40   ` Philip K.F. Hölzenspies
  0 siblings, 1 reply; 6+ messages in thread
From: Nick Clifton @ 2008-01-10 19:23 UTC (permalink / raw)
  To: "Philip K.F. Hölzenspies"; +Cc: binutils

Hi Philip,

> In the end, I would really like to have a libhebe.a file that only exports the 
> symbols of the wrapper AND does not contain unresolved / undefined symbols 
> that impose linker dependencies. Is this at all possible?

What you want is partial linking.  See the description of the --relocatable 
linker command line switch in the linker manual.  Couple that with whole 
archive linking and you should get the result you want.  ie something like this 
will probably work:

   % gcc *.cc wrapper.o -Wl,--whole-archive -lglpk -Wl,--no-whole-archive
     -Wl,--relocatable -o hebe.o

Cheers
   Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linking dependencies into static library / Partial linking
  2008-01-10 19:23 ` Nick Clifton
@ 2008-01-12 19:40   ` Philip K.F. Hölzenspies
  2008-01-13  7:52     ` Dave Korn
  0 siblings, 1 reply; 6+ messages in thread
From: Philip K.F. Hölzenspies @ 2008-01-12 19:40 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 3153 bytes --]

On Wednesday 09 January 2008 16:58:41 Nick Clifton wrote:
> Hi Philip,
>
> > In the end, I would really like to have a libhebe.a file that only
> > exports the symbols of the wrapper AND does not contain unresolved /
> > undefined symbols that impose linker dependencies. Is this at all
> > possible?
>
> What you want is partial linking.  See the description of the --relocatable
> linker command line switch in the linker manual.  Couple that with whole
> archive linking and you should get the result you want.  ie something like
> this will probably work:
>
>    % gcc *.cc wrapper.o -Wl,--whole-archive -lglpk -Wl,--no-whole-archive
>      -Wl,--relocatable -o hebe.o
>
> Cheers
>    Nick


Dear Nick, All,

Thanks for the advice. However, I had already come across this option and not 
understood it earlier. I thought the --whole-archive would maybe prove to 
help me out, but it didn't. Because I want to avoid being sketchy, I took the 
liberty of creating a minimal example of where I don't understand ld's 
behaviour (on two counts).

Please see the files attached. To avoid stripped attachments, I figured I 
would also make this example available on my web-space. If you don't receive 
this e-mail with attachments, please see

www.cs.utwente.nl/~holzensp/ldtest.tgz

When running "make allcpp" you'll notice that the functions in cwrapper.cc and 
foo.h aren't found by the linker:

g++ -L. bar.c -lfoo -o bar
/tmp/cc6lYrCK.o: In function `main':
bar.c:(.text+0x12): undefined reference to `newFoo()'
bar.c:(.text+0x1a): undefined reference to `newFoo()'
bar.c:(.text+0x28): undefined reference to `doFoo(CFoo*)'
bar.c:(.text+0x33): undefined reference to `doFoo(CFoo*)'
bar.c:(.text+0x3e): undefined reference to `freeFoo(CFoo*)'
bar.c:(.text+0x49): undefined reference to `doFoo(CFoo*)'
bar.c:(.text+0x54): undefined reference to `freeFoo(CFoo*)'

However, "nm libfoo.a" disagrees:

holzensp@ewi1043:~/tmp/ldtest> nm libfoo.a

foo.o:
00000180 t _GLOBAL__I__ZN4CFooC2Ev
         U _Unwind_Resume
00000140 t _Z41__static_initialization_and_destruction_0ii
0000001c T _ZN4CFoo5doFooEv
0000000e T _ZN4CFooC1Ev
00000000 T _ZN4CFooC2Ev
000001b0 T _ZN4CFooD1Ev
000001f2 T _ZN4CFooD2Ev
         U _ZNKSs4sizeEv
         U _ZNKSsixEj
         U _ZNSolsEi
         U _ZNSt8ios_base4InitC1Ev
         U _ZNSt8ios_base4InitD1Ev
00000034 t _ZSt17__verify_groupingPKcjRKSs
00000000 W _ZSt3minIjERKT_S2_S2_
         U _ZSt4cout
00000000 b _ZSt8__ioinit
         U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
         U _ZdlPv
         U _Znwj
         U __cxa_atexit
         U __dso_handle
         U __gxx_personality_v0
0000019c t __tcf_0
0000025e T doFoo
00000234 T freeFoo
00000272 T newFoo


Notice that the names are, indeed, unmangled, so the difference between the C 
and C++ interpretations of the CFoo type should not be an issue.

When running "make all" (using gcc instead of g++ for the compilation and 
linking of the C source to the library), the linker also wants to resolve 
stuff from the stdc++ library. I had hoped to have linked those in already.

Does this make any sense? Am I doing something wrong?

Regards,
Philip

[-- Attachment #2: ldtest.tgz --]
[-- Type: application/x-tgz, Size: 1908 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Linking dependencies into static library / Partial linking
  2008-01-12 19:40   ` Philip K.F. Hölzenspies
@ 2008-01-13  7:52     ` Dave Korn
  2008-01-14 16:41       ` Philip K.F. Hölzenspies
  0 siblings, 1 reply; 6+ messages in thread
From: Dave Korn @ 2008-01-13  7:52 UTC (permalink / raw)
  To: 'Philip K.F. Hölzenspies', 'Nick Clifton'; +Cc: binutils

On 11 January 2008 17:04, Philip K.F. Hölzenspies wrote:

> When running "make allcpp" you'll notice that the functions in cwrapper.cc
> and foo.h aren't found by the linker:
> 
> g++ -L. bar.c -lfoo -o bar
> /tmp/cc6lYrCK.o: In function `main':
> bar.c:(.text+0x12): undefined reference to `newFoo()'
> bar.c:(.text+0x1a): undefined reference to `newFoo()'
> bar.c:(.text+0x28): undefined reference to `doFoo(CFoo*)'
> bar.c:(.text+0x33): undefined reference to `doFoo(CFoo*)'
> bar.c:(.text+0x3e): undefined reference to `freeFoo(CFoo*)'
> bar.c:(.text+0x49): undefined reference to `doFoo(CFoo*)'
> bar.c:(.text+0x54): undefined reference to `freeFoo(CFoo*)'
> 
> However, "nm libfoo.a" disagrees:
> 
> holzensp@ewi1043:~/tmp/ldtest> nm libfoo.a
> 
> foo.o:
> 00000180 t _GLOBAL__I__ZN4CFooC2Ev
>          U _Unwind_Resume
> 00000140 t _Z41__static_initialization_and_destruction_0ii
> 0000001c T _ZN4CFoo5doFooEv
> 0000000e T _ZN4CFooC1Ev
> 00000000 T _ZN4CFooC2Ev
> 000001b0 T _ZN4CFooD1Ev
> 000001f2 T _ZN4CFooD2Ev
>          U _ZNKSs4sizeEv
>          U _ZNKSsixEj
>          U _ZNSolsEi
>          U _ZNSt8ios_base4InitC1Ev
>          U _ZNSt8ios_base4InitD1Ev
> 00000034 t _ZSt17__verify_groupingPKcjRKSs
> 00000000 W _ZSt3minIjERKT_S2_S2_
>          U _ZSt4cout
> 00000000 b _ZSt8__ioinit
>          U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
>          U _ZdlPv
>          U _Znwj
>          U __cxa_atexit
>          U __dso_handle
>          U __gxx_personality_v0
> 0000019c t __tcf_0
> 0000025e T doFoo
> 00000234 T freeFoo
> 00000272 T newFoo
> 
> 
> Notice that the names are, indeed, unmangled, so the difference between the
> C and C++ interpretations of the CFoo type should not be an issue.

  I disagree.  Add "--save-temps" to the commandline:

g++ --save-temps -L. bar.c -lfoo -o bar

then look at the symbols required by bar.o:

/artimi/software/firmware/build/ldtest $ nm bar.o
00000000 b .bss
00000000 d .data
00000000 t .text
         U __Z5doFooP4CFoo
         U __Z6newFoov
         U __Z7freeFooP4CFoo
         U ___main
         U __alloca
00000000 T _main

  It's looking for the mangled versions; the library, as you point out, has
only unmangled versions.  If you change the start of bar.c from:

   ...snip...
#include "foo.h"

int main () {
   ...snip...

to this:

   ...snip...
extern "C" {
#include "foo.h"
}

int main () {
   ...snip...


it will link ok.  (Don't forget to manually pass 'this' as the first arg when
calling C++ non-static class member functions from C, of course.)



    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linking dependencies into static library / Partial linking
  2008-01-13  7:52     ` Dave Korn
@ 2008-01-14 16:41       ` Philip K.F. Hölzenspies
  2008-01-14 19:05         ` Dave Korn
  0 siblings, 1 reply; 6+ messages in thread
From: Philip K.F. Hölzenspies @ 2008-01-14 16:41 UTC (permalink / raw)
  To: Dave Korn; +Cc: 'Nick Clifton', binutils

Dear David, All,

On Friday 11 January 2008 18:12:41 Dave Korn wrote:
>   It's looking for the mangled versions; the library, as you point out, has
> only unmangled versions.  If you change the start of bar.c from:

When I compile with "g++ -c bar.c" it does, indeed, give an object file with 
mangled names. This was a considerable oversight on my part. Thank you for 
pointing this out.

> extern "C" {
> #include "foo.h"
> }

I just realized, actually, that in this case there should be

#ifdef __cplusplu
  extern "C" {
#endif

in foo.h.

> it will link ok.  (Don't forget to manually pass 'this' as the first arg
> when calling C++ non-static class member functions from C, of course.)

Absolutely right, there. It was a bit of a sloppy omission when drawing up 
this minimal example. Your help has brought me to the point where I can 
actually get on with my work.

I also found an answer to the other part of my question (wanting to use 
a "plain C" compiler/linker to compile my C program, while still using this 
C++ library). Johan Petersson makes some very useful comments on the matter 
here:

http://www.trilithium.com/johan/2005/06/static-libstdc/

Regards,
Philip

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Linking dependencies into static library / Partial linking
  2008-01-14 16:41       ` Philip K.F. Hölzenspies
@ 2008-01-14 19:05         ` Dave Korn
  0 siblings, 0 replies; 6+ messages in thread
From: Dave Korn @ 2008-01-14 19:05 UTC (permalink / raw)
  To: 'Philip K.F. Hölzenspies'; +Cc: 'Nick Clifton', binutils

On 14 January 2008 08:49, Philip K.F. Hölzenspies wrote:

> Dear David, All,
> 
> On Friday 11 January 2008 18:12:41 Dave Korn wrote:
>>   It's looking for the mangled versions; the library, as you point out, has
>> only unmangled versions.  If you change the start of bar.c from:
> 
> When I compile with "g++ -c bar.c" it does, indeed, give an object file with
> mangled names. This was a considerable oversight on my part. Thank you for
> pointing this out.

  See also the '-x' option, as in "g++ -c -x c bar.c".

> I also found an answer to the other part of my question (wanting to use
> a "plain C" compiler/linker to compile my C program, while still using this
> C++ library). Johan Petersson makes some very useful comments on the matter
> here:
> 
> http://www.trilithium.com/johan/2005/06/static-libstdc/

  Interesting link, ta!


    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-01-14 11:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-08 13:26 Linking dependencies into static library / Partial linking Philip K.F. Hölzenspies
2008-01-10 19:23 ` Nick Clifton
2008-01-12 19:40   ` Philip K.F. Hölzenspies
2008-01-13  7:52     ` Dave Korn
2008-01-14 16:41       ` Philip K.F. Hölzenspies
2008-01-14 19:05         ` Dave Korn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).