How to link libavformat in Cmake on mac? - c++

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.

Related

ld.lld: error: could not open 'libLIBCMTD.a': No such file or directory

I recently installed vspkg and tried to build my c++ application with libcurl using command vcpkg.exe install curl:x64-windows-static
After i tried to compile it, i got an error on linking stage
ld.lld: error: could not open 'libLIBCMTD.a': No such file or directory
ld.lld: error: could not open 'libOLDNAMES.a': No such file or directory
collect2.exe: error: ld returned 1 exit status
mingw32-make[3]: *** [CMakeFiles\testEnv.dir\build.make:140: C:/Users/Administrator/libtestEnv.dll] Error 1
mingw32-make[2]: *** [CMakeFiles\Makefile2:82: CMakeFiles/testEnv.dir/all] Error 2
mingw32-make[1]: *** [CMakeFiles\Makefile2:89: CMakeFiles/testEnv.dir/rule] Error 2
mingw32-make: *** [Makefile:123: testEnv] Error 2
I also tried to install curl library non-static and everything went successfully but i want to have everything linked as one libary so it's not a good solution
My CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(testEnv)
# remove names of functions and optimize
set(CMAKE_CXX_FLAGS "-nolibc -s -O3 -Os -fdata-sections -ffunction-sections -fvisibility=hidden -fvisibility-inlines-hidden -fuse-ld=lld")
set(CMAKE_CXX_STANDARD 17)
find_package(CURL CONFIG REQUIRED)
add_library(testEnv SHARED main.cpp)
target_link_libraries(testEnv CURL::libcurl)
#collect all needed libraries to run
target_link_libraries(testEnv -static)
Any ideas how to fix that problem with linking? Maybe there is any solutions which would allow to exclude those problematic libs?
mingw32-make
looks like you are using mingw. Consider using the correct vcpkg triplet, e.g. x64-mingw-static.cmake.
x64-windows-static will use an installed VS toolchain.
Be aware that you also need to set -DVCPKG_TARGET_TRIPLET=x64-mingw-static and -DVCPKG_HOST_TRIPLET=x64-mingw-static in your cmake call. Also make sure cmake does clean configure.

CMake does not link Boost correctly, but compiling from a terminal does

I am running Ubuntu 21.04 on a Raspberry Pi 4b (8gb), and am using QtCreator for an IDE, with default settings, which landed on Clang as a compiler.
Most code (excepting libconfig) ran perfectly fine, but for reasons unknown to me, linking Boost::filesystem and Boost::system is proving impossible. See the minimal code below for the snippet I have been testing with:
#include <boost/filesystem.hpp>
#include <iostream>
int main()
{
boost::filesystem::path full_path(boost::filesystem::current_path());
std::cout << "Current path is : " << full_path << std::endl;
return 0;
}
If I open a terminal on this source file, and run
clang++ main.cpp -lboost_system -lboost_filesystem
I get an output that behaves exactly as one'd expect, reporting '/home/username/repo/boostsandbox/'.
Now, if I attempt to compile with CMake, using the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(boostsandbox LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Compiler Options --------------------
add_compile_options(--verbose)
# Package Management ------------------
find_package( Boost COMPONENTS filesystem system REQUIRED)
include_directories(... ${Boost_INCLUDE_DIRS})
link_directories(... ${Boost_LIBRARY_DIRS})
message("Found Boost, {${Boost_LIBRARIES}}, at ${Boost_INCLUDE_DIR}")
add_executable(boostsandbox main.cpp)
link_libraries(boostsandbox Boost::filesystem Boost::system)
I receive the CMake parsing message 'Found Boost, {Boost::filesystem;Boost::system}, at /usr/include', and building halts at compile time, reporting the following:
/usr/bin/ld: CMakeFiles/boostsandbox.dir/main.cpp.o: in function `boost::filesystem::current_path()':
/usr/include/boost/filesystem/operations.hpp:244: undefined reference to `boost::filesystem::detail::current_path(boost::system::error_code*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[2]: *** [CMakeFiles/boostsandbox.dir/build.make:133: boostsandbox] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/boostsandbox.dir/all] Error 2
gmake: *** [Makefile:103: all] Error 2
10:13:31: The process "/usr/bin/cmake" exited with code 2.
I am starting to feel like I've used every trick possible by now (including the C++11 enum define that gets Boost to work for some people), but I'm completely stumped. Please help!
TLDR:
Compiling with g++ or clang++, linking lboost_filesystem + lboost_system, building and executing functions perfectly. Building via the QtCreator IDE using CMake, compilation halts on a linking error, while Boost is found and linked.

How do I configure the way a project is built in CLion?

The problem is as follows.
I have installed libarmadillo on my Ubuntu distributive via apt utility having liblapack and libblas previously installed. And I'm trying to use it in my CLion project. What my intentions result in is that I'm receiving some build errors. One of them was solved by adding #define ARMA_DONT_USE_WRAPPER.
I have found the way to build my project in this topic -
Armadillo + BLAS + LAPACK: Linking error?. Though, I can build it only with terminal. I assume that the issue with CLion is CMake configuration.
What is the way for me to alter CMake script so that I refine its built behavior and make it compile my project?
In simple words, how do I make it compile my program with g++ main.cpp -o lab2 -O1 -llapack -lblas.
Code sample:
#define ARMA_DONT_USE_WRAPPER
#define ARMA_USE_BLAS
#define ARMA_USE_LAPACK
#include <armadillo>
#include <iostream>
using namespace arma;
using namespace std;
int main() {
mat A(4, 5);
A.load("matrix.txt");
mat B = resize(A, 4, 4);
cout << norm(A, 2);
cout << B;
return 0;
}
The errors I'm issued:
CMakeFiles/lab2.dir/main.cpp.o: In function `double
arma::blas::asum<double>(unsigned long long, double const*)':
/usr/include/armadillo_bits/wrapper_blas.hpp:241: undefined reference
to `dasum_'
CMakeFiles/lab2.dir/main.cpp.o: In function `double
arma::blas::nrm2<double>(unsigned long long, double const*)':
/usr/include/armadillo_bits/wrapper_blas.hpp:273: undefined reference
to `dnrm2_'
collect2: error: ld returned 1 exit status
CMakeFiles/lab2.dir/build.make:94: recipe for target 'lab2' failed
make[3]: *** [lab2] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/lab2.dir/all'
failed
make[2]: *** [CMakeFiles/lab2.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/lab2.dir/rule'
failed
make[1]: *** [CMakeFiles/lab2.dir/rule] Error 2
Makefile:118: recipe for target 'lab2' failed
make: *** [lab2] Error 2
CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(lab2)
set(CMAKE_CXX_STANDARD 11)
add_executable(lab2 main.cpp)
You first need CMake functions to find the libraries liblapack and libblas.
For both there are already functions in the standard cmake distribution so
find_package(BLAS REQUIRED)
find_package(LAPACK REQUIRED)
find_package(Armadillo REQUIRED)
See FindBLAS.cmake and FindLAPACK.cmake in your cmake modules directory for documentation what variables they define.
then add them to your targets, e.g.:
target_link_libraries(lab2 ${LAPACK_LIBRARIES} ${BLAS_LIBARIES} ${ARMADILLO_LIBRARIES})
As #Richard Hodges said in a comment, in the Settings you can set the variables fed to CMake as well as define environment variables.
Something also I like to do is to include a custom CMake script to easily tweak a configuration; for example add in your CMakeLists.txt:
include(local.cmake OPTIONAL)
That way, you can put any CMake configuration you want in local.cmake in your source directory, and it will be parsed. Nothing happens if the file does not exist.

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)

Error linking to Boost filesystem using cmake on cygwin

I'm using cmake 2.8.9, g++ 3.4.4, and Boost 1.50. in Cygwin on Windows 8 64 bit.
Here is the error message I get.
Linking CXX executable RayTracer.exe
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x89c):
undefined reference to boost::system::generic_category()'
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x8a6):
undefined reference toboost::system::generic_category()'
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o:Ray_Tracer.cpp:(.text+0x8b0):
undefined reference to boost::system::system_category()'
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../i686-pc-cygwin/bin/ld:
CMakeFiles/RayTracer.dir/Ray_Tracer.cpp.o: bad reloc address 0xb in
section
.text$_ZN5boost6system14error_categoryD1Ev[boost::system::error_category::~error_category()]'
collect2: ld returned 1 exit status
CMakeFiles/RayTracer.dir/build.make:94: recipe for target
RayTracer.exe' failed make[2]: *** [RayTracer.exe] Error 1
CMakeFiles/Makefile2:64: recipe for target
CMakeFiles/RayTracer.dir/all' failed make[1]: *
[CMakeFiles/RayTracer.dir/all] Error 2 Makefile:75: recipe for target
`all' failed make: * [all] Error 2
From what I've seen, the usual problem is failing to link the boost system library, but I made sure to do that. Here is the relevant portion of my CMakeLists.txt file:
#Edit: cmake can't find the static libraries on cygwin, so I'm setting this to false for now.
SET(Boost_USE_STATIC_LIBS FALSE)
FIND_PACKAGE(Boost 1.50 REQUIRED date_time program_options thread filesystem system unit_test_framework)
IF(${Boost_FOUND})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ENDIF()
add_executable(RayTracer
Ray_Tracer.cpp
)
target_link_libraries(RayTracer ${Boost_PROGRAM_OPTIONS_LIBRARIES})
And here's the line in my .cpp file that triggers the error:
#include <boost/filesystem.hpp>
Any idea what I'm doing wrong?
You need to tell the linker to link Boost.Filesystem and Boost.System libraries.
You can do:
target_link_libraries(RayTracer
${Boost_PROGRAM_OPTIONS_LIBRARIES}
${Boost_FILESYSTEM_LIBRARIES}
${Boost_SYSTEM_LIBRARIES}
)
or if you just want to link all the libs specified in your find_package(Boost...) call, you can do:
target_link_libraries(RayTracer ${Boost_LIBRARIES})
For further details on the FindBoost CMake module, see the docs or run:
cmake --help-module FindBoost