简体   繁体   中英

gstreamer plugin library not linking against opencv shared object library - “undefined symbol” on Ubuntu

I have tried this for now whole weekend - Saturday/Sunday and Monday spending couple of hours but to no avail. I am following the gstreamer plugin writer's guide http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/section-boiler-project-stamp.html . I had gstreamer-0.10 (sudo apt-get install method) and OpenCV 2.4 already installed before trying gstreamer plugin procedure. I am using default prefix ( /usr/local/lib/gstreamer-0.10 for plugin testing during ./configure prior to sudo make && sudo make install )

I managed to generate the boilerplate code. Now I added a cvcreateImage like

static GstFlowReturn
gst_cvtestfilter_chain (GstPad * pad, GstBuffer * buf)
{
Gstcvtestfilter *filter;
GstBuffer *outbuf;
IplImage* cvImage = cvCreateImage(cvSize(cvwidth,cvheight),cvdepth, cvchannels);
.
.
}

If cvImage line is commented everything works smoothly. All tests are ok. Linking against OpenCV fails for some reason if I don't comment that line.

I modified the makefile.am to add OpenCV flags in src directory as

 # Note: plugindir is set in configure

##############################################################################
# TODO: change libgstcvtestfilter.la to something else, e.g. libmysomething.la     #
##############################################################################
plugin_LTLIBRARIES = libgstcvtestfilter.la

##############################################################################
# TODO: for the next set of variables, name the prefix if you named the .la, #
#  e.g. libmysomething.la => libmysomething_la_SOURCES                       #
#                            libmysomething_la_CFLAGS                        #
#                            libmysomething_la_LIBADD                        #
#                            libmysomething_la_LDFLAGS                       #
##############################################################################

# sources used to compile this plug-in
libgstcvtestfilter_la_SOURCES = gstcvtestfilter.c gstcvtestfilter.h

# compiler and linker flags used to compile this plugin, set in configure.ac
libgstcvtestfilter_la_CFLAGS = $(GST_CFLAGS) $(OPENCV_CFLAGS)
libgstcvtestfilter_la_LIBADD = $(GST_LIBS) $(OPENCV_LIBS)
libgstcvtestfilter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) 
libgstcvtestfilter_la_LIBTOOLFLAGS = --tag=disable-static

# headers we need but don't want installed
noinst_HEADERS = gstcvtestfilter.h

I also modified configure.ac in the parent directory by adding

 dnl *** opencv ***
translit(dnm, m, l) AM_CONDITIONAL(USE_OPENCV, true)

  dnl we specify a max. version too because we set CV_NO_BACKWARD_COMPATIBILITY
  dnl and don't want the build to break when a new opencv version comes out.
  dnl Need to adjust this upwards once we know that our code compiles fine with
  dnl a new version and the no-backward-compatibility define. (There doesn't
  dnl seem to be a switch to suppress the warnings the cvcompat.h header
  dnl causes.)
  PKG_CHECK_MODULES(OPENCV, opencv >= 2.0.0 opencv <= 3.1.0 , [
    AC_PROG_CXX
    AC_LANG_CPLUSPLUS
    OLD_CPPFLAGS=$CPPFLAGS
    CPPFLAGS=$OPENCV_CFLAGS
    AC_CHECK_HEADER(highgui.h, HAVE_HIGHGUI="yes", HAVE_HIGHGUI="no")
    AC_CHECK_HEADER(cvaux.h, HAVE_CVAUX="yes", HAVE_CVAUX="no")
    CPPFLAGS=$OLD_CPPFLAGS
    AC_LANG_C
    if test "x$HAVE_HIGHGUI" = "xno"; then
      AC_MSG_RESULT(highgui.h could not be found.)
      HAVE_OPENCV="no"
    elif test "x$HAVE_CVAUX" = "xno"; then
      AC_MSG_RESULT(cvaux.h could not be found.)
      HAVE_OPENCV="no"
    else
      HAVE_OPENCV="yes" 
      AC_SUBST(OPENCV_CFLAGS)
      AC_SUBST(OPENCV_LIBS)  
    fi
  ], [
    HAVE_OPENCV="no"
    AC_MSG_RESULT(no)
  ])

The compilation is fine - no errors.

Now when I run the plugin in pipeline I get this message

(gst-plugin-scanner:6396): GStreamer-WARNING **: Failed to load plugin '/usr/local/lib/gstreamer-0.10/libgstcvtestfilter.so': /usr/local/lib/gstreamer-0.10/libgstcvtestfilter.so: undefined symbol: cvCreateImage

So obviously my opencv situated in /usr/local/lib is not linking properly.

sudo gedit /etc/bash.bashrc contains

#Added By me
PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH

#Added By me
PATH=$PATH:/opt/Xilinx/13.4/ISE_DS/ISE/bin/lin
export PATH

GST_PLUGIN_PATH=$GST_PLUGIN_PATH:/usr/local/lib/gstreamer-0.10
export GST_PLUGIN_PATH

sudo gedit /etc/ld.so.conf.d/opencv.conf contains

/usr/local/lib

sudo gedit /etc/ld.so.conf.d/gst.conf contains

/usr/local/lib/gstreamer-0.10

sudo ldconfig -v

sudo gedit ~/.bashrc contains

export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib/gstreamer-0.10

ldd /usr/local/lib/gstreamer-0.10/libgstcvtestfilter.so gives no opencv dependency which is strange

linux-gate.so.1 =>  (0xb77b6000)
libgstreamer-0.10.so.0 => /usr/lib/i386-linux-gnu/libgstreamer-0.10.so.0 (0xb76b0000)
libgobject-2.0.so.0 => /usr/lib/i386-linux-gnu/libgobject-2.0.so.0 (0xb7661000)
libglib-2.0.so.0 => /lib/i386-linux-gnu/libglib-2.0.so.0 (0xb7567000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb754c000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb73a7000)
libgmodule-2.0.so.0 => /usr/lib/i386-linux-gnu/libgmodule-2.0.so.0 (0xb73a2000)
libxml2.so.2 => /usr/lib/i386-linux-gnu/libxml2.so.2 (0xb7255000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7228000)
librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb721f000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb721a000)
libffi.so.6 => /usr/lib/i386-linux-gnu/libffi.so.6 (0xb7213000)
libpcre.so.3 => /lib/i386-linux-gnu/libpcre.so.3 (0xb71d7000)
/lib/ld-linux.so.2 (0xb77b7000)
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0xb71c0000)

My OS is 32 bit 12.04 Ubuntu. If anyone can point me right direction I shall be grateful. Thanks.

Update: (June 29 2012)

Taking Cue from OpenCV experience I modified the configure.ac for OpenGL if someone is interested

AC_CHECK_HEADER(
    GL/gl.h,
    AC_DEFINE(
        [HAVE_OPENGL],
        [],
        Define to 1 if you have the <GL/gl.h> header file.
        )
        OPENGL_LIBS="$X_LIBS -lGL -lGLU -lpthread -lglut -lGLEW"
        opengl=yes,
    AC_MSG_WARN([*** no GL/gl.h -- opengl and SDL support disabled])
)
AC_SUBST(OPENGL_CFLAGS)
AC_SUBST(OPENGL_LIBS)


dnl AC_ARG_WITH(
dnl     opengl-cflags,
dnl     [  --with-opengl-cflags=PATH    Specify OpenGL cflags],
dnl     OPENGL_CFLAGS="$withval", OPENGL_CFLAGS="")
dnl AC_ARG_WITH(
dnl     opengl-libs,
dnl     [  --with-opengl-libs=PATH      Specify OpenGL libs (default is -lGL -lGLU -lpthread)],
dnl     OPENGL_LIBS="$withval", OPENGL_LIBS="-lGL -lGLU -lpthread -lglut -lGLEW")
dnl AC_SUBST(OPENGL_CFLAGS)
dnl AC_SUBST(OPENGL_LIBS)

I know that the question was related to version 0.1 of GStreamer, but I've come across with a similar error with GStreamer v1.4.5 when compiling from source, and with OpenCV 2.4.10.1 also compiled from source.

In my case, running gst-inspect-1.0 would print the following message:

(gst-plugin-scanner:7485): GStreamer-WARNING **: Failed to load plugin '/usr/local/lib/gstreamer-1.0/libgstopencv.so': /usr/local/lib/gstreamer-1.0/libgstopencv.so: undefined symbol: cvCloneImage
...
...
Total count: 196 plugins (1 blacklist entry not shown), 1109 features

My solution was inspired in the solution 2 from here , but instead of changing source files just pass the OPENCV_LIBS environment variable to autogen.sh.

OPENCV_LIBS="-lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lopencv_gpu -lopencv_legacy -lopencv_nonfree -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_videostab" ./autogen.sh

You may need to adjust the libraries depending on the used build configuration.

Here is my output from pkg-config --libs opencv :

/usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_ocl.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_superres.so /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl

I managed to solve this problem consulting a friend with an ugly hack in Makefile in src directory.

Solution I

LIBS = was empty so had to add OpenCV libraries there as follows.

LDFLAGS =
LIBOBJS =
LIBS = -lopencv_core -lopencv_highgui # One may add more OpenCV libraries as needed here
LIBTOOL = $(SHELL) $(top_builddir)/libtool

Solution II (Better Solution Comes Along - But Still Ugly)

Leave LIBS = empty but edit OPENCV_LIBS= in the Makefile .

In my case I had

OPENCV_LIBS = /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_core.so ...

I replaced this line by

OPENCV_LIBS = -lopencv_highgui -lopencv_core ... so on and so forth.

Replace this for all OpenCV libraries as needed in the Makefile at this line and it should work.

Solution III (Preferred) Change Makefile.am as follows and add all OpenCV libraries as necessary.

 # Note: plugindir is set in configure

##############################################################################
# TODO: change libgstcvtestfilter.la to something else, e.g. libmysomething.la     #
##############################################################################
plugin_LTLIBRARIES = libgstcvtestfilter.la

##############################################################################
# TODO: for the next set of variables, name the prefix if you named the .la, #
#  e.g. libmysomething.la => libmysomething_la_SOURCES                       #
#                            libmysomething_la_CFLAGS                        #
#                            libmysomething_la_LIBADD                        #
#                            libmysomething_la_LDFLAGS                       #
##############################################################################

# sources used to compile this plug-in
libgstcvtestfilter_la_SOURCES = gstcvtestfilter.c gstcvtestfilter.h

# compiler and linker flags used to compile this plugin, set in configure.ac
libgstcvtestfilter_la_CFLAGS = $(GST_CFLAGS) $(OPENCV_CFLAGS)
libgstcvtestfilter_la_LIBADD = $(GST_LIBS) $(OPENCV_LIBS) -lopencv_highgui -lopencv_core
libgstcvtestfilter_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) 
libgstcvtestfilter_la_LIBTOOLFLAGS = --tag=disable-static

# headers we need but don't want installed
noinst_HEADERS = gstcvtestfilter.h

There is difference in the way opencv 2.3.1 and 2.4.0 is installed as can be seen from /usr/local/lib/pkgconfig/opencv.pc

/usr/local/lib/pkgconfig/opencv.pc file should look as follows: (The PC on which this gstreamer opencv plugin is installed works fine - Ubuntu 10.04)

# Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.3.1
Libs: -L${libdir} -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann
Cflags: -I${includedir_old} -I${includedir_new}

instead of (The PC on which this gstreamer opencv plugin is installed needs Makefile modification - Ubuntu 12.04):

# Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.4.0
Libs:  ${exec_prefix}/lib/libopencv_calib3d.so ${exec_prefix}/lib/libopencv_contrib.so ${exec_prefix}/lib/libopencv_core.so ${exec_prefix}/lib/libopencv_features2d.so ${exec_prefix}/lib/libopencv_flann.so ${exec_prefix}/lib/libopencv_gpu.so ${exec_prefix}/lib/libopencv_highgui.so ${exec_prefix}/lib/libopencv_imgproc.so ${exec_prefix}/lib/libopencv_legacy.so ${exec_prefix}/lib/libopencv_ml.so ${exec_prefix}/lib/libopencv_nonfree.so ${exec_prefix}/lib/libopencv_objdetect.so ${exec_prefix}/lib/libopencv_photo.so ${exec_prefix}/lib/libopencv_stitching.so ${exec_prefix}/lib/libopencv_ts.so ${exec_prefix}/lib/libopencv_video.so ${exec_prefix}/lib/libopencv_videostab.so
Cflags: -I${includedir_old} -I${includedir_new}

I'll post better solution if I can find any.

Did the configure run actualy find the opencv libraries? Check config.log. Also what exacly have you changed in the configure.ac part? As you noticed correctly the generated makefile is supposed to have those vars expanded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM