My old ubuntu-based web server finally died. I'm trying to put things back together on a new 64 bit machine. I have a server-side c++ utility that I need to recompile, but I've never compiled on a 64 bit architecture before, and I'm having some trouble with missing symbols. The only libraries I'm linking with are stdc++ and boost_program_options. The missing symbols are all from boost_program_options. I figure I'm either missing some crucial compiler option, or there's something funny about my boost installation (which I installed with apt-get), or I'm being an idiot and missing something obvious. :)
matt@charon:~/dev/farkle$ dpkg --get-selections | grep options
libboost-program-options-dev:amd64 install
libboost-program-options1.54-dev:amd64 install
libboost-program-options1.54.0:amd64 install
matt@charon:~/dev/farkle$ find /usr/lib/ -print | grep boost_program_options
/usr/lib/x86_64-linux-gnu/libboost_program_options.so
/usr/lib/x86_64-linux-gnu/libboost_program_options.a
/usr/lib/x86_64-linux-gnu/libboost_program_options.s
matt@charon:~/dev/farkle$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04 LTS
Release: 14.04
Codename: trusty
matt@charon:~/dev/farkle$ g++ --version
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Much thanks to anyone who can help me solve my problem.
If you don't get the above output run "ldconfig" to update the cache and try recompiling.
If that doesn't work, try adding "-L/usr/lib/x86_64-linux-gnu/" to your g++ command line.
Just fyi, the boost example program compiles and runs fine for me with your command line: g++ -I . -lstdc++ -lboost_program_options -o po_test options_descriptions.cpp
If the -L option were to fix things, I would think that I'd be getting an error something like:
/usr/bin/ld: cannot find -lboost_program_options
but I don't. Nevertheless, I gave your suggestion a shot:
1 2 3 4 5 6
matt@charon:~/dev/farkle$ g++ -I . -lstdc++ -lboost_program_options -L /usr/lib/x86_64-linux-gnu/ -o farkle main.cpp
/tmp/cc5LNw7x.o: In function `setConfig(Config&, int, char**)':
main.cpp:(.text+0xd5): undefined reference to `boost::program_options::options_description::m_default_line_length'
main.cpp:(.text+0xe0): undefined reference to `boost::program_options::options_description::m_default_line_length'
main.cpp:(.text+0x125): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
...
but saw no obvious changes in output.
Well, this is becoming annoying. I guess I could download the boost source and just compile that library directly to bypass the library problems I'm having. Not a very satisfactory solution though.
I remember having this problem like 20 years ago, learning about the dependence library order during the link step, but somehow hadn't made this mistake since. I guess I had assumed that things had changed somehow. And if the libraries really need to be listed at the end, then why was "norm b" able to build his test program using the same libraries using the same command line ordering -- a bit curious, don't you think?
Anyway, the fact that I was having the trouble on a new platform made me believe the problem was with the new box and not cockpit error.
Thanks so much for getting me through this silliness.
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.
Thanks, Peter. I am aware that the order of the libraries on the command line can make a difference. What's puzzling to me is that order makes a difference in this case on Ubuntu but not on Debian.
What's puzzling to me is that order makes a difference in this case on Ubuntu but not on Debian.
This applies only for static linking, not for dynamic linking, so please check first what you are saying.
LD linker behaves the same on every *nix distribution, even windows port has the same "feature" - they called "optimization" to not search for exported symbols except only once and discard "unused" ones. This is crap, in case of 2 libraries that depends on each other (circular references) you must add some libraries twice to make it link correctly.
Other linkers tries hard to make the executable link correctly, at the cost of more computer resources.