I am compiling my project using LLVM on Mac OS X with CLion and CMake.
My CMake configure is:
cmake_minimum_required(VERSION 3.6)
project(PPAP)
set(CMAKE_CXX_STANDARD 11)
# add_compile_options(-v)
include_directories(
/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/include/python3.6m
/usr/local/Cellar/llvm/3.9.1/include
)
set(SOURCE_FILES src/parser.cpp src/convert.cpp src/ast.cpp)
set(LIBRARIES
/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/libpython3.6.dylib
/usr/local/Cellar/llvm/3.9.1/lib/libLLVM.dylib
)
add_executable(PPAP ${SOURCE_FILES})
target_link_libraries(PPAP ${LIBRARIES})
Then I compile it successfully, but when I run it, I got:
dyld: Library not loaded: #rpath/libLTO.dylib
Referenced from: /usr/local/opt/llvm/lib/libLLVM.dylib
Reason: image not found
How to solve this problem?
Just linking libLLVM.dylib is not enough. Using llvm-config instead of adding libraries manually is a better way.
It's not ideal, but adding the library directories to the DYLD_LIBRARY_PATH environment variable in the CLion Run/Debug Configurations made the errors go away for me.
I'm still interested in a CMake-only solution without having to resort to DYLD_LIBRARY_PATH.
Related
I'm trying to use wxWidgets on an arm64 macOS with vcpkg, CMake, and VS Code. Everything is wired up correctly because other vcpkg libraries include, link, and run fine. But, when I try to use wxWidgets there's a linking error.
My CMakeLists.txt:
cmake_minimum_required(VERSION 3.22.0)
project(main VERSION 0.1.0)
add_executable(main main.cpp)
set_property(TARGET main PROPERTY CXX_STANDARD 17)
find_package(wxWidgets REQUIRED)
include(${wxWidgets_USE_FILE})
target_include_directories(main PRIVATE ${wxWidgets_INCLUDE_DIRS})
target_link_libraries(main PRIVATE ${wxWidgets_LIBRARIES})
The CMake error I get:
[build] [ 50%] Linking CXX executable main
[build] ld: library not found for -llibjpeg.a>
[build] clang: error: linker command failed with exit code 1 (use -v to see invocation)
The value of the wxWidgets_LIBRARIES list (set by find_package(wxWidgets REQUIRED)):
-L/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib;-pthread;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_xrc-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_qa-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu_net-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_html-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_osx_cocoau_core-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu_xml-3.1.a;/Users/myname/cpp/vcpkg/packages/wxwidgets_arm64-osx/lib/libwx_baseu-3.1.a;-lwx_osx_cocoau_core-3.1;libjpeg.a>;libjpeg.a>;libpng.a>;libpng16d.a>;libz.a>;libz.a>;libtiff.a>;libtiffd.a>;liblzma.a>;liblzma.a>;libjpeg.a>;libjpeg.a>;libz.a>;libz.a>;m;-framework AudioToolbox;-framework WebKit;-lwx_baseu-3.1;libexpat.a>;libexpat.a>;libz.a>;libz.a>;-lwxregexu-3.1;libiconv.tbd;-framework CoreFoundation;-framework Security;-framework Carbon;-framework Cocoa;-framework IOKit;-framework QuartzCore;TIFF::TIFF;expat::expat;ZLIB::ZLIB;png_static
I don't have much experience with CMake, so I don't know what the right angle bracket is for, but is that the problem? Could its being the first non-full-path file in the list mean that it doesn't know where to look?
-L is for directories, and -l is for individual library files. I see you have mixed .a files with directories. You'll need to fix that.
Your best bet is to debug cmake configure with --trace-expand and see who is setting wxWidgets_LIBRARIES to a incomplete and very strange generator expression libjpeg.a>;libjpeg.a>;libpng.a>;libpng16d.a>;
Another suspicious thing is that your library paths contain packages/wxwidgets_arm64-osx which indicates either wrong usage of vcpkg or there is a -config.cmake involved which was not fixed by vcpkg. (everything vcpkg finds via cmake should be living in /installed/<triplet>)
I am developing a C++ library, including OpenCV, which will be used in a cross-platform Xamarin solution through a wrapper and the NuGet packaging system (see this guide). I configured a CMakeLists.txt file but I simply cannot get OpenCV to be correctly linked for both static (iOS) and dynamic (Android) libraries.
I tried to change the OpenCV_DIR variable, install and build OpenCV from sources and manually include the content of the OpenCV_INCLUDE_DIRS variable but nothing worked. I also noticed that the linking works when only using cv::Point. But the linking does not work when using cv::Mat, which I do not understand the reason.
The following is the CMakeLists.txt that I am using :
cmake_minimum_required (VERSION 3.2)
project (MyLib C CXX)
enable_testing()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
MESSAGE(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS})
# Source and headers files
set(SOURCES File1.cpp File2.cpp)
set(HEADERS File1.h File2.h)
# Library
if(BUILD_SHARED_LIBS)
add_library (MyLib SHARED ${SOURCES} ${HEADERS})
target_compile_definitions(MyLib PUBLIC IS_BUILDING_SHARED)
else()
add_library (MyLib STATIC ${SOURCES} ${HEADERS})
endif()
# Dependencies
set(OpenCV_DIR /usr/local/Cellar/opencv/4.5.0_1/lib/cmake/opencv4)
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}")
message(STATUS "OpenCV_DIR = ${OpenCV_DIR}")
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(MyLib ${OpenCV_LIBS})
The following shows the location of OpenCV's files that are used during the build process. Everything seems alright.
-- OpenCV_INCLUDE_DIRS = /usr/local/Cellar/opencv/4.5.0_1/include/opencv4
-- OpenCV_LIBS = opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_alphamat;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_datasets;opencv_dnn_objdetect;opencv_dnn_superres;opencv_dpm;opencv_face;opencv_freetype;opencv_fuzzy;opencv_hfs;opencv_img_hash;opencv_intensity_transform;opencv_line_descriptor;opencv_mcc;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_quality;opencv_rapid;opencv_reg;opencv_rgbd;opencv_saliency;opencv_sfm;opencv_shape;opencv_stereo;opencv_structured_light;opencv_superres;opencv_surface_matching;opencv_text;opencv_tracking;opencv_videostab;opencv_viz;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto
-- OpenCV_DIR = /usr/local/Cellar/opencv/4.5.0_1/lib/cmake/opencv4
Android
The following is the commands that I am using to build the Android dynamic library (.so). I have installed the NDK and am building for each ABI (x86, x86_64, armeabi-v7a, arm64-v8a).
cmake ../.. -DCMAKE_TOOLCHAIN_FILE=/Users/$USER/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=21 -DANDROID_ABI=$abi_name -DBUILD_SHARED_LIBS=ON
cmake --build . --config Release
I directly get an error when building the library which is the following.
ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_gapi.4.5.0.dylib: unknown file type
ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_stitching.4.5.0.dylib: unknown file type
[...]
ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_rapid.4.5.0.dylib: unknown file type
ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
iOS
The following is the commands that I am using to build the iOS static library (.a). I am using leetal's ​cmake toolchain file from this repository.
cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS64COMBINED -DBUILD_SHARED_LIBS=OFF
cmake --build . --config Release
The compilation of the static library seems to work because no error message is printed. However, when the library is used in the final Xamarin solution, the linked library cannot be found and the following error is shown.
Native linking failed, undefined symbol: cv::Mat::deallocate(). Please verify that all the necessary frameworks have been referenced and native libraries are properly linked in. (MT5210)
Question
What am I missing in order to properly compile and link OpenCV into my C++ library ?
I am working on macOS Big Sur and uses the following tools versions:
cmake : 3.20.0-rc5
ndk : 23.0.7196353
apple clang : 12.0.0
I hope that the description of my problem is clear enough and I thank you in advance for any help.
We had same problems, including Xamarin's DllNotFoundException with message from last comment, which led me to this topic. What fixed the exception for us in the end was linking statically to OpenCV *.a libs instead of linking to the shared libopencv_java4.so file. So we now have a huge 30MB nativelib.so file for each android ABI in build output, instead of a pair of small nativelib.so and libopencv_java4.so per ABI. CMakeLists looks like this:
set( OpenCV_DIR "~/opencv/build/OpenCV-android-sdk/sdk/native/jni" )
find_package( OpenCV REQUIRED )
target_link_libraries( # Specifies the target library.
nativelib
${OpenCV_LIBS})
Another thing in our project is we use OpenCV optional modules and had to create a custom OpenCV build, which I guess ensures our native library and OpenCV are compiled against same NDK version. I suppose using the prebuilt OpenCV distribution and compiling against a different NDK version could lead to problems too otherwise.
I am currently using CMake to create a static library which utilizes a few of the static libraries from OpenCV 4 ( core imgcodecs video highgui imgproc ). My intention is to be able to bundle all of the required OpenCV static libraries into my own library so that I can distribute it as one library. Additionally, I want for the user of my library to not have to install OpenCV 4 on their system (but do not mind if the user has to do simple installs using apt-get install). I know there are tools for bundling static libraries (such as using ar for linux).
However, where I really am having the issue is with all the dependencies of OpenCV (such as libjpeg, libpng, etc). I don't necessarily mind if these libraries are bundled with mine or linked dynamically as they are relatively easy to install (can be installed with sudo apt-get install, whereas opencv4 needs to be built from source).
What is the best way to go about doing this?
This is my current CMakeLists.txt
It is currently working, but that is because I am using find_package(OpenCV REQUIRED) (which defeats the purpose of what I am trying to do). When I remove that line, the linker complains about not being able to find the OpenCV dependencies.
cmake_minimum_required(VERSION 2.8)
project(myproject)
set(CMAKE_CXX_STANDARD 14)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
find_package(OpenMP REQUIRED)
find_package(OpenCV REQUIRED)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
list(APPEND LINKER_LIBS opencv_core opencv_highgui opencv_video opencv_imgcodecs libmxnet.so libncnn.a nlohmann_json::nlohmann_json)
file(GLOB SRC${CMAKE_CURRENT_LIST_DIR}/src/*.cpp${CMAKE_CURRENT_LIST_DIR}/main.cpp)
add_library(myproject ${SRC})
target_link_libraries(myproject ${LINKER_LIBS} ${OpenMP_CXX_FLAGS})
To elaborate on my question. I build my project which generates libmyproject.a. I then take this library and will eventually extract the symbols from the OpenCV libs (libopencv_core.a libopencv_highgui.a libopencv_imgcodecs.a libopencv_video.a) and add them to my lib (for the time being, I have not yet done this step, which is why in the below example I am linking libopencv_*). I then use my library in a new project, for which the CMakeLists.txt is shown below:
cmake_minimum_required(VERSION 2.8)
project(myproject-driver)
set(CMAKE_CXX_STANDARD 14)
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
find_package(OpenMP REQUIRED)
add_executable(myproject-driver main.cpp)
target_link_libraries(myproject-driver myproject libncnn.a ${OpenMP_CXX_FLAGS} libmxnet.so libopencv_core.a libopencv_highgui.a libopencv_imgcodecs.a libopencv_video.a)
Building this generates the following errors:
Linking CXX executable myproject-driver
/usr/bin/ld: /home/nchafni/Cyrus/myproject/lib/libopencv_imgcodecs.a(grfmt_jpeg.cpp.o): undefined reference to symbol 'jpeg_default_qtables##LIBJPEG_8.0'
//usr/lib/x86_64-linux-gnu/libjpeg.so.8: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
How can I fix this. Is there some CMake command which will link all these dependencies for me? Do I need to manually track down each dependency of those libopencv_* libs and link those manually? Once again, this is assuming that the person using libmyproject.a can't use find_package(OpenCV REQUIRED) as it won't be defined as they have not installed OpenCV on their machine.
First of all, don't use the super old and outdated version 2.8 of CMake. CMake 3.x is so much more powerful and pretty straightforward to use.
Some tips for modern CMake.
Don't use file(GLOB), see here why that is.
Don't use directory wide instructions, rather use target instructions, e.g. target_include_directories vs. include_directories.
Don't use string variables like ${<PACKAGE_NAME>_LIBRARIES}, rather use targets, e.g. <Package_NAME>::lib
When using targets instead of string variables, all the properties (including LINK_INTERFACE) of that target will be populated to the library/executable when calling target_link_libraries, so no more include_directories,link_directories, etc.
myproject
cmake_minimum_required(VERSION 3.14)
project(myproject)
set(CMAKE_CXX_STANDARD 14)
find_package(OpenMP REQUIRED)
find_package(OpenCV REQUIRED)
set(JSON_BuildTests OFF CACHE INTERNAL "")
add_subdirectory(nlohmann_json)
set(SOURCES ...) # list all the source files here
add_library(myproject ${SOURCES})
target_include_directories(myproject PUBLIC # give it a scope
${CMAKE_CURRENT_LIST_DIR}/include
)
target_link_libraries(myproject PUBLIC # give it a scope
opencv_core # using the target, you will get all LINK_LIBRARIES
opencv_highgui
opencv_video
opencv_imgcodecs
libmxnet.so # where is this coming from?
libncnn.a # where is this coming from?
nlohmann_json::nlohmann_json
OpenMP::OpenMP_CXX ## linking against a target, CXX_FLAGS will be populated automatically
)
myprojec-driver
cmake_minimum_required(VERSION 3.14)
project(myproject-driver)
set(CMAKE_CXX_STANDARD 14)
add_executable(myproject-driver main.cpp)
target_link_libraries(myproject-driver PUBLIC # give it a scope
myproject # gets all dependencies through the LINK_INTERFACE
)
I'm trying to use glbinding in my own project. I'm using cmake to build everything. The problem is linker cannot find this library. Probably I don't build library thus it cannot be linked, but I don't know how to achive that.
I've written linking code according to https://github.com/hpicgs/glbinding#linking-binaries.
Cmake:
set(SOURCE_FILES main.cpp)
add_executable(AKOpenGLEngine ${SOURCE_FILES})
set(CMAKE_PREFIX_PATH ${CMAKE_MODULE_PATH} glbinding )
find_package(glbinding REQUIRED)
include_directories(${GLBINDING_INCLUDES})
target_link_libraries(AKOpenGLEngine glbinding ${GLBINDING_LIBRARIES})
Error:
Linking CXX executable AKOpenGLEngine
ld: library not found for -lglbinding
main.cpp:
#include <glbinding/gl/gl.h>
int main(void) {
glbinding::Binding::initialize();
exit(EXIT_SUCCESS);
}
My current project structure:
Have you tried to remove the glbinding from target_link_libraries? ${GLBINDING_LIBRARIES} should be sufficient; it passes <your_specific_file_path_to_glbinding_library> to the linker. With -lglbinding the linker searches for a library within some default directories, your glbinding or build directory not included, thus throwing a library not found. To verify the content of ${GLBINDING_LIBRARIES} you can print it to cmake output, e.g., via message(STATUS ${GLBINDING_LIBRARIES}). However, i also suggest to integrate glbinding as external project as suggested by #janisz.
EDIT: sorry, didn't see the valid, but collapsed answer of #jet47
I downloaded libboost1.50-all in Raspberry Pi and has successfully compiled and execute a program using threads. Libraries were also found in CMake. I then copied the libraries of the boost and its include from /usr/lib and /usr/include/boost respectively to C:\Boost such that the hierarchy becomes:
C:
-> Boost
-> lib
... files
-> include
-> boost
... files
I then used the same CMakeLists.txt and the source code but the library was not found.
NOTE: The cross compiler that I used is fully working and I was able to produce an executable with CMake in Cygwin using the std library. I even specified the location of the library and the user and the root.
Is there anything that I missed out?
cmake_minimum_required(VERSION 2.8)
set(BOOST_ROOT C:/Boost/)
set(BOOST_INCLUDEDIR C:/Boost/include/)
set(BOOST_LIBRARYDIR C:/Boost/lib/)
SET(Boost_DEBUG ON)
find_package(Boost 1.50.0 COMPONENTS thread system)
if (Boost_FOUND)
include_directories (${Boost_INCLUDE_DIRS})
add_executable (thread thread.cpp)
target_link_libraries(thread ${Boost_LIBRARIES})
endif()
Use CMAKE -GUI and then check whether your boost libraries are detected . If not then manually set in the CMAKE-GUI and configure again.
TEMPORARY SOLUTION that I was able to come up to!
I placed the boost lib and include to where the cross compiler is installed since the cross compile was able to link the source code to libstdc++.
The library is placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\sysroot\lib
The include files are placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\include\c++\4.6.3
The CMakeLists content is as follows now:
cmake_minimum_required(VERSION 2.8)
add_executable (thread main.cpp)
target_link_libraries(thread boost_thread boost_system)
Open Cygwin terminal and invoke cmake there, then make. Viola! It now compiles successfully! :>
The magic lies in here:
target_link_libraries(thread boost_thread boost_system)
I found this in one of the questions here in Stackoverflow where someone said to manually link the libraries..
Even though that it worked, why is it that CMake cannot detect the boost library both in Windows (Cygwin terminal) and Linux (VMware) -- These I tried -- but the library was found in Raspberry Pi (Raspbian) using the same CMakeLists.txt and main.cpp. Isn't it the purpose of CMake is to find the libraries itself? If I were just to link them manually, better do it like this then:
arm-unknown-linux-gnueabi-g++.exe -lboost_thread -lboost_system