Boost logo

Boost-Build :

Subject: Re: [Boost-build] Dependency on shared library from static library (mixing shared and static libs)
From: Johan Nilsson (r.johan.nilsson_at_[hidden])
Date: 2009-02-05 03:59:17


"Alexander Sack" <pisymbol_at_[hidden]> skrev i meddelandet
news:3c0b01820902040708g570a31b0h89dfcf4ab948429a_at_mail.gmail.com...
> On Wed, Feb 4, 2009 at 9:35 AM, Johan Nilsson <r.johan.nilsson_at_[hidden]>
> wrote:
>>>> Well, obviously a static lib can't be linked (at least not with msvc).
>>>> Hence
>>>> the "... _reference_ the shared build of a" (which could be even more
>>>> specific by stating "contains references to the functions exported by
>>>> the
>>>> shared build of a", perhaps).
>
> At least with gcc toolchain that worked fine for me.
>
>>> Do you still have the issue though?
>>
>> Yes. Your suggested solution generates both shared and static versions of
>> "a", and passes both as linker inputs for msvc. See below for relevant
>> part
>> of output using "bjam -d+2"
>
> Yes that's true too for gcc. However the final binary is c is
> depedent on the shared library a which is what you want. The rule you
> gave makes liba shared when the main target is always built as per:
>
> http://www.boost.org/doc/tools/build/doc/html/bbv2/advanced/targets.html
>
> Other than the fact that bjam builds both versions of the library, I
> guess I fail to see the real issue (at least with gcc since I have not
> tried msvc). If you build with link=static you get a static binary
> and static libraries, if you build link=shared, you get a static libb,
> a shared liba, and c exe/binary that has symbols linked in from static
> archive and depends on shared library.

I've modified the sample a bit (see attached indirect_usage_of_a.zip). This
is basically your Jamroot, but the c++ code now outputs some tracing
statements and runs the executable using the unit-test rule, showing whether
shared or static library version of a() is called. This is the output I get
when executing bjam link=shared:

---
main: calling b_call_a:
in b_call_a()
in a() (static lib)
---
Result: static library version of a is used (but both static and shared 
versions of a are built).
When modifying c.cpp to directly call a() (see attached 
direct_usage_of_a.zip), I get the following output:
---
main: calling b_call_a:
in b_call_a()
in a() (shared lib)
main: calling a
in a() (shared lib)
---
Result: shared library version of a is used (but both static and shared 
versions of a are built).
I see a couple of problems with how this works:
- When declaring target c you'll need to know that b uses a (and manually
add a to the sources for c as well), _even_ if c does not directly use 
anything
defined in "a". IMHO this breaks encapsulation and somehow voids the
usage-requirements feature - which is one big reason for me to use
Boost.Build. Breaks the principle of least surprise, at least for me.
- It causes both static and shared versions of a to be built, even though
the static version isn't actually used. For such a small project with small
libraries that build fast it's not a big deal, but I'm having this
requirement in a real project where building the static library in question
from scratch takes some ~15-20 minutes. I only tried to illustrate my
problem using a small project.
- When I specify link=shared, I expect all direct and indirect library
dependencies to be built for shared linking if they support it. It doesn't
make sense that one dependency/target along the way propagates its own
"deficiency" (able to build as a static library only) to its own
dependencies. I do realize that mixing shared and static libraries can
potentially lead to problems, but in this case (static lib uses methods in
shared) I can't see the problem, at least not in my specific use case.
This is how I would expect it to work:
--- (modified) Jamroot ---
import testing ;
project foo ;
# can be built as static or shared library
lib a
  : a.cpp
  : <link>shared:<define>A_BUILD_DLL
  :
  : <link>shared:<define>A_USE_DLL
  ;
# can only be built as static library
lib b : b.cpp : <link>static <use>a : : <library>a ;
unit-test c : c.cpp : <library>b ;
---
Running bjam link=shared should _not_ produce static version of "a" (but 
does) and output the followin (but does not):
---
main: calling b_call_a:
in b_call_a()
in a() (shared lib)
---
By adding "<library>a" to the requirements of target "c", I get the desired 
output (but breaks encapsulation). No matter what I do, a static lib version 
of a is always produced as a "side effect".
Help, anyone?
/ Johan
begin 666 indirect_usage_of_a.zip
M4$L#!!0````(`(I*13IPU5_1C0```+0````%````8RYC<'!-B\T*`B$<Q,\)
MOL,?][(;T0.8=)$]=+8_at_B!"_: 77!5=/T;NGP4(PAYG?S'0^FE"L`Z*/$\&H
MVS+SRYJ34_/Y'YHUV^!U91CYF&%6/O;-',!,*NWA\1PP>F.TJT-*S5(R, :$
MJQ!\?(&6ICJI*&GXMW'1AE,];%4_M%257"XIPGB_7*6X<3X*49L/1E]02P,$
M% ````@`;TI%.MQF_at_F""````P ````4```!A+F-P<'6,L0K",!"&9P_N'8YT
M:1<?H!9!Z5+HZEQB[DH/8@)-ZB*^NT9P[/CS?=]?:7!^8R%CCXM!J/Z[TYCR
M*O9Q1D!X1F6R=8/P*L[,,M-ENMZ&L9_Z<40XI,QMZ^*6J>O(:"@VU6FQJS!Y
MO3>F@)\E@?WI>R,^R7Z9;5:W5P;6&>&-\ %02P,$% ````@`<DI%.K%D94UG
M````N ````,```!A+FA3SDQ32$E-R\Q+35'0<(QW"O7T<8EW\?'1Y.52YH1(
M*#C&N[@Z^RC$QZ>D)N<4%Z0F:Z3DY*16%.07E8"4I>:@FA$:[$J4"9FY"!.*
M4S%4@\3S4C+3>+EXN<KR,U-_at_AB1J:%KS<@$`4$L#!!0````(`*-*13I COH4
M7P```((````%````8BYC<'!3SLQ+SBE-25502M++4.+E4H;S$U'Y-IGYQ25%
MJ8FY=KQ<O%QE^9DI"DGQR8DY.?&)&IJ\7-6\7)S%)2E65LGYI24*-C8*2IEY
M2 J40$)@^=2\E!QKH&*@()"JY>4"`%!+`P0*``````!L2D4Z\_;/61(````2
M`````P```&(N:'9O:60_at_8E]C86QL7V$H*3L-"E!+`P04````" `*3$4ZN_at_MV
M%J4````?`0``!P```$IA;7)O;W1]D$$*PC 01?>!W.&#:SV EH)2%T)WTG5)
MTE2C-0G)=-';FS:("N+N,_/XO!GS\"X02$<R]H(=9YSYX&Y:$7KG\F %)2RD
MAAS-0! 1D009!1<0KR+H#H.1082)LQ0_at_. .V$!OE?8[%8.R]S.RVZ'1OK"[W
M[:$YU55;U?5"_46;\_$%?C_at_[hidden]_Q+YT9&J5LPO$NS]S2]5H#:WG#T"EO5K(
M=,2\? )02P$"% L4````" "*2D4Z<-5?T8T```"T````!0`````````!`" `
M````````8RYC<'!02P$"% L4````" !O2D4ZW&:"8((```# ````!0``````
M```!`" ```"P````82YC<'!02P$"% L4````" !R2D4ZL61E36<```"X````
M`P`````````!`" ```!5`0``82YH4$L!`A0+% ````@`HTI%.D".^A1?````
M@@````4``````````0`@````W0$``&(N8W!P4$L!`A0+"@``````;$I%.O/V
MSUD2````$@````,``````````0`@````7P(``&(N:%!+`0(4"Q0````(``I,
M13JZ"W86I0```!\!```'``````````$`( ```)("``!*86UR;V]T4$L%!@``
0```&``8`, $``%P#````````
`
end
begin 666 direct_usage_of_a.zip
M4$L#!!0````(``I,13JZ"W86I0```!\!```'````2F%M<F]O='V000K",!!%
M]X'<X8-K/8"6_at_E(70G?2=4G25*,U"<ETT=N;-H@*XNXS\_B\&?/P+A!(1S+V
M_at_AUGG/G@;EH1>N?R8 4E+*2&',U $!&1!!D%%Q"O(N_at_.@Y%!A(FS%" X`[80
M&^5]CL5@[+W,[+;H=&^L+O?MH3G555O5]4+]19OS\05^.#D[3+_$OG1D:I6S
M"\2[/W-+U6_at_-K></0*6]6LATQ+Q\`E!+`P04````" !O2D4ZW&:"8((```# 
M````!0```&$N8W!P=8RQ"L(P$(9G#^X=CG1I%Q^@%D'I4NCJ7&+N2@]B`DWJ
M(KZ[1G#L^/-]WU]I<'YC(6./BT&H_KO3F/(J]G%&0'A&9;)U@_ JSLPRTV6Z
MWH:QG_IQ1#BDS&WKXI:IZ\AH*#;5:;&K,'F]-Z: GR6!_>E[(S[)?IEM5K=7
M!M89X8WP`5!+`P04````" !R2D4ZL61E36<```"X`````P```&$N:%/.3%-(
M24W+S$M-4=!PC'<*]?1QB7?Q\='DY5+FA$@H.,:[N#K[*,3'IZ0FYQ07I"9K
MI.3DI%84Y!>5@)2EYJ":$1KL2I0)F;D($XI3,52#Q/-2,M-XN7BYRO(S4V"&
M)&IH6O-R`0!02P,$% ````@`HTI%.D".^A1?````@@````4```!B+F-P<%/.
MS$O.*4U)55!*TLM0XN52AO,34?DVF?G%)46IB;EVO%R\7&7YF2D*2?')B3DY
M\8D:FKQ<U;Q<G,4E*596R?FE)0HV-_at_I*F7E("I1 0F#YU+R4'&N_at_8J @D*KE
MY0(`4$L#! H``````&Q*13KS]L]9$@```!(````#````8BYH=F]I9"!B7V-A
M;&Q?82_at_[hidden]*4$L#!!0````(`(=,13H68+5QI@```!(!```%````8RYC<'!M
MC4$+@C 8AL\-]A\^YD4C^P%3NHB'SA8$&3+GR,'\A#E/T7]OBXJD8(?W??<\
M?)%&:>9.`1/;GE$2?7J[[+D>)V>5&';?HYQ<9W3K-THT.AB$QCB$#<A>V#6<
M+PDE-TI6'N1<CK.#/ >6IFF-`>8_at_A3$:K] V(36"U\@R+[Q[G&0_^M(4+^,O
MZB^Q$)ZKPLX$Q#^KW&P1RM/^T%3'HBBKRO_<*7D`4$L!`A0+% ````@`"DQ%
M.KH+=A:E````'P$```<``````````0`@`````````$IA;7)O;W102P$"% L4
M````" !O2D4ZW&:"8((```# ````!0`````````!`" ```#*````82YC<'!0
M2P$"% L4````" !R2D4ZL61E36<```"X`````P`````````!`" ```!O`0``
M82YH4$L!`A0+% ````@`HTI%.D".^A1?````@@````4``````````0`@````
M]P$``&(N8W!P4$L!`A0+"@``````;$I%.O/VSUD2````$@````,`````````
M`0`@````>0(``&(N:%!+`0(4"Q0````(`(=,13H68+5QI@```!(!```%````
I``````$`( ```*P"``!C+F-P<%!+!08`````!@`&`# !``!U`P``````
`
end

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