test.c:(.text+0x36): undefined reference to `md5_file' - c++

I installed polarssl:
make
sudo make install
tried to compile very simple file, named test.c:
#include <stdio.h>
#include "polarssl/md5.h"
int main(int argc, char * argv[])
{
int i;
for (i=1;i<1;i++)
{
char res[16];
if (md5_file("file.txt",res) == 0)
{
int count;
for (count=0;count<16;count++)
printf("%02x",res[count]);
printf("n");
}
}
return 0;
}
Compiled it like this:
gcc -lpolarssl test.c -I /usr/local/include/polarssl/
but it shows me:
/tmp/cczptlsk.o: In function `main':
test.c:(.text+0x36): undefined reference to `md5_file'
collect2: ld returned 1 exit status
whats the problem, how to fix it? I know for 100% that polarssl files are in /usr/local/include/polarssl/

The compiler will attempt to complete linkage in the order the objects or files are presented. In this case, since you had put -lpolarssl first, there were no unresolved symbols needed from that library, so nothing got linked in.
Putting -lpolarssl last lets the compiler resolve unresolved symbols from your source file from that library.

Includes are fine.
But linking is wrong. Try to put the -lpolarssl last in the linker command.
Then add a -L if libpolarssl.a is not found by the linker to point it to the right location.

Related

Simply including <opencv2/opencv.hpp> results in linking error

Simply including the OpenCV header results in linking error. Why is that?
// test.cpp
#include <opencv2/opencv.hpp>
int foo();
int bar();
int main() {
}
If I compile the file with g++ test.cpp, the following linking error occurs:
/tmp/ccugmQl4.o: In function `cv::String::~String()':
test.cpp:(.text._ZN2cv6StringD2Ev[_ZN2cv6StringD5Ev]+0x14): undefined reference to `cv::String::deallocate()'
/tmp/ccugmQl4.o: In function `cv::String::operator=(cv::String const&)':
test.cpp:(.text._ZN2cv6StringaSERKS0_[_ZN2cv6StringaSERKS0_]+0x28): undefined reference to `cv::String::deallocate()'
collect2: error: ld returned 1 exit status
If I compile with g++ test.cpp -lopencv_core, it works all right.
My question is:
It seems to me that there's no need to resolve undefined symbols if I do not use it, like the functions foo and bar. There's no definition for them but the compile-link process works alright.
I don't use any OpenCV functions either. Why is there linking error only for OpenCV functions?
And what kinds of stuff defined in headers can cause such a linking error?
If you tweak your example a little bit
// test.cpp
int foo();
int bar() {
foo();
}
int main() {
}
You would notice that it'd stop working because linker won't be able to understand what is foo();
The same thing happens when you include opencv header - there are references to functions which are declared but since you never link opencv itself - linker can't figure what those functions are and where to get them.

How to force g++ linker to load a symbols not being directly called - avoiding undefined reference

The problem I'm facing is difficult to describe and explain, but let's try...
Enrivornment: Ubuntu, C++ and g++
So I have an hierarchy of c++ projects and namespaces:
main: My main program - that calls....
objectaccess: Access objects (read, write, update, delete) - that calls...
commonaccess: Encapsulate access to sqlite3 functions (sqlite3_open, sqlite3_exec, etc.) - that calls...
sqlite3.so: The Sqlite3 library.
So, an example call code would be:
#include "objectaccess.hpp"
#include "commonaccess.hpp"
int main()
{
int id = 10;
myobjecttype mo = objectaccess::get(id);
}
At objectaccess I have:
#include "commonaccess.hpp"
namespace objectaccess {
myobjecttype get(int id)
{
myobjecttype mo = commonaccess::getFromTableX(id);
return mo;
}
}
At commonaccess I have:
#include <sqlite3.h>
namespace commonaccess {
myobjecttype getFromTableX(int id)
{
sqlite3_init(whatever...);
sqlite3_exe(whatever...);
myobjecttype retobject;
retobject.whatever = data1;
return retobject;
}
}
The code runs fine and is tested, except for one problem. All three namespaces are in different projects delivering a dynamic library (commonaccess.so and objectaccess.so) except for the main program that returns a binary executable.
My problem is:
At main, if I make a call to any of commonaccess functions, I get the following errors on linking:
g++ -L"/home/workspace/objectaccess/Debug"
-L"/home/workspace/commonaccess/Debug"
-L/usr/lib/i386-linux-gnu -Xlinker -rpath="./" -o "test" ./src/test.o
-lsqlite3 -lobjectaccess -lcommonaccess
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_close'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_exec'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_free'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_errmsg'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_open'
/home/workspace/commonaccess/Debug/libcommonaccess.so: undefined reference to `sqlite3_last_insert_rowid'
collect2: error: ld returned 1 exit status
This is simply solved adding at main() a call to any function of commonaccess, like:
#include "objectaccess.hpp"
#include "commonaccess.hpp"
int main()
{
commonaccess::dummycall();
int id = 10;
myobjecttype mo = objectaccess::get(id);
}
Actually calling a dummy function is not desired, so:
a) Why the linker is not being able to solve these references without directly calling any of the commonaccess functions?
b) Why only adding a call to the lower hierarchy namespace in the main program "teaches" the linker about real reference to sqlite3 functions?
Switch the order of libraries being linked. GNU linker can't reorder them, nor keeps references to calls not used so far, so -lsqlite3 is currently useless. Put it after the library that actually uses sqlite3 calls, something like g++ -L"/home/workspace/objectaccess/Debug" -L"/home/workspace/commonaccess/Debug" -L/usr/lib/i386-linux-gnu -Xlinker -rpath="./" -o "test" ./src/test.o -lobjectaccess -lcommonaccess -lsqlite3

undefined reference to `function_name'

I moved from Windows to Ubuntu and I wanted to try some C++ programming on Ubuntu. So here is very simple code and very stupid error which I can't resolve:
horse.h
#ifndef _horse_
#define _horse_
class Horse{
int speed;
public:
void saySomething();
};
#endif
horse.cpp
#include "horse.h"
#include <iostream>
using namespace std;
void Horse::saySomething(){
cout << "iiiihaaaaaaa brrrrr."<<endl;
}
and Main.cpp
#include "horse.h"
int main(){
Horse h;
h.saySomething();
}
After I compile (compilation is successful) and run this I get this error message:
/tmp/ccxuDyrd.o: In function `main':
Main.cpp:(.text+0x11): undefined reference to `Horse::saySomething()'
collect2: ld returned 1 exit status
Please help me somehow.
Try
g++ -c main.cpp horse.cpp (to compile)
g++ -o a.out main.o horse.o (to link)
It seems you only compiled your code but did not link the resulting object files. You probably invoked the compiler like this:
g++ main.cpp
You should instead compile every *.cpp file separately and then link each resulting *.o file. And you should do this with a Makefile.
Actually, the basic idea is the same on Windows with MSVC. The compiler produces object files, the linker links them together.

Linking/compiling a program that uses boost/filesystem.hpp

I'm trying to use the boost/filesystem library in some code that I am writing. I seem to be having a hard time getting it to compile. I'm running Debian Wheezy, and have boost version 1.49(which is what comes if you install using apt-get). I'm trying to compile an example that is available with the documentation
#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: tut1 path\n";
return 1;
}
std::cout << argv[1] << " " << file_size(argv[1]) << '\n';
return 0;
}
I use the following command:
g++ temp.cc -o temp /usr/lib/libboost_filesystem.a
I get a number of errors such as:
/usr/lib/libboost_filesystem.a(operations.o): In function `boost::filesystem3::detail::dir_itr_close(void*&, void*&)':
(.text+0x4d): undefined reference to `boost::system::system_category()'
/usr/lib/libboost_filesystem.a(operations.o): In function `boost::filesystem3::detail::directory_iterator_increment(boost::filesystem3::directory_iterator&, boost::system::error_code*)':
(.text+0xe3): undefined reference to `boost::system::system_category()'
This is probably some linking error right? Any ideas on how I could solve it?
UPDATE #1:
I tried running it with the -lboost_filesyste and -L /usr/lib. It gives me the following error:
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
You are not linking the library properly. Also, as others mentioned, boost_filesystem needs also boost_system library. Use:
g++ temp.cc -o temp -lboost_system -lboost_filesystem
Command line param -l foo links libfoo.a library. If the static library is not in default library location, use command -L /custom/library/dir. But I believe /usr/lib is automatically taken into consideration by GCC.
Edit
According to your comment below it looks like you are not compiling the file with main() function, or you have a typo in main() name. Make sure that temp.cc contains one and only one of these functions:
int main();
int main(int argc, char** argv);
Of course you do remember that upper/lower case matters. :)
Boost.Filesystem uses things in Boost.System. You have to link against that, too.
The error messages that you are seeing:
/usr/lib/libboost_filesystem.a(operations.o): In function
`boost::filesystem3::detail::dir_itr_close(void*&, void*&)':
(.text+0x4d): undefined reference to `boost::system::system_category()'
that's a reference to Boost.System
Add -lboost_system and you should be good to go (or, at least better off).
Compile with -lboost_filesystem

C++ RTTI without libstdc++. Is it possible?

I want investigate how is it possible to link C++ program without libstdc++, but with support of rtti. I tried compile it in the way described below. Any necessary but absent symbol I can define like function strcmp in the example, but is it possible to define typeinfo symbols without explicit mangle/demangle magic? And if possible how?
cd /tmp && cat << 'eof' >rtti.cpp && g++ -nodefaultlibs -lc rtti.cpp
extern "C" int strcmp(const char *s1, const char *s2) { return 0; };
#include "typeinfo"
int main(){
return typeid(int) == typeid(char);
}
Linker says:
/tmp/cc6rBAef.o: In function `main':
rtti.cpp:(.text+0x18): undefined reference to `typeinfo for char'
rtti.cpp:(.text+0x1d): undefined reference to `typeinfo for int'
collect2: error: ld returned 1 exit status
So, how can I define 'typeinfo of char'(_ZTIc##CXXABI_1.3) in source file using g++ or clang++?
PS. Don't ask me why do I need it. Just a curiosity.
Since the symbols needed for RTTI seem to be in the libstdc++ library, you cannot do completely without it. Note that I found this by running
readelf -Ws `g++ -print-file-name=libstdc++.so` | awk '{print $8}' | c++filt | grep 'typeinfo for'
What you can do, however, is statically link with libstdc++:
g++ -static-libstdc++ rtti.cpp
In this way, you won't have any dynamic dependencies on libstdc++ and only the symbols you actually need are pulled in to your executable. (Well, all symbols from the object file that contains the needed symbols, fundamental_type_info.o in you example, I suppose.)
Thanks to gcc community for hint.
The answer is:
"gcc use some magic to substitute destructor of __fundamental_type_info to a set of typeinfo symbols"
Substitution code is placed in file: gcc-4.7.2/gcc/cp/rtti.c, void emit_support_tinfos(void);
rtti.cc:
#include <typeinfo>
namespace __cxxabiv1 {
class __fundamental_type_info:public std::type_info{
public:
explicit __fundamental_type_info(const char* __n) : std::type_info(_n) { }
virtual ~__fundamental_type_info(){};
};
}
int main(){
return typeid(int) == typeid(char);
}
All fundamental typeinfos are inserted into object file during compilation.
$g++ -c ./rtti.cc;readelf -sW ./rtti.o |c++filt|grep typeinfo|wc -l
$153
So the question is answered.