Subject: [Boost-build] Handling of conflict between target's requirements and its dependencies' usage requirements
From: Gevorg Voskanyan (v_gevorg_at_[hidden])
Date: 2010-05-15 05:41:31
In the thread http://old.nabble.com/Linking-static-library-against-shared-library-td28552739.html, Anthony Foglia and me were looking at a case when a target's requirements and its dependency's usage requirements contained conflicting values for the same non-free feature, "link" in particular. A minimal test case is attached here.
# Content of jamroot:
lib a : a.cpp : : : <link>shared ;
lib b : b.cpp a : <link>static ;
explicit a b ;
exe e : e.cpp b ;
Here, there is a conflict between a's <link>shared usage requirement and b's <link>static requirement. An attempt to build this project with Boost.Build from Boost 1.43.0 results in the following output:
|| ...found 23 targets...
|| ...updating 15 targets...
|| common.mkdir bin
|| common.mkdir bin\msvc-8.0
|| common.mkdir bin\msvc-8.0\debug
|| common.mkdir bin\msvc-8.0\debug\threading-multi
|| compile-c-c++ bin\msvc-8.0\debug\threading-multi\e.obj
|| common.mkdir bin\msvc-8.0\debug\link-static
|| common.mkdir bin\msvc-8.0\debug\link-static\threading-multi
|| compile-c-c++ bin\msvc-8.0\debug\link-static\threading-multi\b.obj
|| compile-c-c++ bin\msvc-8.0\debug\link-static\threading-multi\a.obj
|| msvc.archive bin\msvc-8.0\debug\link-static\threading-multi\liba.lib
|| msvc.link.dll bin\msvc-8.0\debug\link-static\threading-multi\b.dll
|| msvc.manifest.dll bin\msvc-8.0\debug\link-static\threading-multi\b.dll <---- Builds b as DLL, despite its
---- <link>static requirement!
|| msvc.link bin\msvc-8.0\debug\threading-multi\e.exe
|| LINK : fatal error LNK1181: cannot open input file 'bin\msvc-8.0\debug\link-static\threading-multi\b.lib'
^ looks for b's import lib,
^ which is not present due to <link>static ?
|| call "C:\Program Files\Microsoft Visual Studio 8\VC\vcvarsall.bat" x86 >nul
|| link /NOLOGO /INCREMENTAL:NO /DEBUG /MACHINE:X86 /subsystem:console /out:"bin\msvc-8.0\debug\threading-multi\e.exe" @"bin\msvc-8.0\debug\threading-multi\e.exe.rsp"
|| if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
|| ...failed msvc.link bin\msvc-8.0\debug\threading-multi\e.exe bin\msvc-8.0\debug\threading-multi\e.pdb...
|| ...failed updating 2 targets...
|| ...updated 13 targets...
Without <link>shared in a's usage requirements the project builds statically and runs fine.
Looks like the build gets confused and enters in UB, if that term can be applied to Boost.Build :)
Should Boost.Build detect such conflicts and act appropriately?
I can only guess what's the most appropriate thing to do, though. It seems there are the following options:
1. Ignore the conflicting build properties gathered from dependencies' usage requirements and proceed with own requirements
Not sure how good this is. Silently ignoring usage requirements might be surprising.
2. Ignore the conflicting build properties from own requirements, and proceed with dependency's usage requirements.
This is unintuitive at best IMHO, and would be the last thing I would want to see in response of such conflicts.
3. Give an explicit error about the conflict and refuse to build the target (b in this case)
This seems quite reasonable to me.
4. Some other option I haven't thought of.
Or am I missing something?
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