Undefined references in static OpenCV libraries - c++

I have a project in C++ that uses OpenCV 3.1 and works fine using shared libaries. But now I want to compile it using static libraries (located in a folder within the project directory) because I want to be able to export it (and also edit and recompile if necessary) where OpenCV is not installed.
I have recompiled OpenCV this time setting shared libs to NO:
make -DCMAKE_BUILD_TYPE=RELEASE -DBUILD_SHARED_LIBS=NO -DCMAKE_INSTALL_PREFIX=~/Desktop/ocv ..
Then I took my required libraries:
libopencv_core.a libopencv_imgproc.a libopencv_highgui.a
libopencv_video.a libopencv_imgcodecs.a libopencv_videoio.a
and ran g++ a.cpp libopencv_core.a where a.cpp is a sample program to test if everything works:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat a;
printf("hello world\n" );
return 0;
}
My problem is that I can not link the first library (core) because I get lots of undefined references like this:
libopencv_core.a(system.cpp.o): In function `cv::Mutex::Mutex()':
system.cpp:(.text._ZN2cv5MutexC2Ev+0x2c): undefined reference to `pthread_mutexattr_init'
system.cpp:(.text._ZN2cv5MutexC2Ev+0x39): undefined reference to `pthread_mutexattr_settype'
system.cpp:(.text._ZN2cv5MutexC2Ev+0x4c): undefined reference to `pthread_mutexattr_destroy'
libopencv_core.a(system.cpp.o): In function `cv::Mutex::trylock()':
system.cpp:(.text._ZN2cv5Mutex7trylockEv+0x8): undefined reference to `pthread_mutex_trylock'
libopencv_core.a(system.cpp.o): In function `cv::TlsAbstraction::TlsAbstraction()':
system.cpp:(.text._ZN2cv14TlsAbstractionC2Ev+0x9): undefined reference to `pthread_key_create'
libopencv_core.a(system.cpp.o): In function `cv::TlsAbstraction::~TlsAbstraction()':
and so on. I have searched all over and cannot find what's missing. Any help is greatly appreciated.
p.s. G++ and Ubuntu version: g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

You need to link pthread library as well. And pass it as -pthread
g++ a.cpp libopencv_core.a -pthread
You're missing other libraries which contain the required code. There must be a libippicv.a which contains the code for ippicv* functions
g++ a.cpp libopencv_core.a libippicv.a -pthread
It should be somewhere among third_party libs.

Related

Cannot use filesystem::path when compiling with MacPorts LLVM / Clang 15.0.5 on macOS 10.13 or 10.14 [duplicate]

I was trying to out the new filesystem STL library, but for some reason am getting errors. The Clang++7 website indicates that it should support the new filesystem library – indeed clang is running ahead of g++ I believe.
I used some code from another Stack Exchange post, so it should be valid based upon the number of upvotes. This could should go to the specified directory and print all files in that directory. Here is the code.
#include <iostream>
#include <string>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main(int argc, char *argv[])
{
std::string path = "/home/.../Downloads";
for (const auto & entry : fs::directory_iterator(path))
{
std::cout << entry.path() << std::endl;
}
}
The error messages I am getting are:
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `main':
/media/.../clangcpp/filesystem_app/main.cpp:13: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator*() const'
/media/.../clangcpp/filesystem_app/main.cpp:13: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::operator++()'
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `path<std::__cxx11::basic_string<char>, std::experimental::filesystem::v1::__cxx11::path>':
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/experimental/fs_path.h:198: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
CMakeFiles/filesystem_app.dir/main.cpp.o: In function `directory_iterator':
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.5.0/../../../../include/c++/5.5.0/experimental/fs_dir.h:188: undefined reference to `std::experimental::filesystem::v1::__cxx11::directory_iterator::directory_iterator(std::experimental::filesystem::v1::__cxx11::path const&, std::experimental::filesystem::v1::directory_options, std::error_code*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I made sure to include the experimental/filesystem header instead of just filesystem which removed any red squiggles in Clion. I tried to compile from CLion as well as from the command line. The compilation string I used was:
clang++-7 -Wall -std=c++17 main.cpp -o app
Does anyone have a sense of what is wrong here? In the compile error messages I see the reference to std::experimental::filesystem::v1::__cxx11::.. and I am wondering why this does not say cxx17, but I was not sure if that was the cause of the issue. I explicitly indicated c++17 in the compilation string above.
filesystem is still experimental and requires an extra library.
If you are using libstdc++, link with -lstdc++fs (or target_link_libraries(${PROJECT_NAME} stdc++fs)).
For libc++, use -lc++fs (similar for the CMake command).

Unable to statically link boost-locale due to libicu linking errors on Ubuntu 18.04

The following code:
#include <boost/locale.hpp>
int main()
{
using namespace boost::locale;
generator gen;
}
Built with the following flags:
g++ -static -static-libstdc++ -pthread main.cpp -lboost_locale -lboost_system -licuuc -licudata -licui18n
Fails to link with the following errors:
(.text+0x16b8): undefined reference to `icu_60::CacheKeyBase::~CacheKeyBase()'
(.text+0x1c8d): undefined reference to `icu_60::UVector64::~UVector64()'
(.text+0x7dc): undefined reference to `icu_60::UCharsTrie::Iterator::~Iterator()'
...hundreds of other undefined symbols
...(the sample code also has boost linking errors, but let's ignore them, as they only appear in my attempt of reproduction; the real code I have issues with has only icu-related link errors)
I'm using Ubuntu 18.04, with both libboost-all-dev and libicu-dev installed from the Ubuntu repositories.
I'm probably missing some trivial component/flag/library needed to make it link together, but am unable to find it.

Undefined reference to boost::random::random_device constructor and destructor on MinGW-w64 gcc

My OS is Windows 7 64-bit and C++ compiler I'm using is:
g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 5.3.0
And I installed Boost version 1.60 using:
bootstrap.bat mingw
b2 install target=gcc
Then I tested is it working, using examples from Boost.Random tutorial.
With the first two everything was fine, but the third one gave linker errors about boost::random::random_device. I minimized the code to have only this:
// Compiled with:
// g++ -IC:/Boost/include/boost-1_60
// -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
// main.cpp
#include "boost/random/random_device.hpp"
int main() {
boost::random::random_device rng;
}
And I get the following errors:
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x15):
undefined reference to `boost::random::random_device::random_device()'
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x20):
undefined reference to `boost::random::random_device::~random_device()'
collect2.exe: error: ld returned 1 exit status
Here, on SO, I found that someone with similar problem added -lboost_system to flags, but for me it didn't helped.
Does anyone have any idea, why it isn't working? I checked, and I have random_device.hpp header in my Boost folder, with declarations of random_device() and ~random_device() in it.
I found what was wrong - the g++ command syntax, that I wanted to use to compile and link my code.
As I wrote in my question, I do this that way:
g++ -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60 main.cpp
While the correct one is with main.cpp (or any other source code file(s), that we want to include in compiling process) before the -L and -l flags.
For example:
g++ -IC:/Boost/include/boost-1_60 main.cpp -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
or even
g++ main.cpp -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
Hope it will help anyone, who will make such silly mistake too.

Octave sample code failing to compile in g++?

I'm attempting to get the Octave C++ code here to compile in g++ (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 4.6.4).
This trimmed version of the above will compile in g++:
#include <iostream>
#include <octave/oct.h>
using namespace std;
int main() {
// Matrix L=Matrix(2,2);
return 0;
}
but if I unremark out the line Matrix L=Matrix(2,2); then compile with g++ temp.cpp it gives the error message:
/tmp/ccTa3Am5.o: In function `Array2<double>::~Array2()':
temp.cpp:(.text._ZN6Array2IdED2Ev[_ZN6Array2IdED5Ev]+0x1f): undefined reference to `Array<double>::~Array()'
/tmp/ccTa3Am5.o: In function `Array<double>::Array(dim_vector const&)':
temp.cpp:(.text._ZN5ArrayIdEC2ERK10dim_vector[_ZN5ArrayIdEC5ERK10dim_vector]+0x26): undefined reference to `Array<double>::get_size(dim_vector const&)'
/tmp/ccTa3Am5.o:(.rodata._ZTV5ArrayIdE[vtable for Array<double>]+0x10): undefined reference to `Array<double>::~Array()'
/tmp/ccTa3Am5.o:(.rodata._ZTV5ArrayIdE[vtable for Array<double>]+0x18): undefined reference to `Array<double>::~Array()'
collect2: ld returned 1 exit status
I'm unsure why. Perhaps I'm missing an #include, perhaps I don't have an appropriate file installed, perhaps I'm not linking to the appropriate library, or perhaps I'm misusing Octave in some way.
Question: Why is this failing to compile? How can I fix it?
It compiles fine if I use mkoctfile --link-stand-alone temp.cpp as indicated at the above site, however, I'd like to use g++ if possible, since I eventually want to be able to call Octave functions from another program I've written in C++.
As indicated in my comment a simple example can be found in this Howto. So in your case a simple way to achieve compilation will be creating a makefile as follows:
makefile:
all: temp
clean:
-rm temp.o temp
temp: temp.o
mkoctfile --link-stand-alone -o temp temp.o
temp.o: temp.cpp
g++ -c -I$(OCTAVE_INCLUDE)
-I$(OCTAVE_INCLUDE)octave -o temp.o temp.cpp
$(OCTAVE_INCLUDE) is an environment variable that should be set to your octave include path (e.g. /usr/include/octave-x.x.xx). Then you can simply compile and link your test application using the command make all.
You need to link to the octave library. If the library is octave.a:
g++ -loctave temp.cpp
Add the library directories to your link command:
your-local-path\octave-x.x.xx\lib\
your-local-path\octave-x.x.xx\lib\octave\x.x.xx\
mkoctfile -L"\your-path\octave-x.x.xx\lib" -L"\your-path\octave-x.x.x\lib\octave\x.x.xx" --link-stand-alone temp.cpp
For cxx11 linker errors:
Converting std::__cxx11::string to std::string
"If you get linker errors about undefined references to symbols that involve types in the std::__cxx11 namespace or the tag [abi:cxx11] then it probably indicates that you are trying to link together object files that were compiled with different values for the _GLIBCXX_USE_CXX11_ABI macro. This commonly happens when linking to a third-party library that was compiled with an older version of GCC."
Defining the following macro before including any standard library headers should fix your problem:
#define _GLIBCXX_USE_CXX11_ABI 0

undefined referance to LibSerial

So i'm writing a serial transmision program, and have just changed over to using C++, it been a while since I used C++
(I've been working with C recently, and before that java)
Now I need to use LibSerial,
(it seems much simpler to use than C's termios)
my code is:
//gen1.cpp
#include "string2num.h" // a custom header
#include <iostream>
#include <SerialStream.h>
using namespace LibSerial;
//using namespace std;
int main(int argc, char*argv[])
{
if (argc<2)
{
std::cout<<argv[0]<<"requires the device name eg \"dev/tty0\" as a parameter\nterminating.\n";
return 1;
}
SerialStream theSerialStream(argv[1]); //open the device
return 0;
}
When I compile the output:
g++ -Wall -o gen1 gen1.cpp string2num.o
/tmp/cchPBWgx.o: In function `main':
gen1.cpp:(.text+0x121): undefined reference to `LibSerial::SerialStream::SerialStream(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Ios_Openmode)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x24): undefined reference to `LibSerial::SerialStreamBuf::showmanyc()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x28): undefined reference to `LibSerial::SerialStreamBuf::xsgetn(char*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x2c): undefined reference to `LibSerial::SerialStreamBuf::underflow()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x34): undefined reference to `LibSerial::SerialStreamBuf::pbackfail(int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x38): undefined reference to `LibSerial::SerialStreamBuf::xsputn(char const*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x3c): undefined reference to `LibSerial::SerialStreamBuf::overflow(int)'
collect2: ld returned 1 exit status
make: *** [gen1] Error 1
This is the linker complaining that it cannot find the functions referenced by the libserial header file.
If I look on my Linux system to see how the shared library is called:
$ dpkg -L libserial0
...
/usr/lib/libserial.so.0.0.0
/usr/lib/libserial.so.0
On my system this implies I would add -lserial as a g++ option (aka link with libserial.so) this would turn your compilation command into
g++ -Wall -lserial -o gen1 gen1.cpp string2num.o
Including the header file is not enough - you also need to link with the library that implements SerialStream. Assuming it is a static library called serstream.a (it is almost certainly actually called something else):
g++ -Wall -o gen1 gen1.cpp string2num.o serstream.a
old thread, but i still use Libserial. here the completed answer
My working setup.
Ubuntu 18.04
g++ 7.3.0
1) Install package for libserial
apt install libserial-dev
2) check for your headers(.h) and .so files
dpkg -l libserial0
dpkg -l libserial-dev
the first command give you the directory of shared library and the second gives you the headers location.
3) Your code.
I have to change a little your code, first i delete the custom header and modifing the constuctor call to this.
SerialStream theSerialStream;
4) compile with g++
Here my compiling command
g++ -o test -I/usr/include test.cpp -L/usr/lib/x86_64-linux-gnu -lserial -lpthread
check for the -lpthread linking option, beacuse Libserial uses mutex.
In Ubuntu/Debian make sure you have to libserial-dev package installed and use the '-lserial' flag for gcc.