6

The following library files exist:

cls /usr/local/Cellar/boost/1.51.0/lib $ ls libboost_program*
libboost_program_options-mt.a       libboost_program_options-mt.dylib

I include the following header with #include <boost/program_options.hpp>:

cls /usr/local/Cellar/boost/1.51.0/include $ ls boost/program_options.hpp
boost/program_options.hpp

I try to link the libraries with

-lboost_program_options-mt
-L/usr/local/Cellar/boost/1.51.0/lib

(I assume that the name of the library is derived from the file name minus the "lib" and the file ending. If I try the name boost_program_options (without -mt), I get ld: library not found for -lboost_program_options)

This is my main function using the library:

#include <boost/program_options.hpp>
#include <iostream

int main(int argc, char **argv) {

    namespace opts = boost::program_options;

    opts::options_description desc("EnsembleClustering options");
    desc.add_options()
            ("hello", "produce greeting");

    opts::variables_map vmap;
    opts::store(opts::parse_command_line(argc, argv, desc), vmap);
    opts::notify(vmap);

    if (vmap.count("hello")) {
        std::cout << "Hello World" << std::endl;
    }
}

Why does this setup give me a symbol(s) not found error?

make all 
Building target: EnsembleClustering-DPar
Invoking: MacOS X C++ Linker
/usr/local/bin/g++-4.7 -L"/Users/cls/workspace/STINGER/OpenMP Debug" -L"/Users/cls/workspace/gtest/lib" -L/usr/local/Cellar/log4cxx/0.10.0/lib -L/usr/local/Cellar/boost/1.51.0/lib -fopenmp -std=c++11 -o "EnsembleClustering-DPar"  ./src/scoring/EdgeScoring.o ./src/scoring/ModularityScoring.o  ./src/overlap/test/OverlapGTest.o  ./src/overlap/Overlapper.o ./src/overlap/RegionGrowingOverlapper.o  ./src/matching/Matcher.o ./src/matching/Matching.o ./src/matching/ParallelMatcher.o  ./src/io/test/InputGTest.o  ./src/io/CSVWriter.o ./src/io/GraphFromAdjacencies.o ./src/io/GraphIO.o ./src/io/GraphReader.o ./src/io/METISGraphReader.o ./src/io/METISParser.o ./src/io/METISToGraph.o  ./src/graph/test/GraphGTest.o ./src/graph/test/STINGERGTest.o  ./src/graph/Graph.o ./src/graph/GraphGenerator.o  ./src/ensemble/test/EnsembleGTest.o  ./src/ensemble/EnsembleClusterer.o  ./src/coarsening/test/CoarseningGTest.o  ./src/coarsening/ClusterContracter.o ./src/coarsening/ClusteringProjector.o ./src/coarsening/Contracter.o ./src/coarsening/GraphContraction.o ./src/coarsening/MatchingContracter.o  ./src/clustering/test/ClusteringGTest.o  ./src/clustering/base/Clustering.o ./src/clustering/base/ClusteringGenerator.o ./src/clustering/base/Modularity.o ./src/clustering/base/QualityMeasure.o  ./src/clustering/algo/test/ClusteringAlgoGTest.o  ./src/clustering/algo/Clusterer.o ./src/clustering/algo/LabelPropagation.o ./src/clustering/algo/ParallelAgglomerativeClusterer.o  ./src/aux/test/AuxGTest.o  ./src/aux/Noise.o ./src/aux/RandomInteger.o ./src/aux/RandomProbability.o ./src/aux/Timer.o  ./src/EnsembleClustering.o   -lSTINGER -lgtest -llog4cxx -lboost_program_options-mt
Undefined symbols for architecture x86_64:
  "boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)", referenced from:
      boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*) in EnsembleClustering.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [EnsembleClustering-DPar] Error 1

EDIT: Checking the library files with lipo gives

cls /usr/local/Cellar/boost/1.51.0/lib $ lipo -detailed_info libboost_program_options-mt.a libboost_program_options-mt.dylib 
input file libboost_program_options-mt.a is not a fat file
input file libboost_program_options-mt.dylib is not a fat file
Non-fat file: libboost_program_options-mt.a is architecture: x86_64
Non-fat file: libboost_program_options-mt.dylib is architecture: x86_64

I'd like to link the static library.

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
clstaudt
  • 21,436
  • 45
  • 156
  • 239
  • @Caribou I've read that question before posting. Where exactly do you see the solution to my problem there? – clstaudt Jan 18 '13 at 10:51
  • 1
    apologies I just realised I'm wrong as well :( – Caribou Jan 18 '13 at 10:52
  • What compiler are you using? – Alberto Miranda Jan 18 '13 at 10:55
  • 2
    Did you try linking with the static version of the library to see if it works? Could it be possible that the installed lib is 32 bits instead of 64? – Alberto Miranda Jan 18 '13 at 11:02
  • I think Alberto may be right, although I was able to build this no problem on 64 bit g++ (4.1.2) against a 32 bit library. `/usr/lib/libboost_program_options.so.1.33.1: ELF 32-bit LSB shared object, Intel 80386` – Component 10 Jan 18 '13 at 11:15
  • did you try g++ -static? – TemplateRex Jan 18 '13 at 11:47
  • @AlbertoMiranda I want to link the static library, not the dynamic one. How do I tell the linker to do this? How can I check for 32 bit vs 64 bit? – clstaudt Jan 18 '13 at 11:47
  • Just add it to the command line as if it was an object file, that is without using the `-l` flag. I believe you need to include the `.a` extension as well. In my answer you can see how to check the arch. – Alberto Miranda Jan 18 '13 at 11:51
  • I added the `-static` flag to the linker but this gives me: `ld: library not found for -lcrt0.o`. I gues I'll have to do without `boost::program_options`. – clstaudt Jan 18 '13 at 12:02
  • how did you build the boost libraries? Which toolchain was used? – Sam Miller Mar 27 '13 at 03:22

2 Answers2

4

Read the error message

Undefined symbols for architecture x86_64:
  "boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)", referenced from:
      boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*) in EnsembleClustering.o

It very clearly says, missing symbol std::__debug::vector, note that the std::__debug namespace is key here. I suspect you've built your source code using iterator debugging with -D_GLIBCXX_DEBUG but are attempting to link against a library that hasn't, such as boost program options. You didn't show us how you built your translation units, so here is a sscce:

$ g++-4.8 -std=c++11 -O2 -pthread main.cpp -D_GLIBCXX_DEBUG -lboost_program_options && ./a.out
/tmp/cca1jwUx.o: In function `boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*)':
main.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x319): undefined reference to `boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::string, std::allocator<std::string> > const&)'
collect2: error: ld returned 1 exit status

There are a few ways to solve this

  • remove the -DGLIBCXX_DEBUG flag from translation units including the program options headers.
  • consult your boost package maintainer to see if they offer a version built with -D_GLIBCXX_DEBUG. Some variants on Linux do, you might ask around the MacPorts or brew users mailing lists.
Sam Miller
  • 23,808
  • 4
  • 67
  • 87
2

Since you're specifying the location for includes, libraries and providing the appropriate .dylib, the only problem I can think of is that the library that you're linking to doesn't have an x86_64 arch in it.

Try checking the library with either file or lipo. If it doesn't show x86_64, then that's the problem.

Alberto Miranda
  • 382
  • 6
  • 16
  • 1
    I was tempted to suggest simply creating a sym link called `libboost_program_options-mt.so` file to the `libboost_program_options-mt.dylib` file, but a bit of reading of [this question and answer](http://stackoverflow.com/questions/8158783/whats-the-meaning-of-dylib-files) convinced me that it may be a bit more complicated than that. – Component 10 Jan 18 '13 at 11:26
  • See the edit to my question. The .dylib is 64bit. The `.a` with which I want to link, also? – clstaudt Jan 18 '13 at 11:52
  • `file` provides few information for `.a` files. Try with `lipo` instead. – Alberto Miranda Jan 18 '13 at 11:54
  • I can't think of any reason why it would not work. Were you able to link to the static library? – Alberto Miranda Jan 18 '13 at 13:51
  • @AlbertoMiranda No. I can't think of a reason either. Thanks for your help, but I'll use this option parser instead: http://optionparser.sourceforge.net/ – clstaudt Jan 18 '13 at 14:03