Ask Your Question

Revision history [back]

There's a lot to unpack here, so I'll go section-by-section:

NOTE: This is long enough that it's collapsed by default. Don't overlook the little (more) link at the end.

But what is DSO and what it has to do with the command line?

"DSO" is short for "Dynamic Shared Object" and it's platform-agnostic jargon for a .so, .dylib, or .dll file, as fits the platform.

I've written almost no C++ (Python mainly), but I believe "error adding symbols: DSO missing from command line" means "Your code references this library, but you didn't ask me to link it in. I don't know which one was a mistake, so please either edit your code to not use it or add a -l for it to your g++ ... command and try again."

I would not ask about symbol '_ZN2cv6imreadERKNS_6StringEi' gobbledegook.

I should probably explain it anyway. ld uses a symbol name lookup system that predates C++ and only work on strings for names, so, when multiple functions or methods have the same name, differing only in their arguments or what class they belong to, they need to be disambiguated.

I won't give a full guide to decoding _ZN2cv6imreadERKNS_6StringEi but I will point out the imread in the middle of it. The gobbledegook is how ld sees the version of imread that your code is trying to call.

I installed openCV using .sh script downloaded from

A quick caution. It doesn't look like you ran make install but, if you ever want to, I advise installing checkinstall and running that instead. It'll give you a wizard for building a .deb package from make install and then install it for you, making it easy to uninstall with sudo apt remove PACKAGE_NAME or track what got installed with dpkg -L PACKAGE_NAME.

find / -name opencv_imgcodecs

-name does exact string matching, so find / -name opencv_imgcodecs (without any wildcards) should return no results.

If you've had time for your nightly updatedb run to occur since installing your libraries, I'd suggest locate opencv_imgcodecs as the fastest solution for finding them. (locate does substring matching, so no wildcards are needed)

...bearing in mind that, if you move a file, locate won't know until the next updatedb.

Another quick solution which will only cover stuff installed by checkinstall or distro-provided packages but which will tell you the name of the package providing it is dpkg -S opencv_imgcodecs.

Mine produces this output:

$ dpkg -S opencv_imgcodecs
opencv3: /usr/local/lib/libopencv_imgcodecs.so.3.2
opencv3: /usr/local/lib/libopencv_imgcodecs.so
opencv3: /usr/local/lib/libopencv_imgcodecs.so.3.2.0

(I could then get additional information by running apt-cache show opencv3 and apt-cache showpkg opencv3)

If you really must take the slowest approach, using find, my suggestion is to use this command:

for X in /{lib,usr/lib,usr/local/lib,home}; do find "$X" -name '*opencv_imgcodecs*'; done

It's equivalent to doing this, and will avoid wasting time checking places not in your library lookup path:

find /lib -name '*opencv_imgcodecs*'; done
find /usr/lib -name '*opencv_imgcodecs*'; done
find /usr/local/lib -name '*opencv_imgcodecs*'; done
find /home -name '*opencv_imgcodecs*'; done

After libopencv_imgcodecs.so.3.4 was moved out

ld should resolve -lopencv_imgcodecs to libopencv_imgcodecs.so (which is why there exists a library named libiberty.so (-liberty).) which should be a symlink to libopencv_imgcodecs.so.3.4 either directly or via a libopencv_imgcodecs.so.3 symlink.

First, try putting libopencv_imgcodecs.so.3.4 back where you found it and running sudo ldconfig.

(ld uses a cached index of where libraries are found and, if any package updates occurred in the interim, it would have been updated to not include libopencv_imgcodecs.so.3.4 at that location. Forgetting to run ldconfig after a make install was a big source of frustratingly confusing error messages back when I first got into Linux around the turn of the millennium.)

might have two versions of openCV installed and should uninstall one

First, I'd make sure that you're using the one you do have correctly before you potentially break things further.

I notice that you're not using the g++ command given by the page you linked.

I use OpenCV via Python, so none of the handful of C++ build commands I've put together have referenced OpenCV libraries, but my intuition tells me that you never tried adding -lopencv_imgcodecs to your g++ command before you moved libopencv_imgcodecs.so.3.4.

Also, don't automatically assume that having more than one OpenCV installed is causing your problems. Libraries are designed for a certain amount of that because some programs may need one version and some may need another.

The problem is when the linker gets confused about which version it's supposed to be using, or tries to mix pieces of one with pieces of another... and I don't see that as being a problem with the fresh install you described.

(And, even if it was, you should first try temporarily altering variables like LD_LIBRARY_PATH before trying things that are harder to undo like removing packages.)

pkg-config

Note that the g++ command they gave does not use manually-specified -l flags like in your example command. Instead, it uses pkg-config --cflags --libs <OpenCV_Home_Dir>/installation/OpenCV-3.4.4/lib/pkgconfig/opencv.pc which will provide them for you.

pkg-config is a standardized Linux tool for allowing libraries to specify how to link to them, and allowing you to request that information to automatically build compiler commands.

Judging by your example command, this should be what you want:

g++ -std=c++11 decolor.cpp -o fish pkg-config --cflags --libs /home/a/Downloads/installation/OpenCV-3.4.4/lib/pkgconfig/opencv.pc

Backticks in a shell command mean "Run the command between the backticks and substitute its output into the command line.

On my system, pkg-config --cflags --libs /usr/local/lib/pkgconfig/opencv.pc returns this output:

-I/usr/local/include/opencv -I/usr/local/include -L/usr/local/lib -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dpm -lopencv_freetype -lopencv_fuzzy -lopencv_line_descriptor -lopencv_optflow -lopencv_reg -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_rgbd -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_face -lopencv_plot -lopencv_dnn -lopencv_xfeatures2d -lopencv_shape -lopencv_video -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_xobjdetect -lopencv_objdetect -lopencv_ml -lopencv_xphoto -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_photo -lopencv_imgproc -lopencv_core

There's a lot to unpack here, so I'll go section-by-section:

NOTE: This is long enough that it's collapsed by default. Don't overlook the little (more) link at the end.

But what is DSO and what it has to do with the command line?

"DSO" is short for "Dynamic Shared Object" and it's platform-agnostic jargon for a .so, .dylib, or .dll file, as fits the platform.

I've written almost no C++ (Python mainly), but I believe "error adding symbols: DSO missing from command line" means "Your code references this library, but you didn't ask me to link it in. I don't know which one was a mistake, so please either edit your code to not use it or add a -l for it to your g++ ... command and try again."

I would not ask about symbol '_ZN2cv6imreadERKNS_6StringEi' gobbledegook.

I should probably explain it anyway. ld uses a symbol name lookup system that predates C++ and only work on strings for names, so, when multiple functions or methods have the same name, differing only in their arguments or what class they belong to, they need to be disambiguated.

I won't give a full guide to decoding _ZN2cv6imreadERKNS_6StringEi but I will point out the imread in the middle of it. The gobbledegook is how ld sees the version of imread that your code is trying to call.

I installed openCV using .sh script downloaded from

A quick caution. It doesn't look like you ran make install but, if you ever want to, I advise installing checkinstall and running that instead. It'll give you a wizard for building a .deb package from make install and then install it for you, making it easy to uninstall with sudo apt remove PACKAGE_NAME or track what got installed with dpkg -L PACKAGE_NAME.

find / -name opencv_imgcodecs

-name does exact string matching, so find / -name opencv_imgcodecs (without any wildcards) should return no results.

If you've had time for your nightly updatedb run to occur since installing your libraries, I'd suggest locate opencv_imgcodecs as the fastest solution for finding them. (locate does substring matching, so no wildcards are needed)

...bearing in mind that, if you move a file, locate won't know until the next updatedb.

Another quick solution which will only cover stuff installed by checkinstall or distro-provided packages but which will tell you the name of the package providing it is dpkg -S opencv_imgcodecs.

Mine produces this output:

$ dpkg -S opencv_imgcodecs
opencv3: /usr/local/lib/libopencv_imgcodecs.so.3.2
opencv3: /usr/local/lib/libopencv_imgcodecs.so
opencv3: /usr/local/lib/libopencv_imgcodecs.so.3.2.0

(I could then get additional information by running apt-cache show opencv3 and apt-cache showpkg opencv3)

If you really must take the slowest approach, using find, my suggestion is to use this command:

for X in /{lib,usr/lib,usr/local/lib,home}; do find "$X" -name '*opencv_imgcodecs*'; done

It's equivalent to doing this, and will avoid wasting time checking places not in your library lookup path:

find /lib -name '*opencv_imgcodecs*'; done
find /usr/lib -name '*opencv_imgcodecs*'; done
find /usr/local/lib -name '*opencv_imgcodecs*'; done
find /home -name '*opencv_imgcodecs*'; done

After libopencv_imgcodecs.so.3.4 was moved out

ld should resolve -lopencv_imgcodecs to libopencv_imgcodecs.so (which is why there exists a library named libiberty.so (-liberty).) which should be a symlink to libopencv_imgcodecs.so.3.4 either directly or via a libopencv_imgcodecs.so.3 symlink.

First, try putting libopencv_imgcodecs.so.3.4 back where you found it and running sudo ldconfig.

(ld uses a cached index of where libraries are found and, if any package updates occurred in the interim, it would have been updated to not include libopencv_imgcodecs.so.3.4 at that location. Forgetting to run ldconfig after a make install was a big source of frustratingly confusing error messages back when I first got into Linux around the turn of the millennium.)

might have two versions of openCV installed and should uninstall one

First, I'd make sure that you're using the one you do have correctly before you potentially break things further.

I notice that you're not using the g++ command given by the page you linked.

I use OpenCV via Python, so none of the handful of C++ build commands I've put together have referenced OpenCV libraries, but my intuition tells me that you never tried adding -lopencv_imgcodecs to your g++ command before you moved libopencv_imgcodecs.so.3.4.

Also, don't automatically assume that having more than one OpenCV installed is causing your problems. Libraries are designed for a certain amount of that because some programs may need one version and some may need another.

The problem is when the linker gets confused about which version it's supposed to be using, or tries to mix pieces of one with pieces of another... and I don't see that as being a problem with the fresh install you described.

(And, even if it was, you should first try temporarily altering variables like LD_LIBRARY_PATH before trying things that are harder to undo like removing packages.)

pkg-config

Note that the g++ command they gave does not use manually-specified -l flags like in your example command. Instead, it uses pkg-config --cflags --libs <OpenCV_Home_Dir>/installation/OpenCV-3.4.4/lib/pkgconfig/opencv.pc which will provide them for you.

pkg-config is a standardized Linux tool for allowing libraries to specify how to link to them, and allowing you to request that information to automatically build compiler commands.

Judging by your example command, this should be what you want:

g++ -std=c++11 decolor.cpp -o fish pkg-config `pkg-config --cflags --libs /home/a/Downloads/installation/OpenCV-3.4.4/lib/pkgconfig/opencv.pc

/home/a/Downloads/installation/OpenCV-3.4.4/lib/pkgconfig/opencv.pc`

Backticks in a shell command mean "Run the command between the backticks and substitute its output into the command line.

On my system, pkg-config --cflags --libs /usr/local/lib/pkgconfig/opencv.pc returns this output:

-I/usr/local/include/opencv -I/usr/local/include -L/usr/local/lib -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_aruco -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_dpm -lopencv_freetype -lopencv_fuzzy -lopencv_line_descriptor -lopencv_optflow -lopencv_reg -lopencv_saliency -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_rgbd -lopencv_surface_matching -lopencv_tracking -lopencv_datasets -lopencv_text -lopencv_face -lopencv_plot -lopencv_dnn -lopencv_xfeatures2d -lopencv_shape -lopencv_video -lopencv_ximgproc -lopencv_calib3d -lopencv_features2d -lopencv_flann -lopencv_xobjdetect -lopencv_objdetect -lopencv_ml -lopencv_xphoto -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_photo -lopencv_imgproc -lopencv_core