Re: [Boost-users] [program options] failure to link [SOLVED]

Sorry for the double post. I had to patch Source of the Program
Options to solve this issue. Here the organization of the project
which produced Linking errors:
BoostProgramOptions.LIB (we link against DLL version of LIB)
^
|
Lib with PO retriever (static lib)
^
|
+------------------------------------------------------------+
| |
Lib A Lib B
^ ^
| |
+------------------------------------------------------------+
^
|
DLL which links with A & B
Lib A & Lib B rely on the same program options reader.
Initial problem was as described below. To solve this issue I had to
remove the arg definition in the value_semantic.cpp file and
initialize it in the header file detail/value_semantic.hpp with MS
specific __declspec(selectany) which causes to ignore multiple defined
linker symbol. Here the linke in the value_semantic.hpp
extern BOOST_PROGRAM_OPTIONS_DECL __declspec(selectany)
std::string arg("arg");
I hope you can reproduce this behaviour and apply this patch to next
boost destributions.
With Kind Regards,
Ovanes
P.S. I don't know if the entire fix is worth doing it when the arg's
value is copied in the source anyway. Just a small example:
template
Hi *!
We switched the alignment of boost (1.34.0 + VC 7.1) libs to 4 byte, since our project has a restriction of 4byte struct member alignment and we receive a linker error that program_options can no link to a boost::program_options::arg string global.
error LNK2001: unresolved external symbol "class std::basic_string
const boost::program_options::arg" (?arg@program_options@boost@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@B) Making the dumpbin /exports from the boost_program_options....lib I clearly find this symbol as exported one, with the exactly searched signature. Using the default struct member alignment I can link to the program_options lib whithout any problems. Any ideas or suggestions are really welcome!
With Kind Regards, Ovanes

Ovanes Markarian wrote:
Sorry for the double post. I had to patch Source of the Program Options to solve this issue. Here the organization of the project which produced Linking errors:
BoostProgramOptions.LIB (we link against DLL version of LIB) ^ | Lib with PO retriever (static lib) ^ | +------------------------------------------------------------+ | | Lib A Lib B ^ ^ | | +------------------------------------------------------------+ ^ | DLL which links with A & B
Lib A & Lib B rely on the same program options reader.
Initial problem was as described below. To solve this issue I had to remove the arg definition in the value_semantic.cpp file and initialize it in the header file detail/value_semantic.hpp with MS specific __declspec(selectany) which causes to ignore multiple defined linker symbol. Here the linke in the value_semantic.hpp
extern BOOST_PROGRAM_OPTIONS_DECL __declspec(selectany) std::string arg("arg");
So, what is the *reason* for the original linker error?
I hope you can reproduce this behaviour and apply this patch to next boost destributions.
With Kind Regards, Ovanes
P.S. I don't know if the entire fix is worth doing it when the arg's value is copied in the source anyway. Just a small example:
template
std::string typed_value ::name() const { if (!m_default_value.empty() && !m_default_value_as_text.empty()) { return arg + " (=" + m_default_value_as_text + ")";
Well, this will rely on compiler/linker ability to merge duplicate strings. - Volodya

Vladimir, please read my answer below.
extern BOOST_PROGRAM_OPTIONS_DECL __declspec(selectany) std::string arg("arg");
So, what is the *reason* for the original linker error?
To be honest I don't know what is the reason, but it sounds like a BUG in VC7.1 linker to me. If I use default alignment in the described scenario I can link, asap I switch to 4 byte struct member alignment (boost libs are recompiled with that setting as well) linker can't find the symbol. The signature of the exported symbol is exact with the signature of looked up symbol. May be the linker makes the look-up in Lib A and Lib B only, instead of in program_options.lib. If I move the initialiazation to the header with the __declspec(selectany) decl-specifier the string is indeed present in Lib A, Lib B and program_options.lib and the linker picks one of them. Many thanks for your help. Ovanes
participants (2)
-
Ovanes Markarian
-
Vladimir Prus