OpenCV C++ give architecture arm64 error in Macbook M1 chip - c++

I built OpenCV-4.5.2 in Macbook M1 followed this tutorial: https://sayak.dev/install-opencv-m1. It works fine in Python but when I use in C++
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
int main()
{
cv::Mat img = cv::imread("avatar.jpeg");
return 0;
}
It give an error in cv::Mat
Undefined symbols for architecture arm64:
"cv::Mat::~Mat()", referenced from:
_main in main.cpp.o
"cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [imgproc] Error 1
make[2]: *** [CMakeFiles/imgproc.dir/all] Error 2
make[1]: *** [CMakeFiles/imgproc.dir/rule] Error 2
make: *** [imgproc] Error 2
After hours, I can't find what's wrong with it. Can anybody help me? Thank you!
P/S: as additional, this is my CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(imgproc)
set(CMAKE_CXX_STANDARD 14)
# Set the location of the OpenCV directory
set(OpenCV_DIR "/usr/local/include/opencv4")
# Find OpenCV library
find_package( OpenCV 4 REQUIRED )
# Add header file
include_directories(include ${OpenCV_INCLUDE_DIRS} )
add_executable(imgproc main.cpp)

I found that replace these include:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
with:
#include <opencv2/opencv.hpp>
Then everything worked!

After some exploration I finally solved the problem. To user the openCV library on M1 Mac, you need to include -I/opt/homebrew/Cellar/opencv/4.5.5/include/opencv4/ -lopencv_core -lopencv_imgcodecs -lopencv_highgui -L/opt/homebrew/Cellar/opencv/4.5.5/lib/ as your g++ compile options.

I have tested OpenCV in macOS successfully, refer to:
https://medium.com/#mfkhao2009/set-up-opencv-development-enrioment-875aa69bd403
You should link the library to the target imgproc by adding this code to CMakeLists.txt
add_executable(imgproc main.cpp)
target_link_libraries(imgproc ${OpenCV_LIBS} )

I've been dealing with the same issue. I kept getting the linker error (Undefined symbols for architecture arm64...). FYI I installed via homebrew on my M1 mac, and developing with CLion.
What solved it was adding this to specifiy X86_64 in cmake:
set(CMAKE_OSX_ARCHITECTURES x86_64)
My full CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
set(CMAKE_OSX_ARCHITECTURES x86_64)
project(opencvtest)
set(CMAKE_CXX_STANDARD 23)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(opencvtest main.cpp)
target_link_libraries(opencvtest ${OpenCV_LIBS})

Related

Unable to run SFML project with CMake on arm64

I am using MacBook with M1 and I try to create a project with SFML.
I downloaded a snapshot of SFML with files built for arm64
I verified it using file command
Example:
libsfml-graphics.dylib: Mach-O 64-bit dynamically linked shared library arm64
I placed these files in ~/Library/Frameworks along with extlibs directory content.
I set a CMake flag: -DCMAKE_OSX_ARCHITECTURES=arm64
But I still am unable to run this project.
Error:
[ 50%] Linking CXX executable myProject
Undefined symbols for architecture arm64:
"__ZN2sf6StringC1EPKcRKSt6locale", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make[3]: *** [myProject] Error 1
make[2]: *** [CMakeFiles/myProject.dir/all] Error 2
make[1]: *** [CMakeFiles/myProject.dir/rule] Error 2
make: *** [myProject] Error 2
This is my whole CMakeLists.txt file:
cmake_minimum_required(VERSION 3.19)
project(myProject)
add_executable(myProject main.cpp)
set(CMAKE_CXX_COMPILER "/opt/homebrew/bin/g++-11" CACHE STRING "C++ compiler" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DCMAKE_OSX_ARCHITECTURES=arm64")
include_directories(/usr/local/include)
find_package(SFML 2.5 COMPONENTS system window graphics network audio REQUIRED)
include_directories(${SFML_INCLUDE_DIRS})
target_link_libraries(myProject sfml-system sfml-window sfml-graphics sfml-audio sfml-network)
I also tried to use dylib instead of framework, but it was unsuccessful also. I'd be grateful for any help, I can't figure out what I did wrong.

Making C++ Project with OpenCV and librealsense

I want to start a computer vision project using an r200 and OpenCV. I'm using the legacy librealsense library and i've ran the examples on it successfully.
Unfortunately i'm new to C++ and Cmake so i'm struggling to import things appropriately.
My project structure looks like:
-Project
-build
-librealsense //this is the directory that contains the code to run the r200
-main.cpp //my main working file
-CMakeLists.txt //what i'm working on
my CMakeLists.txt runs successfully when i execute ../ cmake from the build directory and it looks like this:
cmake_minimum_required(VERSION 3.10)
project(Project)
set(CMAKE_CXX_STANDARD 11)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_subdirectory(librealsense)
# add the executable
add_executable(Project main.cpp librealsense/examples/example.hpp)
target_link_libraries( Project ${OpenCV_LIBS})
target_link_libraries(Project realsense2)
Note that at the moment i'm just trialing code from the examples and that librealsense/examples/example.hpp is the relative path to one of the example.hpp headers used in the example that i'm copying.
The imports that i'm using in main.cpp are as follows:
#include <librealsense2/rs.hpp>
#include "librealsense/examples/example.hpp"
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
It responds with a very verbose error message that ends with the following:
...
"_rs2_start_processing", referenced from:
void rs2::processing_block::start<rs2::frame_queue>(rs2::frame_queue) in main.cpp.o
"_rs2_stream_to_string", referenced from:
texture::show(rect const&) const in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Project] Error 1
make[1]: *** [CMakeFiles/Project.dir/all] Error 2
make: *** [all] Error 2
My question is how do I actually import OpenCV and the librealsense libraries!!!
Any direction to good guides for this and CMake would make me forever grateful!

cmake build .so library

My CMakeLists.txt is here.
cmake_minimum_required(VERSION 3.9)
project(iemoji-lab)
set(CMAKE_CXX_STANDARD 14)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
add_executable(
util
src/util/util.cpp
)
target_link_libraries(
util
avformat
)
After I build, I got util executable file. As you see, I have to link util with avformat which is in ffmepg.
Now I want to build a .so file named libiemoji.
I have already tried like this.
cmake_minimum_required(VERSION 3.9)
project(iemoji-lab)
set(CMAKE_CXX_STANDARD 14)
add_library(
libiemoji
SHARED
src/util/util.cpp
)
But I got error.
Undefined symbols for architecture x86_64:
"_av_register_all", referenced from:
GetFrameCount(char const*) in util.cpp.o
"_avformat_alloc_context", referenced from:
GetFrameCount(char const*) in util.cpp.o
"_avformat_close_input", referenced from:
GetFrameCount(char const*) in util.cpp.o
"_avformat_free_context", referenced from:
GetFrameCount(char const*) in util.cpp.o
"_avformat_open_input", referenced from:
GetFrameCount(char const*) in util.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[2]: * [CMakeFiles/libiemoji.dir/build.make:95: liblibiemoji.dylib] Error 1
gmake[1]: * [CMakeFiles/Makefile2:68: CMakeFiles/libiemoji.dir/all] Error 2
gmake: *** [Makefile:84: all] Error 2
So how can generate .so library?
EDIT
After #Mario point, I got solution for no error.
cmake_minimum_required(VERSION 3.9)
project(iemoji-lab)
set(CMAKE_CXX_STANDARD 14)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
add_library(
iemoji
SHARED
src/util/util.cpp
)
target_link_libraries(
iemoji
avformat
)
Now I got a file libiemoji.dyib. I am confused by it because I want to generate a file with extension .so.
You've got everything right, you just forgot linking the library as well. Copy target_link_libraries() and you should be fine.
The sub-project should link libraries, similar to executable project; because of dependencies; you can look at CMake tutorial

allegro5 project in CLion, ld: library not found error

I'm making a C++ and allegro5 project for university. I compiled allegro library and it's working well in Xcode for example. But I wanted to do my project in CLion and as soon as try to build project including allegro it throws an error:
ld: library not found for -lallegro_acodec
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [TEST1] Error 1
make[1]: *** [CMakeFiles/TEST1.dir/all] Error 2
make: *** [all] Error 2
CMakeLists.txt:
cmake_minimum_required(VERSION 3.3)
project(TEST1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(TEST1 ${SOURCE_FILES})
INCLUDE_DIRECTORIES( /usr/local/Cellar/allegro/5.0.11/include )
LINK_DIRECTORIES( /usr/local/Cellar/allegro/5.0.11/lib )
TARGET_LINK_LIBRARIES(TEST1
allegro_acodec
allegro_audio
allegro_color
allegro_dialog
allegro_image
allegro_main
allegro_memfile
allegro_physfs
allegro_primitives
allegro_ttf
allegro_font
allegro)
main.cpp:
#include <iostream>
#include <allegro5/allegro.h>
using namespace std;
int main(int argc, char **argv) {
al_init();
return 0;
}
I'm working on OSX 10.11. I could not find solution for my problem. I konw that allegro and CLion are not that popular. Can anyone help me what that error means?
You should issue link_directories before add_executable.
From the documentation about link_directories:
The command will apply only to targets created after it is called.

Add github library(BamTools) to c++ using cmake ExternalProject_Add

I would like to use the BamTools library for a project. I am using CMake ExternalProject_Add to do this. CMake clones and compiles BamTools GitHub repo fine, but no matter what I try I can't get it to link properly. Does anyone have any ideas?
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(myProject)
include(ExternalProject)
set( CMAKE_C_FLAGS "-Wall -g")
set(BAMTOOLS_ROOT ${CMAKE_CURRENT_BINARY_DIR}/external/bamtools)
set(BAMTOOLS_INCLUDE_DIRS ${BAMTOOLS_ROOT}/include/bamtools)
set(BAMTOOLS_LIBRARIES ${BAMTOOLS_ROOT}/lib/bamtools/libbamtools.a)
set(bamtools_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/external/bamtools")
set(bamtools_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${bamtools_INSTALL_DIR})
include_directories(${BAMTOOLS_INCLUDE_DIRS})
ExternalProject_Add(bamtools
PREFIX ${BAMTOOLS_ROOT}
GIT_REPOSITORY https://github.com/pezmaster31/bamtools
BINARY_DIR ${BAMTOOLS_ROOT}
INSTALL_DIR ${BAMTOOLS_ROOT}
CMAKE_ARGS ${bamtools_CMAKE_ARGS}
)
add_subdirectory(src)
My simple main.cpp file exists in a src folder in the same directory as the CMakeLists.txt
#include <iostream>
#include <string>
#include <api/BamReader.h>
using namespace BamTools;
int main(){
BamReader reader =BamReader();
reader.Close();
};
I get the following error
Linking CXX executable project
Undefined symbols for architecture x86_64:
"_crc32", referenced from:
BamTools::Internal::BgzfStream::DeflateBlock(int) in libbamtools.a(BgzfStream_p.cpp.o)
"_deflate", referenced from:
BamTools::Internal::BgzfStream::DeflateBlock(int) in libbamtools.a(BgzfStream_p.cpp.o)
"_deflateEnd", referenced from:
BamTools::Internal::BgzfStream::DeflateBlock(int) in libbamtools.a(BgzfStream_p.cpp.o)
"_deflateInit2_", referenced from:
BamTools::Internal::BgzfStream::DeflateBlock(int) in libbamtools.a(BgzfStream_p.cpp.o)
"_inflate", referenced from:
BamTools::Internal::BgzfStream::InflateBlock(unsigned long const&) in libbamtools.a(BgzfStream_p.cpp.o)
"_inflateEnd", referenced from:
BamTools::Internal::BgzfStream::InflateBlock(unsigned long const&) in libbamtools.a(BgzfStream_p.cpp.o)
"_inflateInit2_", referenced from:
BamTools::Internal::BgzfStream::InflateBlock(unsigned long const&) in libbamtools.a(BgzfStream_p.cpp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [src/project] Error 1
make[1]: *** [src/CMakeFiles/project.dir/all] Error 2
make: *** [all] Error 2
Like the other answer said it was not linking ZLib properly. Making the following changes will resolve the issue. Instead of the add_subdirectory(src) add
find_package(ZLIB REQUIRED)
add_library(libbamtools STATIC IMPORTED)
set_target_properties(libbamtools PROPERTIES IMPORTED_LOCATION ${BAMTOOLS_LIBRARIES}/libbamtools.a)
add_dependencies(libbamtools bamtools)
add_executable(myProject src/main.cpp)
include_directories(${BAMTOOLS_INCLUDE_DIRS})
target_link_libraries(myProject libbamtools ${ZLIB_LIBRARIES})
Those are functions from zlib, I believe. You may need to explicitly link with zlib. Try adding find_package(ZLIB REQUIRED).