Undefined Reference but Library Linked - c++

I'm currently trying to add the RaspiCam library found here:
https://sourceforge.net/projects/raspicam/?source=typ_redirect
To the Apriltags library found here:
http://people.csail.mit.edu/kaess/apriltags/
I unzipped the RaspiCam library and built it separately, then just copied and pasted it into the AprilTags folder. My AprilTags folder looks like this now:
AprilTags build cmake CMakeLists.txt example LICENSE Makefile pod-build raspicam-0.1.6 README.txt src systems.txt tags
Inside the raspicam-0.1.6 folder is this:
build Changelog CMakeLists.txt CMakeLists.txt.user cmake_uninstall.cmake.in dependencies README src utils
I add the library from raspicam to the top of my code in AprilTags as:
#include <raspicam/raspicam_cv.h>
and it detects it when I build. I know this because I purposefully wrote the library wrong, ex. raspicam_cvv.h, and it gave me an error because there is no library like that. So it definitely links. However, when I try to use the library in code with for example:
raspicam::RaspiCam_Cv Camera;
It gives this error:
CMakeFiles/apriltags_demo.dir/apriltags_demo.cpp.o: In function `main':
apriltags_demo.cpp:(.text.startup+0x2d4): undefined reference to `raspicam::RaspiCam_Cv::RaspiCam_Cv()'
apriltags_demo.cpp:(.text.startup+0x324): undefined reference to `raspicam::RaspiCam_Cv::~RaspiCam_Cv()'
apriltags_demo.cpp:(.text.startup+0x384): undefined reference to `raspicam::RaspiCam_Cv::~RaspiCam_Cv()'
collect2: error: ld returned 1 exit status
example/CMakeFiles/apriltags_demo.dir/build.make:139: recipe for target 'bin/apriltags_demo' failed
make[3]: *** [bin/apriltags_demo] Error 1
CMakeFiles/Makefile2:193: recipe for target 'example/CMakeFiles/apriltags_demo.dir/all' failed
make[2]: *** [example/CMakeFiles/apriltags_demo.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make[1]: *** [all] Error 2
Makefile:27: recipe for target 'all' failed
make: *** [all] Error 2
as an undefined reference. I did some research online and found a similar query here: library is linked but reference is undefined where the solution is to change the order in which you link. However, because both projects are built using CMake, I don't know how you would change the order of linking.

NOTE - I would make this a comment if I could, need more rep:
Have you tried "" over <> for your include? <> is for predefined directories while "" follows a relative path
This may seem like an excess check, but did you make sure you have both the .lib and corresponding .h file for the library in the same directory? Lot of people have the .lib but are missing the .h for the lib
I come across this problem when I forget to do either of these two, whether in cmake or in visual c++ through vstudio

Related

Linking a prebuilt binary in cpp does not work?

I just build the following package: faiss and my cpp program now recognises all library header so I can include them into my program. But my programm throws undefined reference to. So when I built faiss it created a libfaiss.a and a libfaiss.so which one to link and how??? I think I have tried any solution that I could find in the internet, but my knowledge of the build/linking process is limited.
My Faiss build-directory looks like this:
faiss-1.5.3/
-libfaiss.a
-libfaiss.so
-foo.h
-foo.o
-foo.cpp
-bar.h
-...
My tries. (I am using ROS, catkin_simple and gtests)
So this is how I would usually do it:
find_library(LibFaiss faiss HINT /home/tim/faiss/faiss-1_5_3/faiss-1.5.3/)
catkin_add_gtest(test_inverted_nn test/test_inverted-nn.cc
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}})
target_link_libraries(test_inverted_nn ${LIBRARY_NAME} ${LibFaiss})
I get the following Error:
/usr/bin/ld: cannot find -lLibFaiss-NOTFOUND}
collect2: error: ld returned 1 exit status
CMakeFiles/test_inverted_nn.dir/build.make:358: recipe for target '/home/tim/catkin_ws/devel/lib/nn/test_inverted_nn' failed
make[3]: *** [/home/tim/catkin_ws/devel/lib/inverted_nn/test_inverted_nn] Error 1
I also found this Solution here Import an external library into a ROS node, but that does not work for me:
add_library(libfaiss STATIC IMPORTED)
set_target_properties(libfaiss PROPERTIES IMPORTED_LOCATION /home/tim/faiss/faiss-1_5_3/faiss-1.5.3/libfaiss.a)
target_link_libraries(test_inverted_nn ${LIBRARY_NAME} ${libfaiss})
This throws the following Error:
/usr/bin/ld: cannot find -l}
collect2: error: ld returned 1 exit status
EDIT
After correcting the not_found error I am getting the following error:
CMake Warning at /opt/ros/melodic/share/catkin/cmake/test/gtest.cmake:180 (add_executable):
Cannot generate a safe runtime search path for target
test_inverted_multi_index because files in some directories may conflict
with libraries in implicit directories:
runtime library [libz.so.1] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
/usr/local/lib
Some of these libraries may not be found correctly.
*** It does not matter what I add inside target_link_libraries I am always getting that error***
EDIT2
So with the tipp of #Aconcagua I deleted everything from the CMakeLists.txt and only added the following to my cmake options:
-DCMAKE_CXX_FLAGS=-L/home/tim/faiss/faiss-1_5_3/faiss-1.5.3/
But Im still getting the undefined reference errors. It does not make any difference

Make/Cmake subdirectory linking to external library fails

I'm currently having trouble in the following setup:
My main project has a subdirector that is a library. This library depends on a system library "triangle" (installed from source). The main project does use a file from the subdirectory.
Cmake of the main project (and the library) work fine.
Building the library works just fine.
(Either in it's own directory or after cmake in the main directory with
make subdir_lib compiles without problems)
This is where the problems starts.
Building the main project with make project fails. It happens during linking:
subdir/libsubdir_lib.a(Test.cpp.o): In function `Test::run()':
/home/mimre/workspace/tmp/cmake-problem/subdir/files/Test.cpp:34: undefined reference to `triangle_context_create'
/home/mimre/workspace/tmp/cmake-problem/subdir/files/Test.cpp:35: undefined reference to `triangle_context_options'
/home/mimre/workspace/tmp/cmake-problem/subdir/files/Test.cpp:42: undefined reference to `triangle_mesh_create'
/home/mimre/workspace/tmp/cmake-problem/subdir/files/Test.cpp:50: undefined reference to `triangle_context_destroy'
collect2: error: ld returned 1 exit status
CMakeFiles/cmake_problem.dir/build.make:95: recipe for target 'cmake_problem' failed
make[3]: *** [cmake_problem] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/cmake_problem.dir/all' failed
make[2]: *** [CMakeFiles/cmake_problem.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/cmake_problem.dir/rule' failed
make[1]: *** [CMakeFiles/cmake_problem.dir/rule] Error 2
Makefile:118: recipe for target 'cmake_problem' failed
make: *** [cmake_problem] Error 2
To avoid having a wall of code in here, I uploaded a minimal example onto github: https://github.com/mimre25/cmake_problem
Also, this is the library I'm using, installed with cmake & sudo make install: https://github.com/wo80/Triangle
I've tried the solutions from various similar threads but to no avail.
Thanks in advance for any help!
I would have written this as a comment but I don't have enough reputation for that. Is this a situation where you need to use this Triangle (https://github.com/wo80/Triangle), rather than the original Triangle (https://www.cs.cmu.edu/~quake/triangle.html)? If you can use the latter, I know from experience that its is very easy to link to. I just put it in a subdirectory in my code with this CMakeLists.txt.
## This only works for linux. Use an if statement to handle all architectures.
SET(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS} -O -DLINUX -DTRILIBRARY -w -DANSI_DECLARATORS"
)
SET(FILES_SOURCE
triangle.h triangle.c
)
ADD_LIBRARY( my_local_name_for_triangle_library STATIC ${FILES_SOURCE} )
And then I can link to the triangle library I have created like this:
include_directories(my_local_triangle_dir)
target_link_libraries(my_local_name_for_triangle_library)
However, some of the #define macros are missing in triangle.h, so you need to copy them from triangle.c to triangle.h.
It seems that you tried to link a library that doesn't exist (where CMake can find it).
You either need to create a find_library, or when you link to triangle, give a full path with name.
Alternatively, you can leave the source in a sub directory which you can call then link to the name.

How to correctly import freenect2 using cmake?

I have to use a kinect2 (ubuntu 16.04 LTS). So I installed several things :
OpenNi (https://github.com/OpenNI/OpenNI)
OpenNi2 (https://github.com/occipital/openni2
libfreenect, (because I used the first kinect before) (https://github.com/OpenKinect/libfreenect)
libfreenect2 (https://github.com/OpenKinect/libfreenect2)
PrimeSese (with the corresponding part of https://www.icyphy.org/accessors/wiki/Main/InstallingThePrimeSenseKinectSensorOnUbuntu)
OpenCV (https://github.com/opencv/opencv)
When I was using the first kinect I was able to import the libfreenect tools without an problem, but now way with libfreenect !
You can find my CMake here. There isn't any problem with the others libs in the CMake.
What I changed to install libfreenect2:
I clone the repository in my folder ~/sofware. (I put all my libs here)
Instead of
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/freenect2
I did
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/software/libfreenect2/freenect2
With my Cmake when I compile I got this:
CMakeFiles/Kinect2CaptureYM.dir/app/Kinect2CaptureYM.cpp.o: In function `Kinect2CaptureYM::Kinect2CaptureYM()':
Kinect2CaptureYM.cpp:(.text._ZN16Kinect2CaptureYMC1Ev[_ZN16Kinect2CaptureYMC1Ev]+0x108): undefined reference to `libfreenect2::Freenect2::Freenect2(void*)'
Kinect2CaptureYM.cpp:(.text._ZN16Kinect2CaptureYMC1Ev[_ZN16Kinect2CaptureYMC1Ev]+0x427): undefined reference to `libfreenect2::Freenect2::~Freenect2()'
CMakeFiles/Kinect2CaptureYM.dir/app/Kinect2CaptureYM.cpp.o: In function `Kinect2CaptureYM::~Kinect2CaptureYM()':
Kinect2CaptureYM.cpp:(.text._ZN16Kinect2CaptureYMD1Ev[_ZN16Kinect2CaptureYMD1Ev]+0xb8): undefined reference to `libfreenect2::Freenect2::~Freenect2()'
collect2: error: ld returned 1 exit status
CMakeFiles/Kinect2CaptureYM.dir/build.make:156: recipe for target 'Kinect2CaptureYM' failed
make[2]: *** [Kinect2CaptureYM] Error 1
CMakeFiles/Makefile2:190: recipe for target 'CMakeFiles/Kinect2CaptureYM.dir/all' failed
make[1]: *** [CMakeFiles/Kinect2CaptureYM.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
So my make isn't able to link the the freenec2 lib. But I don't understand why as I put this in my makefile:
FIND_PACKAGE(freenect2 REQUIRED)
LIST(APPEND INCLUDE_DIRS ${FREENECT2_INCLUDE_DIRS})
LIST(APPEND LIBRARIES ${FREENECT2_LIBRARIES})
Does someone know how to link it correctly ? I'm really stuck beacause of that :/
If you need anything else just ask, thx!
PS : The most important things in my code are (enough to make the make crash):
the include : #include <libfreenect2/libfreenect2.hpp>
the declaration : libfreenect2::Freenect2 freenect2;

How to link to static library?

I have an executable that links to a static library I build and another library that is provided to me already built.
I'm trying to get cmake to link to it but I always get the following error:
ld: library not found for -lsrc/thislibrary/libthislibrary.a
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [MyExecutable] Error 1
make[1]: *** [CMakeFiles/DocumentParserTests.dir/all] Error 2
make: *** [all] Error 2
These are my build instructions:
add_executable(MyExecutable tests/MyExecutable.cpp)
target_link_libraries(MyExecutable statictests)
target_link_libraries(MyExecutable myownlib)
target_link_libraries(MyExecutable src/thislibrary/libthislibrary.a)
Both statictests and myownlib build flawlessly.
CMake is running the link command from a different working directory than you expect. Instead of using bare relative paths in a CMakeLists.txt file, use the special variables ${CMAKE_SOURCE_DIR}, ${CMAKE_CURRENT_SOURCE_DIR}, ${CMAKE_BINARY_DIR}, etc.
For a quick cheat-sheet of the meanings of these, see http://www.cmake.org/Wiki/CMake_Useful_Variables, or see the CMake documentation.
In your case, I suspect the correct path location is this:
target_link_libraries(MyExecutable ${CMAKE_CURRENT_SOURCE_DIR}/src/thislibrary/libthislibrary.a)

undefined reference linking yaml-cpp program with mingw-w64 + cmake

I'm using mingw-w64 (4.8.0) + cmake to build shared libraries for yaml-cpp (0.5.1). The project has a few build targets in the CMakeLists.txt that comes with it: the main library yaml-cpp and some test programs e.g. parse, which links the library.
The library target yaml-cpp itself built without error but it is followed by this error when parse is built:
Linking CXX executable parse.exe
CMakeFiles\parse.dir/objects.a(parse.cpp.obj):parse.cpp:(.text+0x1a3): undefined reference to `YAML::Load(std::istream&)'
CMakeFiles\parse.dir/objects.a(parse.cpp.obj):parse.cpp:(.text+0x1b2): undefined reference to `YAML::operator<<(std::ostream&, YAML::Node const&)'
c:/work/mingw64-4.8/bin/../lib/gcc/x86_64-w64-mingw32/4.8.0/../../../../x86_64-w64-mingw32/bin/ld.exe: CMakeFiles\parse.dir/objects.a(parse.cpp.obj): bad reloc address 0x0 in section `.data'
collect2.exe: error: ld returned 1 exit status
util\CMakeFiles\parse.dir\build.make:90: recipe for target 'util/parse.exe' failed
mingw32-make[3]: *** [util/parse.exe] Error 1
CMakeFiles\Makefile2:228: recipe for target 'util/CMakeFiles/parse.dir/all' failed
mingw32-make[2]: *** [util/CMakeFiles/parse.dir/all] Error 2
CMakeFiles\Makefile2:240: recipe for target 'util/CMakeFiles/parse.dir/rule' failed
mingw32-make[1]: *** [util/CMakeFiles/parse.dir/rule] Error 2
makefile:211: recipe for target 'parse' failed
mingw32-make: *** [parse] Error 2
I run into similar errors when I try to write small test programs using the library, and I don't know what is wrong. What might be the issue here?
Jesse Beder's comment points to the exact issue causing the error described in the question. A quick fix while this gets fixed in a follow-up release is to apply the patch (https://code.google.com/p/yaml-cpp/issues/detail?id=216#c4) to a clean copy of yaml-cpp 0.5.1. There is also a line that declares std::string node_data::empty_scalar in the source file src/node_data.cpp that should be commented out. After making these changes, the shared libraries and utilities build without error.