How to link to static library? - c++

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)

Related

Error with linking flag when using the cmake build for cppyy

I am trying to build the example for a make build for cppyy in the cppyy-knearestneighbors example (https://github.com/jclay/cppyy-knearestneighbors-example). From what I understand it used the more modern cppyy cmake.
However when it comes to the linking I find this error,
ld: unknown option: --no-as-needed
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [knn_example/libknn_exampleCppyy.dylib] Error 1
make[1]: *** [CMakeFiles/knn_exampleCppyy.dir/all] Error 2
make: *** [all] Error 2
I couldn't find away to remove this flag as it seems to be something internal to cppyy cmake. Is there any work around to fix the compilation?
I cannot talk about cppyy since I have never used it, but since it internally uses CMake, the issue that you have could control by the value of the LINK_WHAT_YOU_USE property.
I would first try to disable the default value of LINK_WHAT_YOU_USE with:
# When running cmake configure:
cmake -GNinja -DCMAKE_LINK_WHAT_YOU_USE=OFF
If it does not work, a more evolve approach which means iterating all of the targets and unsetting their LINK_WHAT_YOU_USE property. Let me know if you need help for this
https://cmake.org/cmake/help/latest/variable/CMAKE_LINK_WHAT_YOU_USE.html#variable:CMAKE_LINK_WHAT_YOU_USE

How to link libavformat in Cmake on mac?

I am trying to use the libavformat from ffmpeg in a C++ project. I have ffmpeg installed using homebrew.
My CMakeLists.txt :
cmake_minimum_required(VERSION 3.14)
project(av_test)
set(CMAKE_CXX_STANDARD 11)
INCLUDE_DIRECTORIES(/usr/local/Cellar/ffmpeg/4.2.1_2/include)
LINK_DIRECTORIES(/usr/local/Cellar/ffmpeg/4.2.1_2/lib)
add_executable(av_test main.cpp)
TARGET_LINK_LIBRARIES(av_test libavformat)
When running cmake I get this error:
ld: library not found for -llibavformat
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [av_test] Error 1
make[2]: *** [CMakeFiles/av_test.dir/all] Error 2
make[1]: *** [CMakeFiles/av_test.dir/rule] Error 2
make: *** [av_test] Error 2
A quick find libavformat* into /usr/local/Cellar/ffmpeg/4.2.1_2/lib returns:
libavformat.58.29.100.dylib
libavformat.58.dylib
libavformat.a
libavformat.dylib
Also in /usr/local/Cellar/ffmpeg/4.2.1_2/include/libavformat there is avformat.h
My main.cpp:
#include <libavformat/avformat.h>
int main() {
AVFormatContext *pFormatContext;
return 0;
}
I am running on mac os 10.14 with cmake version 3.15.5 , ffmpeg version 4.2.1
The problem here is noted from the error:
ld: library not found for -llibavformat
As you can see, it has both '-l' and 'lib' as prefix even though '-l' should replace 'lib' before the library name. It seems the TARGET_LINK_LIBRARIES function parses library names with a prefix -l (or lib) automatically attached. So, you need to write either of the following:
TARGET_LINK_LIBRARIES(av_test avformat)
TARGET_LINK_LIBRARIES(av_test -lavformat)
Adding -l at start doesn't make a difference, but is still accepted by cmake.

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.

Undefined Reference but Library Linked

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

Project Compilation Error - cannot find -lwxmsw28

While compiling a project i get the following error as
c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/ld.exe: cannot find lwxmsw28
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGW-Windows/libRegistration.dll] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
I am using wxwidgets libraries however when i ran a command in cmd as
wx-config --libs
i could not see lwxmsw28 either let me know if it is downloadable from somewhere or any workaround to resolve this issue.
Thanks
This is a linker error, rather than a compilation error.
"lwxmsw28" looks to me like a wxwidgets v2.8 microsoft windows library. Should the linker be looking for this? Since you are using mingw, I would think you should NOT be linking to msw libraries. However, I am not familiar with mingw, so maybe this is the name used for mingw libraries.
If this is the correct library, then the next question is: have you built the wxWidgets libraries? The libraries are NOT "downloadable from somewhere" - you must download the source and build the libraries yourself.
A simple test to find out if you have built the libraries - try to build one of the sample projects.