tags:

views:

278

answers:

2

I'm new to boost, and thought I'd try it out with some realistic deployment scenarios for the .dlls, so I used the following command to compile/install the libraries:

.\bjam install --layout=system variant=debug runtime-link=shared link=shared
--with-date_time --with-thread --with-regex --with-filesystem
--includedir=<my include directory> --libdir=<my bin directory> > installlog.txt

That seemed to work, but my simple program (taken right from the "Getting Started" page) fails:

#include <boost/regex.hpp>
#include <iostream>
#include <string>

// Place your functions after this line
int main()
{
    std::string line;
    boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );

    while (std::cin)
    {
        std::getline(std::cin, line);
        boost::smatch matches;
        if (boost::regex_match(line, matches, pat))
            std::cout << matches[2] << std::endl;
    }
}

This fails with the following linker error:

fatal error LNK1104: cannot open file 'libboost_regex-vc80-mt-1_42.lib'

I'm sure that both the .lib and the .dlls are in that directory, and named how I want them to be (ie: boost_regex.lib, etc, all unversioned, as the --layout=system says). So why is it looking for the versioned type of it? And how do I get it to look for the unversioned type of the library?

I've tried this with more "normal" options, such as below:

.\bjam stage --build-type=complete --with-date_time --with-thread --with-filesystem --with-regex > mybuildlog.txt

And that works fine. I made sure my compiler saw the "stage\lib" directory, and it compiled and ran fine with nothing beyond having the environment looking into the right lib directory. But when I took those "testing" directories away, and wanted to use these others (unversioned), then it failed.

I'm under VS2005 here on XP. Any ideas?

+2  A: 

Fast answer, for I have no access to a Visual C++ at home.

I believe you are clashing with the "autolinking" of Boost on Visual C++ compilers.

A solution would be to disable "autolink" (see your documentation for that: A quick google search showed the macro "BOOST_ALL_NO_LIB" to disable autolinking for ALL Boost libraries), and then link explicitely your project to the right library.

I'll update this answer as soon as possible.

paercebal
That worked, though now I'm getting a shared_ptr error (a BOOST_ASSERT is failing for null pointer). I even stepped through the code and can't understand how something's not initialized. Probably because I compiled the libraries without this flag, and am trying to compile the application with it, but that still doesn't make a lot of sense.Anyways, thanks for your help.
Kevin
A: 

I also ran into this strange (to me) linker error for my build of Boost on Windows Server 2003 using VS2005. I'm using similar bjam command-line options as the OP was, but without the --layout=system option since I don't mind the version info in them (not yet).

The executive summary of the verbiage that follows is: If you see LINK : fatal error LNK1104: cannot open file 'libboost_regex-vc80-mt-gd-1_42.lib', then you need to to specify the same -D compile line options in your downstream application build as Boost's builds do when they build the Boost Regex library. The documentation does not state that AFAICT (as of 2010-03-23).

The details: Things I found quite helpful debugging this problem were:

  1. Use the -d+2 option to bjam when building. This dumps out a huge amount of logging about exactly what command-line options are being used. That was how I determined that -DBOOST_ALL_NO_LIB=1 and -DBOOST_REGEX_DYN_LINK=1 were being specified on the cl.exe compile line when building the Boost Regex library.

  2. Realize that you have to also supply the same special -D flags (use either -D or /D options which VS2005 accepts as the same thing) when you compile the .cpp files in the app that uses that Boost library (true for Boost Regex, and I am guessing it is true for others, which I have not confirmed). That is why you will see a linker failure of: LINK : fatal error LNK1104: cannot open file 'libboost_regex-vc80-mt-gd-1_42.lib', since without the -DBOOST_ALL_NO_LIB=1 and -DBOOST_REGEX_DYN_LINK=1 options, the auto-linking will kick in when the compiler parses your .cpp file and #include's the Boost header, the latter of which #include's the auto-linking headers, the latter of which by default uses the auto-linking logic which are compiler pragmas that tell the linker which library to use. And guess which ones that auto-linking logic chooses by default? Answer: The static ones that are of the form libblablabla.lib and not blablabla.lib which are the import libraries you expect. This pragma-based linker directive logic is what had me chasing my tail for 3 hours trying to figure out what I did wrong on my linker line, when it is under C-preprocessor control in the auto-linking logic that did it.

bgoodr
Rather than the command-line option, I actually altered the user.hpp file in boost\config, since that then affects both bjam, and your own application when compiling.
Kevin