Boost logo

Boost Users :

Subject: Re: [Boost-users] dynamic link error: boost::program_options::arg not found (Sebastian Hauer)
From: Vial, Florent (fvial_at_[hidden])
Date: 2008-09-18 05:42:38


Hi Sebastian and Ovanes,

I am facing the same problems as you with linking to boost::program_options, and boost::system too.
In all my win32 projects (I use msvc9.0), I define BOOST_DYN_LIB using a common property sheet.
It compiles just fine with 1.36.0 but it does not link.
I also specify BOOST_LIB_DIAGNOSTIC so that I can see what boost auto link is trying to do.

May be I should say that I built my boost 1.36.0 libraries on Win32 (Windows XP Professional SP3) using following command line:

./bjam.exe toolset=msvc --build-type=complete --build-dir="D:\tmp" --threading=multi --runtime-link=static,shared --prefix="C:\boost1.36"

install --without-mpi --without-python --without-wave

When I compile my project (some libraries using boost_filesystem and boost_system, some not), I can see in the compiler output:

Linking to lib file: boost_filesystem-vc90-mt-1_36.lib
Linking to lib file: boost_system-vc90-mt-1_36.lib

When I compile my main :

#include <iostream>

#include <boost/program_options.hpp>

namespace po = boost::program_options;

int main(int argc, char **argv)
{
    int ret = 0;
    po::variables_map vm;
    po::options_description all("Allowed options");
    try
    {
        po::options_description general("General options");
        
        general.add_options()
                ("help,h", "Show this message and exit.")
                ("version,v", "Output version information and exit.");
                    
        po::options_description optional("Optional options");
        optional.add_options()
        ("optional,o", po::value<std::string>(), "Optional")
        ("optional2,p", po::value<std::string>(), "Optional2");
        
        all.add(general).add(optional);
        
        po::store(po::parse_command_line(argc, argv, all), vm);
        po::notify(vm);
    }
    catch (const po::invalid_command_line_syntax &badsyntax)
    {
        /* My log error with badsyntax*/
        ret = -1;
    }
    catch (const po::unknown_option &badoption)
    {
        /* My log error with badoption*/
        ret = -2;
    }
    catch (const po::error &err)
    {
        /* My log error with err*/
        ret = -3;
    }

    if (vm.count("optional"))
    {
        std::string optionalParam = vm["optional"].as<std::string>();
        
        /** Handling optionalParam ... */
    }
    
    if (vm.count("optional2"))
    {
        std::string optionalParam2 = vm["optional2"].as<std::string>();
        /** Handling optionalParam2 ... */
    }
    
    if (vm.count("help"))
    {
        std::cout << all << std::endl;
        return 0;
    }
                  
    return ret;

}

with following command line:

/O2 /Ob2 /Oy /I all-my-includes-here /I "../../../../boost/include/boost-1_36" /D "BOOST_PROGRAM_OPTIONS_DYN_LINK" /D "UNICODE" /D "NDEBUG"

/D "BOOST_LIB_DIAGNOSTIC" /D "BOOST_SYSTEM_DYN_LINK" /D "BOOST_FILESYSTEM_DYN_LINK" /D "BOOST_THREAD_DYN_LINK" /D "NOMINMAX" /D

"WIN32_LEAN_AND_MEAN" /D "WIN32" /D "_WINDOWS" /D "_CRT_NONSTDC_NO_WARNINGS" /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D

"_CRT_NONSTDC_NO_DEPRECATE" /FD /EHsc /MD /GS- /arch:SSE2 /Fo"./../../Release/MyApp/" /Fd"./../../Release/MyApp/vc90.pdb" /W3 /nologo /c /TP

/wd4100 /wd4290 /errorReport:prompt -EHsc -Zm200 -w34100 -w34189 -w34189

I can see in the compiler output following lines:

Linking to lib file: boost_program_options-vc90-mt-1_36.lib
../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(21) : warning C4275: non dll-interface class 'std::logic_error' used

as base for dll-interface class 'boost::program_options::error'
> C:\Programme\MicrosoftVisualStudio9.0\VC\include\stdexcept(21) : see declaration of 'std::logic_error'
> ../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(21) : see declaration of 'boost::program_options::error'
>../../../../boost/include/boost-1_36\boost/program_options/errors.hpp(61) : warning C4251:

'boost::program_options::ambiguous_option::alternatives' : class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of

class 'boost::program_options::ambiguous_option'
> with
> [
> _Ty=std::string
> ]

[snip a lot of similar warnings]

Then, linking with following command line

/OUT:"../../Release\MyApp.exe" /INCREMENTAL /NOLOGO /LIBPATH:"../../Release" /LIBPATH:"..\..\..\..\boost/lib/vc90" /MANIFEST

/MANIFESTFILE:"../../Release/MyApp\MyApp.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'"

/NODEFAULTLIB:"libcpmt.lib" /NODEFAULTLIB:"libcmt.lib" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /MACHINE:X86 /ERRORREPORT:PROMPT msvcrt.lib

msvcprt.LIB binmode.obj kernel32.lib user32.lib netapi32.lib Iphlpapi.lib Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib

comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

I get following errors:

Memain.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall

boost::program_options::detail::cmdline::set_additional_parser(class boost::function1<struct std::pair<class std::basic_string<char,struct

std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >

>,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &>)"

(__imp_?set_additional_parser_at_cmdline@detail_at_program_options_at_boost@@QAEXV?$function1_at_U?$pair_at_V?$basic_string_at_DU?$char_traits_at_D@std@@V?$alloc

ator_at_D@2@@std@@V12@@std@@ABV?$basic_string_at_DU?$char_traits_at_D@std@@V?$allocator_at_D@2@@2@@4@@Z) referenced in function "public: class

boost::program_options::basic_command_line_parser<char> & __thiscall

boost::program_options::basic_command_line_parser<char>::extra_parser(class boost::function1<struct std::pair<class

std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct

std::char_traits<char>,class std::allocator<char> > >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>

> const &>)"

(?extra_parser@?$basic_command_line_parser_at_D@program_options_at_boost@@QAEAAV123_at_V?$function1_at_U?$pair_at_V?$basic_string_at_DU?$char_traits_at_D@std@@V?

$allocator_at_D@2@@std@@V12@@std@@ABV?$basic_string_at_DU?$char_traits_at_D@std@@V?$allocator_at_D@2@@2@@3@@Z)
1>metiscalibrationdata.lib(MetisMatrixCalibration_io.obj) : error LNK2019: unresolved external symbol "class boost::system::error_category

const & __cdecl boost::system::get_generic_category(void)" (?get_generic_category_at_system@boost@@YAABVerror_category_at_12@XZ) referenced in

function "void __cdecl boost::system::`dynamic initializer for 'generic_category''(void)" (??__Egeneric_category_at_system@boost@@YAXXZ)

error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const & __cdecl

boost::system::get_generic_category(void)" (__imp_?get_generic_category_at_system@boost@@YAABVerror_category_at_12@XZ) referenced in function

"void __cdecl boost::system::`dynamic initializer for 'generic_category''(void)" (??__Egeneric_category_at_system@boost@@YAXXZ)
1>filesystem.lib(FileUtils.obj) : error LNK2001: unresolved external symbol "__declspec(dllimport) class boost::system::error_category const

& __cdecl boost::system::get_generic_category(void)" (__imp_?get_generic_category_at_system@boost@@YAABVerror_category_at_12@XZ)
1>filesystem.lib(FileUtils.obj) : error LNK2019: unresolved external symbol "__declspec(dllimport) class boost::system::error_code

boost::filesystem::detail::throws" (__imp_?throws_at_detail@filesystem_at_boost@@3Verror_code_at_system@3_at_A) referenced in function "void __cdecl

boost::filesystem::remove<class boost::filesystem::basic_path<class std::basic_string<char,struct std::char_traits<char>,class

std::allocator<char> >,struct boost::filesystem::path_traits> >(class boost::filesystem::basic_path<class std::basic_string<char,struct

std::char_traits<char>,class std::allocator<char> >,struct boost::filesystem::path_traits> const &,class boost::system::error_code &)"

(??$remove_at_V?$basic_path_at_V?$basic_string_at_DU?$char_traits_at_D@std@@V?$allocator_at_D@2@@std@@Upath_traits_at_filesystem@boost@@@filesystem_at_boost@@@fi

lesystem_at_boost@@YAXABV?$basic_path_at_V?$basic_string_at_DU?$char_traits_at_D@std@@V?$allocator_at_D@2@@std@@Upath_traits_at_filesystem@boost@@@01_at_AAVerror

_code_at_system@1@@Z)

When I open boost\include\boost-1_36\boost\program_options\detail\cmdline.hpp I can see BOOST_PROGRAM_OPTIONS_DECL declared as

__declspec(dllimport) when compiling my application.
When I open boost\include\boost-1_36\boost\system\error_code.hpp, I can see BOOST_SYSTEM_DECL declared as __declspec(dllimport) as well.

So my question (at last!) is: how can I check if those symbols were properly exported when building boost ?

thank you,
Cheers,
Florent

----------------------------------------------------------------------

Message: 1
Date: Wed, 17 Sep 2008 13:21:41 -0400
From: "Sebastian Hauer" <sebastian.hauer_at_[hidden]>
Subject: Re: [Boost-users] dynamic link error:
        boost::program_options::arg not found
To: boost-users_at_[hidden]
Message-ID:
        <fb92d9f00809171021k8c0cf93i75f67b9564281852_at_[hidden]>
Content-Type: text/plain; charset=ISO-8859-1

Hello Ovanes,
thanks for the reply. I fixed it.
I eventually found your posting and tried your suggestion attributing
boost::program_options::arg with an additional __declspec(selectany)
but either I did something wrong or things are different with msvc-8.0
it did not work for me.

Instead I went down a different path and got rid of the global arg
variable altogether. Since nothing seems to write into it and the
value is always copied it seemed like a reasonable thing to do
considering it causes so much grief with the linking.

Once this was fixed I got another linker error:

error LNK2001: unresolved external symbol "public: static unsigned int
const boost::program_options::options_description::m_default_line_length"
(?m_default_line_length_at_options_description_at_program_options_at_boost@@2IB)

I found the solution to that one from this posting from Evert at
http://archives.free.net.ph/message/20080815.085344.d72efb54.en.html .
Once I changed the declaration of the class static const
m_default_line_length to:
 BOOST_STATIC_CONSTANT (unsigned, m_default_line_length = 80);

With these two changes in place all compiled and linked without a problem.
Below I've inlined the patch of my changes against the original
boost_1_36_0 source as reference for other people running into this
issue. If these changes seem like a good idea to others perhaps they
could be included with the next boost release.

Regards,
Sebastian




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net