1 | initial version |
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.
"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 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.
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
.
-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
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.)
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.)
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
2 | No.2 Revision |
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.
"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 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.
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
.
-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
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.)
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.)
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
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