Opened 11 months ago

Last modified 3 months ago

#13326 new Bugs

linking with program_options has unresolved symbols on MSVC

Reported by: Mario Emmenlauer <mario@…> Owned by: Vladimir Prus
Milestone: To Be Determined Component: program_options
Version: Boost 1.65.0 Severity: Problem
Keywords: Cc:

Description

I'm developing a simple command line client application against boost::program_options. Everything works fine on Linux with gcc-4.8, gcc-5.3 and gcc-6.3, on Darwin with XCode 7 and on Windows with MinGW-w64. But on Windows with MSVC Build Tools 2017 x64 I get two unresolved symbols:

LightBISClientCMDLine.cc.obj : error LNK2001: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > boost::program_options::arg" (?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A)
LightBISClientCMDLine.cc.obj : error LNK2001: unresolved external symbol "public: static unsigned int const boost::program_options::options_description::m_default_line_length" (?m_default_line_length@options_description@program_options@boost@@2IB)

I checked program_options.dll and I am under the impression that those two symbols are defined there. I get exact matches for ?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A and ?m_default_line_length@options_description@program_options@boost@@2IB. Also all other symbols from program_options are resolved correctly. Here is the details build log with a verbose linker message: http://data.biodataanalysis.de/tmp/boost_program_options_linker_error_emmenlau.txt

I am explictily setting preprocessor defines for debug, and I set to code to build for C++14. Is that possibly related?

Change History (14)

comment:1 Changed 10 months ago by Mario Emmenlauer <mario@…>

I investigated a bit and I think I found a new hint. As far as I could see, it's no longer supported to export STL classes from a DLL with Visual Studio 2017. There are various reports that indicate that exporting STL classes can cause issues when mixing different runtimes or compiler versions. Is it possible that Microsoft just disabled that option alltogether?

I found related reports here:

comment:2 Changed 8 months ago by Mario Emmenlauer <mario@…>

Is there any progress on this? I understand that it breaks use of program options with MSVC 2017, or am I doing something wrong?

comment:3 Changed 8 months ago by Jakub

same problem here

comment:4 Changed 8 months ago by Vladimir Prus

Could you provide the minimal example (source, build command) that reproduces this?

comment:5 Changed 8 months ago by Mario Emmenlauer <mario@…>

Here is an example that shows the error. The build is configured with cmake. https://github.com/emmenlau/BDAMinimalTestCase

comment:6 Changed 7 months ago by anonymous

It looks to me the commit 1f9413f532e58b82d12e9185c2eb8bc45612914c is the culprit. I could not paste the github link here as the system complained it is external link. github<add .com> /boostorg/program_options/commit/1f9413f532e58b82d12e9185c2eb8bc45612914c In my local build with that reverted, the program_options.lib is generated.

What's the rationale for that commit?

comment:7 Changed 7 months ago by Mario Emmenlauer <mario@…>

Its an interesting find that this causing the build problem. But according to my understanding, exporting STL classes from a DLL (or other shared library) is generally not a good idea.

As quoted from Stackoverflow: Various articles seems to indicate that this is very bad, which is quite understandable. Everything must be compiled with the same compiler settings and CRT version. Otherwise everything will crash and burn.

comment:8 Changed 7 months ago by Vladimir Prus

I am not sure it's a problem with STL classes - the two unresolved references are not STL classes, they are static members of program_options classes. When building program_options, -DBOOST_PROGRAM_OPTIONS_DYN_LINK=1 must be set, otherwise these two are not marked as exported, and this error occurs.

Commit 1f9413 indeed broke things, but it was then fixed in https://github.com/boostorg/boost/commit/a696afede9da8dbf0e3084ad07585148903bfaca

So, the first step in diagnosing this issue would be to go to libs/program_options/build, run b2 toolset=msvc link=shared -n and see whether the library is built with -DBOOST_PROGRAM_OPTIONS_DYN_LINK=1 or not.

comment:9 Changed 7 months ago by Mario Emmenlauer <mario@…>

Dear Vladimir, thanks for your help. But one question: I checked program_options.dll and I am under the impression that those two symbols are defined there. I get exact matches for ?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A and ?m_default_line_length@options_description@program_options@boost@@2IB in program_options.dll. Should that not imply that the export worked, but the linker does not accept these symbols?

comment:10 Changed 7 months ago by Vladimir Prus

boost_program_options.dll is expected to have these symbols at all times, however the linker is not using .dll, it's using import library, usually boost_program_options.lib. When building without -DBOOST_PROGRAM_OPTIONS_DYN_LINK=1, the import library does not mention these symbols, and the linker cannot find them.

There could be other issues, maybe specific to VC 2017, but the first thing we need to determine if -DBOOST_PROGRAM_OPTIONS_DYN_LINK=1 is used. If not, nothing is gonna work.

comment:11 Changed 7 months ago by Mario Emmenlauer <mario@…>

Ok I did as you suggested and added -n to the build options. Then I get

#> grep BOOST_PROGRAM_OPTIONS_DYN_LINK /tmp/buildlog.txt
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1
-DBOOST_PROGRAM_OPTIONS_DYN_LINK=1

Do you need the full build log?

comment:12 Changed 6 months ago by Mario Emmenlauer <mario@…>

So do I understand correctly that the symbols should be there because the flag is present as expected? Anything I can do to help?

comment:13 Changed 5 months ago by anonymous

Hi,

thanks for details.

I am using boost 1.64, library program_options.lib does contain the unresolved symbols pointed out in VS link errors. Still I am facing the same issue. Do i need to build the library again with DBOOST_PROGRAM_OPTIONS_DYN_LINK=1 option.

comment:14 Changed 3 months ago by Mario Emmenlauer <mario@…>

Is there progress on this issue? I can not use boost::program_options shared build on MSVC with any compiler since 2015 (tested with MSVC 2015, MSVC2017 and Intel Compiler for Windows).

Note: See TracTickets for help on using tickets.