I'm using the following CMake file to build an opencv project using the command cmake followed by make.
cmake_minimum_required(VERSION 2.8)
project(t)
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} /home/keiths/opencv/opencv-2.4.11_build/build)
SET(CMAKE_C_COMPILER mpicc)
SET(CMAKE_CXX_COMPILER mpicxx)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(OpenCV REQUIRED)
find_package(MPI REQUIRED)
add_executable(t t.cpp)
target_link_libraries(t ${OpenCV_LIBS} ${OpenCV_LIBRARIES} opencv_core opencv_highgui opencv_calib3d opencv_contrib opencv_core opencv_features2d opencv_flann opencv_gpu opencv_highgui opencv_imgproc opencv_legacy opencv_ml opencv_nonfree opencv_objdetect opencv_ocl opencv_photo opencv_stitching opencv_superres opencv_ts opencv_video opencv_videostab rt pthread m dl)
MESSAGE(${OpenCV_LIBS})
MESSAGE(${OpenCV_INCLUDE_DIRS})
cmake completes fine, but make gives me the following error:
CMakeFiles/t.dir/t.cpp.o: In function main': t.cpp:(.text+0x56):
undefined reference to
cv::namedWindow(std::__cxx11::basic_string, std::allocator > const&, int)' collect2:
error: ld returned 1 exit status make[2]: * [t] Error 1 make[1]: *
[CMakeFiles/t.dir/all] Error 2 make: *** [all] Error 2
I've tried running the following command
g++ t.cpp $(pkg-config --libs opencv --cflags)
but get the following error
/home/keiths/tmp/ccWFcaXH.o: In function main': t.cpp:(.text+0x56):
undefined reference to
cv::namedWindow(std::__cxx11::basic_string, std::allocator > const&, int)' collect2:
error: ld returned 1 exit status
I'm running the following simple code
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
//#include <mpi.h>
using namespace cv;
int main(int argc, char **argv) {
Mat image;
namedWindow( "Display window", WINDOW_AUTOSIZE );
return 0;
}
I've tried as many recommendations as I can without success. Platform is CentOS and I'm a limited user (non-root) with my locally installed (more recent) versions of g++/gcc. I get the correct list of libraries for the pkg-config command and have configured library paths as well as the PATH to my local opencv folder
Just to add a very important point, I tried compiling the same code while explicitly specifying the stock g++ compiler (/usr/bin/g++) and all went well. So it seems that the problem would be with my local g++ compiler at '/home/keiths/lbin'. I need this latest version however for the c++11 capability (the old is 4.4.7 and it would take ages for the Sysadmin to upgrade it)
I had built my OpenCV library using the old g++ compiler (in the system bin folder), prior to building the latest g++. Rebuilding the OpenCV library using the new g++ compiler did it for me. Out of curiosity, I tried building the OpenCV example using the old compiler and it returned many 'undefined reference' lines, but I'm happy to swap problems since I don't need it anyway!
Related
I'm trying to build a minimalist project using OpenCV in the browser.
I've compiled OpenCV on my computer.
Here is the C++ code (josef.cpp):
#include <iostrem>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
int main(int argc, char **argv)
{
printf("Hello here\n");
cv::Mat m;
std::cout << m;
}
Here is the CMakeLists.txt :
cmake_minimum_required(VERSION 2.8)
project( josef )
# Give here the directory in which we have
# the file OpenCVConfig.cmake
set(OpenCV_DIR "/usr/local/lib/cmake/opencv4")
find_package( OpenCV REQUIRED )
add_executable( josef josef.cpp )
target_link_libraries( josef ${OpenCV_LIBS} )
Compiling with
cmake .
make
works perfectly well and provides an executable which produces the expected result:
Hello here
[]
My problem arises when trying with emscripten.
emcmake cmake .
produces lot of warnings like that one:
CMake Warning (dev) at /usr/local/lib/cmake/opencv4/OpenCVModules.cmake:393 (add_library):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking. Building a STATIC library instead. This may lead
to problems.
Call Stack (most recent call first):
/usr/local/lib/cmake/opencv4/OpenCVConfig.cmake:126 (include)
CMakeLists.txt:7 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
Then
emmake make
fails on undefined symbols:
error: undefined symbol: _ZN2cv3Mat10deallocateEv
warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
My question is : what do I wrong ? How to tell emscripten where are the famous missing symbols (these are the file .so if I understood correctly) ?
This is partially a hack solution.
In the file /usr/local/lib/cmake/opencv4/OpenCVModules.cmake, change every instances of "SHARED" by "STATIC".
In your cmake file, add the line
file( GLOB opencv_js "/path/to/opencvjs/opencv/build_js/lib/*.a")
This part supposes that you compiled opencv by hand.
then refer to my answer to my next question. (in short: use a canvas, do not use cv::imdecode.)
I downloaded the ffmpeg from git, and make the libs by sources. Created main.c as below and put the ffmpeg libs in the same folder as main.c, (my system is ubuntu 15.10, gcc version 5.2.1)
#include <stdio.h>
void av_register_all(void);
int main() {
printf("abc\n");
av_register_all();
return 0;
}
After I issued gcc main.c -L. -lavformat -lswscale -lavcodec -lswscale -lavutil -lavdevice -lavfilter, I got a lot of (nearly 1000) undefined reference errors:
...
/home/arton/sources/ffmpeg/libavcodec/vorbisdec.c:868: undefined reference to `atan'
/home/arton/sources/ffmpeg/libavcodec/vorbisdec.c:868: undefined reference to `atan'
/home/arton/sources/ffmpeg/libavcodec/vorbisdec.c:869: undefined reference to `atan'
/home/arton/sources/ffmpeg/libavcodec/vorbisdec.c:869: undefined reference to `atan'
/home/arton/sources/ffmpeg/libavcodec/vorbisdec.c:869: undefined reference to `floor'
...
/home/arton/sources is where the ffmpeg sources at, I have no idea why it report the sources path of ffmpeg and why the link fails. Any hint is appreciated. Thanks!
atan and floor are included in lm.
Do you link with lm?
You might want to read this.
I am using XAMPP and tried with a clean install of Ubuntu 12.04 in a VM, the results are the same.
The program bellow compile and link easily with:
gcc c_mysql.c -l mysqlclient -o c_mysql
That is, produces the default dynamically liked program.
But getting a statically linked program is not so easy:
I tried successively the following ways after extensive googling. Any help will be
really appreciated:
1) gcc c_mysql1.c libmysqlclient.a -o c_mysql
[Library libmysqlclient.a not found]
2) gcc c_mysql1.c /usr/lib/i386-linux-gnu/libmysqlclient.a -o c_mysql
[Many undefined references]
3) gcc c_mysql1.c /usr/lib/i386-linux-gnu/libmysqlclient.a /usr/lib/i386-linux-gnu/libdl.a
[Many but less undefined references]
4) gcc c_mysql1.c /usr/lib/i386-linux-gnu/libmysqlclient.a /usr/lib/i386-linux-gnu/libdl.a -lpthread -lz -o c_mysql
[The minimum undefined references I could get]
/usr/lib/i386-linux-gnu/libmysqlclient.a(client_plugin.c.o): In function `mysql_load_plugin_v':
(.text+0x524): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x42): undefined reference to `pow'
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x50): undefined reference to `log'
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x62): undefined reference to `pow'
/usr/lib/i386-linux-gnu/libdl.a(dlopen.o): In function `dlopen':
(.text+0x1b): undefined reference to `__dlopen'
/usr/lib/i386-linux-gnu/libdl.a(dlclose.o): In function `dlclose':
(.text+0x1): undefined reference to `__dlclose'
/usr/lib/i386-linux-gnu/libdl.a(dlsym.o): In function `dlsym':
(.text+0x1b): undefined reference to `__dlsym'
/usr/lib/i386-linux-gnu/libdl.a(dlerror.o): In function `dlerror':
(.text+0x1): undefined reference to `__dlerror'
collect2: ld returned 1 exit status
-static makes many more undefined references (-static-libgcc is even worst).
/usr/lib/i386-linux-gnu/libmysqlclient.a(client_plugin.c.o): In function `mysql_load_plugin_v':
(.text+0x524): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(mf_pack.c.o): In function `unpack_dirname':
(.text+0x653): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(libmysql.c.o): In function `read_user_name':
(.text+0x2a91): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(mf_pack.c.o): In function `unpack_dirname':
(.text+0x667): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(client.c.o): In function `mysql_real_connect':
(.text+0x47b6): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(libmysql.c.o): In function `mysql_server_init':
(.text+0x27fa): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x42): undefined reference to `pow'
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x50): undefined reference to `log'
/usr/lib/i386-linux-gnu/libmysqlclient.a(dh.cpp.o): In function `TaoCrypt::DH::GeneratePrivate(TaoCrypt::RandomNumberGenerator&, unsigned char*)':
(.text+0x62): undefined reference to `pow'
/usr/lib/i386-linux-gnu/libmysqlclient.a(my_compress.c.o): In function `my_compress_alloc':
(.text+0x68): undefined reference to `compress'
/usr/lib/i386-linux-gnu/libmysqlclient.a(my_compress.c.o): In function `my_uncompress':
(.text+0x1cf): undefined reference to `uncompress'
collect2: ld returned 1 exit status
#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
int main()
{
MYSQL mysql;
MYSQL_RES *res;
MYSQL_ROW row;
char *query = "select * from dbtablename;";
int t,r;
mysql_init(&mysql);
//if(!mysql_real_connect(&mysql,"localhost", "dbusername", "dbpassword", "dbname", port, NULL, 0)) The connection data is fake. If you, for a big miracle make it compile statically, the program will not connect.
if(!mysql_real_connect(&mysql,"192.231.182.73","PinData","YULYU7M", "DB084", 0, NULL, 0)){
printf("Error connecting to database:%s\n",mysql_error(&mysql));
}
else{
printf("Connected to the remote database........");
}
t=mysql_query(&mysql,query);
if(t)
{
printf("Error making query:%s\n",mysql_error(&mysql));
}
else
{
printf("Query made ....\n");
res = mysql_use_result(&mysql);
if(res)
{
for(r=0;r<=mysql_field_count(&mysql);r++)
{
row = mysql_fetch_row(res);
if(row<0) break;
for(t=0;t<mysql_num_fields(res);t++)
printf("%s ",row[t]);
printf("\n");
}
}
mysql_free_result(res);
}
mysql_close(&mysql);
return 0;
}
After many trial and error and google search, the answer is: To statically link libmysqlclient you have to use the following options:
-lpthread -lm -lz -ldl
This makes the linker find on some libraries.
That is:
gcc -static-libgcc c_mysql1.c /usr/lib/i386-linux-gnu/libmysqlclient.a -lpthread -lm -lz -ldl -o c_mysql
However the general question is still open: Given a static library StaticLib, how to know in advance which options and libraries to use.
I can not believe the answer would be " trial and error and google search"
I'm working on a project which uses OpenCV development libraries found on my package manager. I'm currently using two machines to work on this project, my laptop and my desktop. When I compile the code on my laptop, I have no issues. However, I'm getting a linking error on my desktop, which is strange because both machines have all corresponding libraries.
The error message complains about an undefined reference to a set of methods that should be getting linked, but cannot be found. Here's the output from cmake and make:
cmake:
malak#bigblackbox:~/Dropbox/libcardreader/release$ cmake .. && make
-- The C compiler identification is GNU 4.7.2
-- The CXX compiler identification is GNU 4.7.2
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/malak/Dropbox/libcardreader/release
make:
Scanning dependencies of target test
[ 33%] Building CXX object CMakeFiles/test.dir/test.cpp.o
[ 66%] Building CXX object CMakeFiles/test.dir/libimganalyzer.cpp.o
[100%] Building CXX object CMakeFiles/test.dir/libcardreader.cpp.o
Linking CXX executable test
CMakeFiles/test.dir/libimganalyzer.cpp.o: In function `cv::MSER::~MSER()':
libimganalyzer.cpp:(.text._ZN2cv4MSERD1Ev[_ZN2cv4MSERD1Ev]+0xe): undefined reference to `vtable for cv::MSER'
libimganalyzer.cpp:(.text._ZN2cv4MSERD1Ev[_ZN2cv4MSERD1Ev]+0x26): undefined reference to `vtable for cv::MSER'
libimganalyzer.cpp:(.text._ZN2cv4MSERD1Ev[_ZN2cv4MSERD1Ev]+0x2e): undefined reference to `VTT for cv::MSER'
libimganalyzer.cpp:(.text._ZN2cv4MSERD1Ev[_ZN2cv4MSERD1Ev]+0x55): undefined reference to `cv::Algorithm::~Algorithm()'
libimganalyzer.cpp:(.text._ZN2cv4MSERD1Ev[_ZN2cv4MSERD1Ev]+0x8a): undefined reference to `cv::Algorithm::~Algorithm()'
collect2: error: ld returned 1 exit status
make[2]: *** [test] Error 1
make[1]: *** [CMakeFiles/test.dir/all] Error 2
make: *** [all] Error 2
libimganalyzer.cpp has an #include statement to reference libimganalyzer.h and here is what I reference in libimganalyzer.h:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
If I use cat to look at the contents of features2d.hpp, which is where MSER is defined, it shows up:
malak#bigblackbox:~/Dropbox/libcardreader/release$ cat /usr/include/opencv2/features2d/features2d.hpp | grep MSER
typedef struct CvMSERParams
/////// the next few params for MSER of color image
} CvMSERParams;
CVAPI(CvMSERParams) cvMSERParams( int delta CV_DEFAULT(5), int min_area CV_DEFAULT(60),
CVAPI(void) cvExtractMSER( CvArr* _img, CvArr* _mask, CvSeq** contours, CvMemStorage* storage, CvMSERParams params );
/////// The class implements MSER algorithm introduced by J. Matas.
class CV_EXPORTS_W MSER : public CvMSERParams
CV_WRAP MSER();
CV_WRAP MSER( int _delta, int _min_area, int _max_area,
//! the operator that extracts the MSERs from the image or the specific part of it
MserFeatureDetector( CvMSERParams params=cvMSERParams() );
MSER mser;
malak#bigblackbox:~/Dropbox/libcardreader/release$
and here is the output of my CMakeLists.txt file:
set( CMAKE_AUTOMOC ON )
cmake_minimum_required(VERSION 2.8)
project( test )
find_package( OpenCV REQUIRED )
add_executable( test test.cpp libimganalyzer.cpp libimganalyzer.h libcardreader.cpp libcardreader.h )
target_link_libraries( test ${OpenCV_LIBS} )
I'd like to know what it is I lack on my desktop that lets me compile this project on my laptop without a hitch.
Update: I've tried multiple scenarios in terms of cmake and make on both my laptop and desktop and here's the results if it helps any:
cmake on desktop; make on desktop: cmake is successful, make throws error above.
cmake on desktop; make on laptop: cmake is successful, make is successful. Project runs.
cmake on laptop; make on desktop: cmake is successful, make is successful. Project runs.
cmake on laptop; make on laptop: cmake is successful, make is successful. Project runs.
I have a copy of OpenCV2.4.0 installed in /usr/local/lib
My program compiled properly but when the linker is evoked, it gave errors such as:
/home/zhouw/moos-ivp-zhouw/trunk/src/pATRTest/mst.cpp:661: undefined reference to 'cv::_OutputArray::_OutputArray(cv::Mat const&)'
CMakeFiles/pATR.dir/mst.cpp.o:/home/zhouw/moos-ivp-zhouw/trunk/src/pATRTest/mst.cpp:675: more undefined references to `cv::_OutputArray::_OutputArray(cv::Mat const&)'
collect2: ld returned 1 exit status
make[2]: *** [../bin/pATR] Error 1
make[1]: *** [src/pATRTest/CMakeFiles/pATR.dir/all] Error 2
make: *** [all] Error 2
The strange thing is my program uses opencv intensively, if CMake has trouble finding the libraries, it should have complained a lot more undefined references than jsut a few.
I tried adding
LINK_DIRECTORIES("/usr/local/lib") in my cmake file but it didn't help.
There's another library called POCO is also installed under /usr/local/lib. My program also links to the POCO libraries, but CMake seems having no trouble finding them.
If I manually link with -L/usr/local/lib, it would link properly without error.
The CMakeLists.txt looks like this
PROJECT(pATR)
#what files are needed?
SET(SRCS
spline.hpp
utils.hpp utils.cpp
mst.hpp mst.cpp
cluster.hpp cluster.cpp
target.hpp target.cpp
detector.hpp detector.cpp
classifier.hpp classifier.cpp
atr.hpp atr.cpp
MOOSAtr.h MOOSAtr.cpp
main.cpp
)
ADD_EXECUTABLE(pATR ${SRCS})
# indicate how to link
#LINK_DIRECTORIES("/usr/local/lib")
TARGET_LINK_LIBRARIES(pATR opencv_core opencv_highgui opencv_imgproc MOOS)
INSTALL(TARGETS
pATR
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
)
Any idea what's going on? Many thanks!
If you have CMake 2.8, I recommend using find_package(OpenCV) to load the libraries.
There is an example at http://docs.opencv.org/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.html
The CMake file:
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
You're after:
find_package(OPENCV COMPONENTS core imgproc highgui REQUIRED)
From the docs:
Packages with components
Some libraries are not monolithic, but come with one or more dependent
libraries or components. A notable example for this is the Qt library,
which ships (among others) with the components QtOpenGL and QtXml. To
use both of these components, use the following the find_package
command:
find_package(Qt COMPONENTS QtOpenGL QtXml REQUIRED)
also, for more info you may check out the following link.
https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-To-Find-Libraries
I am not sure if it makes sense that CMake can't find the linking libraries. CMake finds your dependencies and generates the Makefile, but it doesn't actually compile and link for you.
Your error are not from CMake, right? They are from make.
I always link manually with this
g++ -o myopencvapp `pkg-config --cflags --libs opencv` myopencvapp.cpp`
when invoking g++.