Undefined symbol using emcmake (emscripten and opencv) - opencv

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.)

Related

CMake does not find OpenCV

I seem to have an issue with my CMakeLists and opencv.
I am currently using opencv version 2.4 which is confirmed by
pkg-config --modversion opencv
2.4.8
and
dpkg -l libopencv*
which outputs http://pastebin.com/ZJEfLjDX
But for some reason when i cmake a simple program such as
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int argc, char** argv )
{
if ( argc != 2 )
{
printf("usage: DisplayImage.out <Image_Path>\n");
return -1;
}
Mat image;
image = imread( argv[1], 1 );
if ( !image.data )
{
printf("No image data \n");
return -1;
}
namedWindow("Display Image", WINDOW_AUTOSIZE );
imshow("Display Image", image);
waitKey(0);
return 0;
}
Will cmake not continue due to this error.
CMake Error at /opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVModules.cmake:183 (message):
The imported target "opencv_core" references the file
"/opt/ros/indigo/lib/libopencv_core3.so.3.1.0"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
"/opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVModules.cmake"
but not all the files it references.
Call Stack (most recent call first):
/opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVConfig.cmake:86 (include)
CMakeLists.txt:3 (find_package)
-- Configuring incomplete, errors occurred!
with this CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project( DisplayImage )
find_package( OpenCV REQUIRED )
add_executable( DisplayImage DisplayImage.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
The project has no ros dependency, and I have no idea why it is looking for OpenCVConfig.cmake inside ros.
A simple locate shows that the correct version is available other places
locate OpenCVConfig.cmake
/home/k/opencv/opencv-2.4.8/build/OpenCVConfig.cmake
/home/k/opencv/opencv-2.4.8/build/unix-install/OpenCVConfig.cmake
/home/k/opencv/opencv-2.4.8/cmake/OpenCVConfig.cmake
/home/k/opencv/opencv-2.4.8/cmake/templates/OpenCVConfig.cmake.in
/opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVConfig.cmake
/usr/local/share/OpenCV/OpenCVConfig.cmake
/usr/share/OpenCV/OpenCVConfig.cmake
but why does it choose to use the one from ros, which I am not sure is even an option if I don't have opencv3.1.0-dev installed?
I know that a solution to this problem would be SET the path. But why can't find_package make use of the 2.4.8 version? I even tried to change the filename of /opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVConfig.cmake to /opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVConfig.cmake.old, which caused the same error?... Why is cmake not able to find opencv by simple using find_package( OpenCV REQUIRED ), and how do I make it so that it possible to find using this.

Opencv 'undefined reference to `cv::namedWindow....' (linking error)

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!

CMake linking error with OpenCV libraries

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.

Linker can not find OpenCV libraries when using CMake

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++.

Error linking to OpenCV after restructure of code

I've just reorganised my code (which worked before) and am now getting an error message when I run my executable: The program can't start because opencv_core230d.dll is missing from your computer. The error is accurate, I only have .lib library files for OpenCV, but it worked before and I don't think this should be a problem, should it?
An extract from the cmake file is:
FIND_PACKAGE( OpenCV REQUIRED )
# Define LIBRARY and SRC_FILES to create my library
add_library(${LIBRARY} ${SRC_FILES})
target_link_libraries(${LIBRARY} ${OpenCV_LIBS} )
# Define appName and appFile to create application,
# and link to my library and OpenCV
add_executable(${appName} ${appFile})
target_link_libraries(${appName} ${LIBRARY} ${OpenCV_LIBS})
Am I doing anything obviously wrong, or what else might cause this error?
EDIT: I've now reduced this problem to a minimal example. Inside one directory test I have two files: testApp.cpp and CMakeLists.txt as follows:
testApp.cpp
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[])
{
cv::namedWindow("Test");
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(test)
FIND_PACKAGE( OpenCV REQUIRED )
add_executable(appName testApp.cpp)
target_link_libraries(appName ${OpenCV_LIBS})
message(STATUS "Linking testapp to: ${OpenCV_LIBS}")
With the error as before: opencv_highgui230d.dll is missing.
The problem is that the environment variable PATH does not point to the location where OpenCV's DLLs reside. Search inside OpenCV directories and if you can't find it you'll need to reinstall OpenCV.
Seems this is a common problem which simply needed some more research. To fix, I just added the OpenCV/bin directory to the PATH environmental variable. Still not sure why it was working previously though...

Resources