Shared library not linking / cannot be done this way? - c++

Here's my issue:
In my project, I have a class called Match. Now, I would like to use somebody else's code to compare their results. They, unfortunately, also have a class called Match.
OK, so I thought I'd do:
namespace MonteCarlo {
#include "monte-carlo/match.hpp"
}
I appreciate that this is not best practice, but I really just want to test the output for now rather than rewrite everything in new namespaces.
Then, I made a shared library out of his code, and linked it:
LIBPATHS = -L mysql_connector/lib/ -Lmonte-carlo/lib
LIBS = -l mysqlcppconn -l boost_date_time -l boost_iostream boost_system -l boost_filesystem -l MonteCarloTennis
But when I build, I get:
evaluator.cc:139: undefined reference to `MonteCarlo::Match::Match(double, double, double, double, bool, bool)'
evaluator.cc:140: undefined reference to `MonteCarlo::Match::play_match()'
But in the library, using nm, I see:
0000000000001286 T Match::Match(double, double, double, double, bool, bool)
0000000000001286 T Match::Match(double, double, double, double, bool, bool)
I am really new to libraries, so I could really use your advice. Am I getting this linker error because my library is not linking correctly, or because I wrapped the Match class in the namespace and thus the two functions in the library are not found?

Thank you to Joachim Pileborg for providing the answer!
Wrapping the #include in a namespace meant the linker couldn't find the corresponding function in the library. I have now fixed the issue by putting my colleague's code into namespaces.
So a very simple error, but there was so much that could have gone wrong (my first time building a library!) that it was really helpful to get Joachim's advice. Thanks again!

Related

Error related to libraries

i just write a fuzzy code with a fuzzylogic library(eFLL library). I used it in a linux environment and try to compile it with g++. i unziped the library in the g++ path. but these errors come to me and i do not know what are these for. i make a Makefile and try to solve the problem but nothing well happend. does anyone know how can i solve this problem?
a part of code is like this:
include <iostream.h>
#include "../FuzzyRule.h"
#include "../FuzzyComposition.h"
#include "../Fuzzy.h"
void setup(){
Fuzzy* fuzzy = new Fuzzy();
FuzzyInput* Threat = new FuzzyInput(1);
FuzzySet* lowThreat = new FuzzySet::FuzzySet(0, 1.875, 1.875, 3.75),
a part of errors are like this:
fuzzycode2.cpp:(.text+0x23): undefined reference to `Fuzzy::Fuzzy()'
fuzzycode2.cpp:(.text+0x61): undefined reference to
`FuzzyInput::FuzzyInput(int)'
fuzzycode2.cpp:(.text+0xbb): undefined reference to
`FuzzySet::FuzzySet(float, float, float, float)'
fuzzycode2.cpp:(.text+0xed): undefined reference to
`FuzzyIO::addFuzzySet(FuzzySet*)'
fuzzycode2.cpp:(.text+0x129): undefined reference to
`FuzzySet::FuzzySet(float, float, float, float)'
Including the headers into the C++ files isn't enough. You also need to specify the library file and possibly its location while linking, e.g.:
g++ your-files-go-here -o some-name -Llocation-of-the-library -llibrary-name
Looking at the page of this particular "library" it seems it consists of just a bunch of object files which you would need to put together into a library or include explicitly while linking.

Not able to locate error cpp linux

This maybe really stupid, but I faced the following error, while trying to compile certain code modules, using cmake
acg_localizer_active_search.cc:(.text+0x43c6): undefined reference to
`ANNkd_tree::ANNkd_tree(float**, int, int, int, ANNsplitRule)'
acg_localizer_active_search.cc:(.text+0x4441): undefined reference to
`ANNkd_tree::ANNkd_tree(float**, int, int, int, ANNsplitRule)'
Please help me to understand what this undefined reference error means.
The error line mentioned as '.text+0x...', is not understandable. How can I locate the error.
I have been stuck for quite some time, solving error after error and have ended up here. Please help me. Thanks in advance
Sorry for not adding the code. it is around 2000 lines and am not sure where to locate this error. its part of a software package, called acg_localizer.
That's a link time error. The method ANNkd_tree::ANNkd_tree(float**, int, int, int, ANNsplitRule) cannot be found in any libraries and object files specified in the link command, although it is referenced.
You have to find out where it is defined, and make sure the library it is defined in comes after the library that uses it on the linker command line.
You can use the nm tool to find out which symbols (= variables, methods) are defined or used by an object file or library. Do a man nm (or search on google) to find out more.

Linking Intel's MKL (BLAS & LAPACK) to GCC

I am trying to compile a giant software package, and this is the last hurdle I can't seem to figure out.
I'm getting errors like:
RNDiracDeterminantBase.cpp:(.text+0x22bf): undefined reference to `dgetrf_'
RNDiracDeterminantBase.cpp:(.text+0x2524): undefined reference to `dgetri_'
RNDiracDeterminantBase.cpp:(.text+0x3005): undefined reference to `dgetri_'
../../lib/libqmcwfs.a(RNDiracDeterminantBase.cpp.o): In function `qmcplusplus::RNDiracDeterminantBase::ratio(qmcplusplus::ParticleSet&, int, qmcplusplus::ParticleAttrib<qmcplusplus::TinyVector<double, 3u> >&, qmcplusplus::ParticleAttrib<double>&)':
RNDiracDeterminantBase.cpp:(.text+0x4156): undefined reference to `dgemv_'
RNDiracDeterminantBase.cpp:(.text+0x420f): undefined reference to `dger_'
Google reveals that these references are to Intel's MKL library. However, I don't know what file I need to link. I've tried libmkl_core.a, libmkl_gnu_thread.a, libmkl_blacs_intelmpi_lp64.a, etc. There's tons of files in:
/mkl/lib/intel64/
Can post more information if requested.
I don't know what file I need to link. I've tried libmkl_core.a, libmkl_gnu_thread.a, libmkl_blacs_intelmpi_lp64.a, etc. There's tons of files in: /mkl/lib/intel64/
The fact that there are tons of files doesn't mean you have to try each library in turn.
To find out which library defines the symbols you want, run this command:
cd /mkl/lib/intel64
nm -A *.a | egrep '[TWBD] (dger_|dgemv_|dgetrf_|dgetri_)$'
Also be sure to put libraries at the end of your link line, as the order of archive libraries on command line matters.
Based on the incomplete information you provided, it's likely that you need libmkl_intel_lp64.a, libmkl_gnu_thread.a, and libmkl_core.a.
Intel MKL has a built-in tool to help you figure out linking: /mkl/tools/mkl_link_tool. This tool is also available on the web: http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor. Use this tool to get the exact link line for your situation.
You should have asked your question on the official MKL forum (http://software.intel.com/en-us/forums/intel-math-kernel-library). You'd get the answer for this type of questions within hours instead of days.
I had a similar problem when setting up mingw on windows.
The following library linking order worked for me with gcc:
mkl_intel_thread
mkl_rt
mkl_core
mkl_intel_lp64
Hope this helps anyone stuck with this problem.

c++ undefined reference class constructor

I'm trying to use a library where one of the classes has a constructor like so:
public:
AreaNodeIndex(size_t cacheSize);
I'm trying to instantiate an object of this class in my program like so:
size_t const cacheSize = 50000;
AreaNodeIndex areaNodeIndex(cacheSize);
The linker gives me the following error:
main.o: In function `main':
make: Leaving directory `/home/Dev/_quicktest_build'
main.cpp:(.text+0x212): undefined reference to
osmscout::AreaNodeIndex::AreaNodeIndex(unsigned int)
I think I have the necessary includes and I'm linking to the library with the compiler. For example, if I try to instantiate the object without any arguments on purpose I get this error:
../quicktest/main.cpp: In function ‘int main()’:
../quicktest/main.cpp:36: error: no matching function for call to ‘osmscout::AreaNodeIndex::AreaNodeIndex()’
/usr/local/include/osmscout/AreaNodeIndex.h:75: note: candidates are: osmscout::AreaNodeIndex::AreaNodeIndex(size_t)
/usr/local/include/osmscout/AreaNodeIndex.h:33: note: osmscout::AreaNodeIndex::AreaNodeIndex(const osmscout::AreaNodeIndex&)
So I can see the correct prototype (though here it says size_t and before it said unsigned int)...
I can use other parts of the library fine. Here are the actual source files for the class in question:
http://libosmscout.git.sourceforge.net/git/gitweb.cgi?p=libosmscout/libosmscout;a=blob;f=libosmscout/include/osmscout/AreaNodeIndex.h
http://libosmscout.git.sourceforge.net/git/gitweb.cgi?p=libosmscout/libosmscout;a=blob;f=libosmscout/src/osmscout/AreaNodeIndex.cpp
I'm pretty lost as to why this is happening. I feel like I've missed something obvious.
*In response to the replies:
The library gets size_t from "sys/types.h", so I don't think we're using different versions. The library was compiled on my system with the same compiler (g++, linux).
Changing the 'const' specifier location has no effect.
I am linking to the library. As I mentioned, I can use other classes from the library without issue. Here's the linking command:
g++ -Wl,-O1 -Wl,-rpath,/home/QtSDK/Desktop/Qt/473/gcc/lib -o quicktest main.o -L/home/QtSDK/Desktop/Qt/473/gcc/lib -losmscout -lpthread
The library name is 'osmscout'.
kfl
Possible cause of the problem in your case could be because of mixing of different size_t as mentioned by #rodrigo. For consistency maybe you can include <cstddef> where you are using size_t unless your project declares it own typedef for size_t. Please refer the link below.
Please refer Does "std::size_t" make sense in C++?
Hope this helps!
The problem may be that the actual size_t typedef depends on several compiler options. Even in a full 32-bit machine, it can be unsigned int or unsigned long depending on the mood of the developers.
So, if the library is compiled with typedef unsigned long size_t; and your program is with typedef unsigned int size_t; you have a problem. You can check it with objdump -t library | c++filt | grep AreaNodeIndex or something like that.
You don't show us the most important part: the command line used to
edit. You're probably not specifying the library to be linked in
(options -l and -L, or you can specify the library as you would any
other file).
As for the linker specifying unsigned int, and the compiler size_t,
that's just an artifact of the way the errors are displayed: the
compiler will display the name of the typedef if that's what was used
when declaring the function. The linker doesn't have this information,
so displays the name of the actual type.
It looks like you're not linking with the library correctly.
can you try
const size_t cacheSize = 50000;
instead?
[edit]
Well, I'd guess that if that declaration is giving you an unsigned long than there is some compiler option that's being overlooked, and that size_t is defined as a typedef over an unsigned long, in your compiler, and not a type that would match up with what the library see's.

Unable to link to shared library

I'm building a shared library with g++ 3.3.4. I cannot link to the library because I am getting
./BcdFile.RHEL70.so: undefined symbol: _ZNSt8_Rb_treeIjjSt9_IdentityIjESt4lessIjESaIjEE13insert_uniqueERKj
Which c++filt describes as
std::_Rb_tree<unsigned int, unsigned int, std::_Identity<unsigned int>, std::less<unsigned int>, std::allocator<unsigned int> >::insert_unique(unsigned int const&)
I thought this might have come from using hash_map, but I've taken that all out and switched to regular std::map. I am using g++ to do the linking, which is including -lstdc++.
Does anyone know what class would be instantiating this template? Or even better, which library I need to be linking to?
EDIT: After further review, it appears adding the -frepo flag when compiling has caused this, unfortunately that flag is working around gcc3.3 bug.
std::_Rb_Tree might be a red-black tree, which would most likely be from using map. It should be part of libstdc++, unless your library is linking against a different version of libstdc++ than the application, which from what you've said so far seems unlikely.
EDIT: Just to clarify, the red-black tree is the underlying data structure in map. All that hash_map does is hash the key before using it, rather than using the raw value.
Try #include < map > in the source file where you are using map.
You seem to have 2 different incompatible versions of libstdc++.so from different versions of gcc. Check your paths.