[filesystem][iostreams][program_options] linker issues on msvc

Guys, We use boost.build not only for building boost but also to create own binary packages. For a long time I observe linker errors on msvc due to lack of usage requirements in Jamfile's. Issue is reproduced when somebody builds executable like this: exe foo : main.cpp /boost/filesystem ; #or /boost/program_options or /boost/iostreams Following trivial patch resolves these issues: Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@ project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ; @@ -17,4 +20,4 @@ <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's ; Index: libs/filesystem/build/Jamfile.v2 =================================================================== --- libs/filesystem/build/Jamfile.v2 (revision 57802) +++ libs/filesystem/build/Jamfile.v2 (working copy) @@ -11,6 +11,7 @@ project boost/filesystem : source-location ../src : usage-requirements # pass these requirement to dependents (i.e. users) + <library>/boost/system <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1 <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1 ; @@ -29,4 +30,4 @@ : ; Index: libs/iostreams/build/Jamfile.v2 =================================================================== --- libs/iostreams/build/Jamfile.v2 (revision 57802) +++ libs/iostreams/build/Jamfile.v2 (working copy) @@ -7,7 +7,11 @@ # See http://www.boost.org/libs/iostreams for documentation. -project /boost/iostreams : source-location ../src ; +project /boost/iostreams + : usage-requirements + <link>shared:<define>BOOST_IOSTREAMS_DYN_LINK=1 + : source-location ../src + ; # The biggest trick in this Jamfile is to link to zlib and bzip2 when # needed. To configure that, a number of variables are used, which must Regards

Alexander Arhipenko wrote:
Guys,
We use boost.build not only for building boost but also to create own binary packages. For a long time I observe linker errors on msvc due to lack of usage requirements in Jamfile's. Issue is reproduced when somebody builds executable like this:
exe foo : main.cpp /boost/filesystem ; #or /boost/program_options or /boost/iostreams
Following trivial patch resolves these issues:
Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@
project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ;
@@ -17,4 +20,4 @@ <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 # tell source we're building dll's ;
Index: libs/filesystem/build/Jamfile.v2 =================================================================== --- libs/filesystem/build/Jamfile.v2 (revision 57802) +++ libs/filesystem/build/Jamfile.v2 (working copy) @@ -11,6 +11,7 @@ project boost/filesystem : source-location ../src : usage-requirements # pass these requirement to dependents (i.e. users) + <library>/boost/system <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1 <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1 ;
Alexander, do you actually need the above patch? Because boost.filesystem has boost.system in sources, you should not need to add it to usage requirements. Could you clarify? I have checked in two other changes in your patch. Thanks! - Volodya

On Sat, Nov 21, 2009 at 11:20 AM, Vladimir Prus <vladimir@codesourcery.com> wrote:
Alexander Arhipenko wrote:
Index: libs/filesystem/build/Jamfile.v2 =================================================================== --- libs/filesystem/build/Jamfile.v2 (revision 57802) +++ libs/filesystem/build/Jamfile.v2 (working copy) @@ -11,6 +11,7 @@ project boost/filesystem : source-location ../src : usage-requirements # pass these requirement to dependents (i.e. users) + <library>/boost/system <link>shared:<define>BOOST_FILESYSTEM_DYN_LINK=1 <link>static:<define>BOOST_FILESYSTEM_STATIC_LINK=1 ;
Alexander, do you actually need the above patch? Because boost.filesystem has boost.system in sources, you should not need to add it to usage requirements.
Could you clarify?
I have checked in two other changes in your patch. Thanks!
- Volodya
Hi Volodya, I thinks the filesystem's patch is required and will try to clarify why. Here is minimal example that reproduces the issue: #Jamfile.v2: exe foo : main.cpp /boost/filesystem ; //main.cpp: #include <boost/filesystem.hpp> int main(int argc, char* argv) { return 0; } In this case following error appears: main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::get_system_category(void)" (__imp_?get_system_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'system_category''(void)" (??__Esystem_category@system@boost@@YAXXZ) The reason is: #include <boost/filesystem.hpp> --> includes <boost/path.hpp> --> includes <boost/system/system_error.hpp> --> includes <boost/system/error_code.hpp> File boost/system/error_code.hpp has following declarations: BOOST_SYSTEM_DECL const error_category & get_system_category(); BOOST_SYSTEM_DECL const error_category & get_generic_category(); So, when the header above is included in main.cpp, BOOST_SYSTEM_DECL unrolls to: __declspec(dllimport). And this causes the linker error. As a result, library that links boost::filesystem should link boost::system. Regards

Alexander Arhipenko wrote: Hi Alexander,
Here is minimal example that reproduces the issue: #Jamfile.v2:
exe foo : main.cpp /boost/filesystem ;
//main.cpp:
#include <boost/filesystem.hpp>
int main(int argc, char* argv) { return 0; }
In this case following error appears:
main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl boost::system::get_system_category(void)" (__imp_?get_system_category@system@boost@@YAABVerror_category@12@XZ) referenced in function "void __cdecl boost::system::`dynamic initializer for 'system_category''(void)" (??__Esystem_category@system@boost@@YAXXZ)
The reason is: #include <boost/filesystem.hpp> --> includes <boost/path.hpp> --> includes <boost/system/system_error.hpp> --> includes <boost/system/error_code.hpp>
File boost/system/error_code.hpp has following declarations:
BOOST_SYSTEM_DECL const error_category & get_system_category(); BOOST_SYSTEM_DECL const error_category & get_generic_category();
So, when the header above is included in main.cpp, BOOST_SYSTEM_DECL unrolls to: __declspec(dllimport). And this causes the linker error.
As a result, library that links boost::filesystem should link boost::system.
Yes, and this: lib boost_filesystem : $(SOURCES).cpp ../../system/build//boost_system : should be enough for that. I'll check why is that not working. - Volodya

Vladimir Prus wrote:
Alexander Arhipenko wrote:
The reason is: #include <boost/filesystem.hpp> --> includes <boost/path.hpp> --> includes <boost/system/system_error.hpp> --> includes <boost/system/error_code.hpp>
File boost/system/error_code.hpp has following declarations:
BOOST_SYSTEM_DECL const error_category & get_system_category(); BOOST_SYSTEM_DECL const error_category & get_generic_category();
So, when the header above is included in main.cpp, BOOST_SYSTEM_DECL unrolls to: __declspec(dllimport). And this causes the linker error.
As a result, library that links boost::filesystem should link boost::system.
Yes, and this:
lib boost_filesystem : $(SOURCES).cpp ../../system/build//boost_system :
should be enough for that. I'll check why is that not working.
I've looked. Apparently, Boost.Filesystem not only uses Boost.System in its sources, but also uses it in inlined and/or template functions. Therefore, a client of Boost.Filesystem will have direct references to Boost.System function in it. And on Windows, for this to work, Boost.System library must be directly linked with. I've checked in a patch that adds necessary usage requirements to Boost.Filesystem, see: https://svn.boost.org/trac/boost/changeset/58028 Thanks for the report! - Volodya

On Mon, Nov 30, 2009 at 9:31 AM, Vladimir Prus <vladimir@codesourcery.com> wrote:
Vladimir Prus wrote:
Alexander Arhipenko wrote: [snip] Yes, and this:
lib boost_filesystem : $(SOURCES).cpp ../../system/build//boost_system :
should be enough for that. I'll check why is that not working.
I've looked. Apparently, Boost.Filesystem not only uses Boost.System in its sources, but also uses it in inlined and/or template functions. Therefore, a client of Boost.Filesystem will have direct references to Boost.System function in it. And on Windows, for this to work, Boost.System library must be directly linked with.
I've checked in a patch that adds necessary usage requirements to Boost.Filesystem, see:
https://svn.boost.org/trac/boost/changeset/58028
Thanks for the report!
- Volodya
Hi Volodya, Thanks for you attention! Cheers

Am 21.11.2009 10:20, schrieb Vladimir Prus:
Alexander Arhipenko wrote:
Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@
project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ;
Hi, I'm not pretty sure ... but does this solve Ticket #2273 ? Cheers -Sascha

Sascha Ochsenknecht wrote:
Am 21.11.2009 10:20, schrieb Vladimir Prus:
Alexander Arhipenko wrote:
Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@
project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ;
Hi,
I'm not pretty sure ... but does this solve Ticket #2273 ?
Yes, it does. That's why the commit closed that ticket ;-) https://svn.boost.org/trac/boost/changeset/57832 - Volodya

Vladimir Prus wrote:
Sascha Ochsenknecht wrote:
Am 21.11.2009 10:20, schrieb Vladimir Prus:
Alexander Arhipenko wrote:
Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@
project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ;
Hi,
I'm not pretty sure ... but does this solve Ticket #2273 ?
Yes, it does. That's why the commit closed that ticket ;-)
Hm, the ticket is still open: https://svn.boost.org/trac/boost/ticket/2273 Maybe because BOOST_PROGRAM_OPTIONS_STATIC_LINK is not defined? Cheers -Sascha

Sascha Ochsenknecht wrote:
Vladimir Prus wrote:
Sascha Ochsenknecht wrote:
Am 21.11.2009 10:20, schrieb Vladimir Prus:
Alexander Arhipenko wrote:
Index: libs/program_options/build/Jamfile.v2 =================================================================== --- libs/program_options/build/Jamfile.v2 (revision 57802) +++ libs/program_options/build/Jamfile.v2 (working copy) @@ -1,6 +1,9 @@
project boost/program_options : + usage-requirements + <link>shared:<define>BOOST_PROGRAM_OPTIONS_DYN_LINK=1 + : source-location ../src ;
Hi,
I'm not pretty sure ... but does this solve Ticket #2273 ?
Yes, it does. That's why the commit closed that ticket ;-)
Hm, the ticket is still open: https://svn.boost.org/trac/boost/ticket/2273
Seems like Trac integration had an issue.
Maybe because BOOST_PROGRAM_OPTIONS_STATIC_LINK is not defined?
There's no such macro -- if _DYN_LINK is not defined, it means static link is done. I have now closed that issue for real. - Volodya
participants (3)
-
Alexander Arhipenko
-
Sascha Ochsenknecht
-
Vladimir Prus