C++ Link two Shared Library to main.cpp - opencv

I'm having some problems try to link two shared library to my main.cpp file in a cmake file.
My folder tree is:
**mainfolder**
|_main.cpp
|_CMakeLists.txt
|
| **lib**
|_**lib1**
|_CMakeLists.txt
|_liblib1.so
|_**src**
|_lib1.cpp
|_**include**
|_lib1.h
|_**lib2**
|_CMakeLists.txt
|_liblib2.so
|_**src**
|_lib2.cpp
|_**include**
|_lib2.h
the two CMakeLists.txt for the two libraries are quite similar and created according to this link:
cmake_minimum_required(VERSION 2.6)
project( LibraryLib1 C CXX )
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
set(CMAKE_BUILD_TYPE Release)
find_package( OpenCV REQUIRED )
# Find source files
file(GLOB SOURCES src/*.cpp)
# Include header files
include_directories(include)
# Create shared library
add_library(${PROJECT_NAME} SHARED ${SOURCES})
# Install library
install(TARGETS ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME})
# Install library headers
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION include/${PROJECT_NAME})
my main.cpp file is:
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include "lib/lib1/lib1.h"
#include "lib/lib2/lib2.h"
using namespace cv;
int main()
{
printf("Executing main.cpp");
lib1 lib1object;
lib2 lib2object;
for(;;)
{
lib1object.Analize(param1, param2);
lib2object.Draw(param1, param2, param3);
}
return 0;
}
My main.cpp should call openCV + the two libraries. Could you please tell me which line I have to add to the CMakeLists.txt in the main folder to run my main?
in this moment the mainfolder/CMakeLists.txt is:
cmake_minimum_required(VERSION 2.8)
project( MyProject C CXX )
find_package( OpenCV REQUIRED )
add_executable( main main.cpp )
target_link_libraries( main ${OpenCV_LIBS})
I really appreciate your help. Thanks!!
One more thing... If I modify tghe last row of the mainfolder/CMakeLists.txt as:
target_link_libraries( main ${OpenCV_LIBS} LibraryLib1 LibraryLib2)
where LibraryLib1 and LibraryLib2 are the name of the two library project, I obtain:
/usr/bin/ld: unable to find -lLibraryLib1
/usr/bin/ld: unable to find -lLibraryLib2

You have separate projects for the libraries and the main file. Therefore, the main file doesn't know the target names from the other projects. The easiest solution (as everything is in a single source tree) is to have just a single projects.
Therefore, use add_subdirectory to build your libarires directly in the main project:
cmake_minimum_required(VERSION 2.8)
project( MyProject C CXX )
add_subidrectory(lib/lib1)
add_subidrectory(lib/lib2)
find_package( OpenCV REQUIRED )
add_executable( main main.cpp )
target_link_libraries( main ${OpenCV_LIBS} LibraryLib1 LibraryLib2)
This ensures that target names are known. This assumes that you have calls in the subfolders like add_library(LibraryLib1.... Otherwise, exchange the names appropriately.

Related

PCL can't find header file

/home/ubuntu/emvs_ws/src/rpg_emvs/mapper_emvs/src/realtime.cpp:25:62: fatal error: pcl/registration/impl/incremental_registration.hpp: No such file or directory
compilation terminated.
rpg_emvs/mapper_emvs/CMakeFiles/realtime_emvs.dir/build.make:62: recipe for target 'rpg_emvs/mapper_emvs/CMakeFiles/realtime_emvs.dir/src/realtime.cpp.o' failed
make[2]: *** [rpg_emvs/mapper_emvs/CMakeFiles/realtime_emvs.dir/src/realtime.cpp.o] Error 1
I'm getting this error after catkin_make
Theses are the includes in realtime.cpp
#include <pcl/registration/incremental_registration.h>
#include <pcl/registration/icp.h>
CMakeLists.txt file
project(mapper_emvs)
cmake_minimum_required(VERSION 2.8.3)
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
set(CMAKE_BUILD_TYPE RelWithDebInfo) # Release, RelWithDebInfo
set(CMAKE_CXX_FLAGS "-O3 -fopenmp -std=c++11 ${CMAKE_CXX_FLAGS}")
## Generate dynamic reconfigure parameters in the 'cfg' folder
##generate_dynamic_reconfigure_options(
## cfg/EMVSCfg.cfg
##)
set(HEADERS
include/mapper_emvs/mapper_emvs.hpp
include/mapper_emvs/data_loading.hpp
include/mapper_emvs/depth_vector.hpp
include/mapper_emvs/trajectory.hpp
include/mapper_emvs/geometry_utils.hpp
include/mapper_emvs/median_filtering.hpp
)
set(SOURCES
src/mapper_emvs.cpp
src/data_loading.cpp
src/median_filtering.cpp
)
option(DEFINE_USE_INVERSE_DEPTH "Use linear spacing in inverse depth (if OFF, will use linear spacing in depth)" ON)
if(DEFINE_USE_INVERSE_DEPTH)
add_definitions(-DUSE_INVERSE_DEPTH)
endif(DEFINE_USE_INVERSE_DEPTH)
cs_add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS})
# Executables
################################################################################
cs_add_executable(run_emvs src/main.cpp)
target_link_libraries(run_emvs ${PROJECT_NAME})
cs_add_executable(realtime_emvs src/realtime.cpp)
add_dependencies(realtime_emvs ${PROJECT_NAME}_gencfg)
target_link_libraries(realtime_emvs ${PROJECT_NAME})
################################################################################
cs_install()
cs_export()
Note that I did Catkin_make not catkin build, I don;t know if this makes a difference.
I'm asked to add more details, so please ignore this line :)
You need to add PCL library in your CMakeLists.txt file as follows:
project(mapper_emvs)
cmake_minimum_required(VERSION 2.8.3)
find_package(catkin_simple REQUIRED)
# Adding PCL lib
find_package(PCL REQUIRED)
# Setting include, lib directories and definitions
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS} )
add_definitions(${PCL_DEFINITIONS} )
catkin_simple(ALL_DEPS_REQUIRED)
set(CMAKE_BUILD_TYPE RelWithDebInfo) # Release, RelWithDebInfo
set(CMAKE_CXX_FLAGS "-O3 -fopenmp -std=c++11 ${CMAKE_CXX_FLAGS}")
## Generate dynamic reconfigure parameters in the 'cfg' folder
##generate_dynamic_reconfigure_options(
## cfg/EMVSCfg.cfg
##)
set(HEADERS
include/mapper_emvs/mapper_emvs.hpp
include/mapper_emvs/data_loading.hpp
include/mapper_emvs/depth_vector.hpp
include/mapper_emvs/trajectory.hpp
include/mapper_emvs/geometry_utils.hpp
include/mapper_emvs/median_filtering.hpp
)
set(SOURCES
src/mapper_emvs.cpp
src/data_loading.cpp
src/median_filtering.cpp
)
option(DEFINE_USE_INVERSE_DEPTH "Use linear spacing in inverse depth (if OFF, will use linear spacing in depth)" ON)
if(DEFINE_USE_INVERSE_DEPTH)
add_definitions(-DUSE_INVERSE_DEPTH)
endif(DEFINE_USE_INVERSE_DEPTH)
cs_add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS})
# Executables
################################################################################
cs_add_executable(run_emvs src/main.cpp)
target_link_libraries(run_emvs ${PROJECT_NAME} ${PCL_LIBRARIES})
cs_add_executable(realtime_emvs src/realtime.cpp)
add_dependencies(realtime_emvs ${PROJECT_NAME}_gencfg)
target_link_libraries(realtime_emvs ${PROJECT_NAME} ${PCL_LIBRARIES})
################################################################################
cs_install()
cs_export()
Note: Hope you installed PCL lib. Besides,
I added ${PCL_LIBRARIES} into target_link_libraries. I hope it will work this way, if you are getting some errors, try adding ${PCL_LIBRARIES} into cs_add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${PCL_LIBRARIES}). Please let us know if get errors after applying these changes.

Can't link a project using cmake with OpenCV and LibTorch

I asked a similar question about linking a project with OpenCV a few days ago. I got that working, but now I've hit a very weird problem using CMake and adding LibTorch to the project.
If I only use OpenCV in the project, everything compiles, links, and runs fine.
But if I add Torch to CMakeLists.txt, I get a linker error:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
set(CMAKE_VERBOSE_MAKEFILE ON)
project(torchscriptie)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
find_package(Torch HINTS "/usr/local/libtorch")
message(STATUS "TORCH_LIBRARIES = ${TORCH_LIBRARIES}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(torchscriptie main.cpp)
target_link_libraries( torchscriptie ${OpenCV_LIBS} )
target_link_libraries(torchscriptie "${TORCH_LIBRARIES}")
set_property(TARGET torchscriptie PROPERTY CXX_STANDARD 14)
This CMakeLists.txt file causes this error:
CMakeFiles/torchscriptie.dir/main.cpp.o: In function `main':
/code/cpp/torchscriptie/main.cpp:18: undefined reference to `cv::imread(std::string const&, int)'
/code/cpp/torchscriptie/main.cpp:24: undefined reference to `cv::namedWindow(std::string const&, int)'
/code/cpp/torchscriptie/main.cpp:25: undefined reference to `cv::imshow(std::string const&, cv::_InputArray const&)'
collect2: error: ld returned 1 exit status
Here's the command:
/usr/bin/c++ -g -rdynamic CMakeFiles/torchscriptie.dir/main.cpp.o -o torchscriptie -Wl,-rpath,/usr/local/lib:/usr/local/libtorch/lib /usr/local/lib/libopencv_gapi.so.4.3.0 /usr/local/lib/libopencv_stitching.so.4.3.0 /usr/local/lib/libopencv_alphamat.so.4.3.0 /usr/local/lib/libopencv_aruco.so.4.3.0 /usr/local/lib/libopencv_bgsegm.so.4.3.0 /usr/local/lib/libopencv_bioinspired.so.4.3.0 /usr/local/lib/libopencv_ccalib.so.4.3.0 /usr/local/lib/libopencv_dnn_objdetect.so.4.3.0 /usr/local/lib/libopencv_dnn_superres.so.4.3.0 /usr/local/lib/libopencv_dpm.so.4.3.0 /usr/local/lib/libopencv_face.so.4.3.0 /usr/local/lib/libopencv_freetype.so.4.3.0 /usr/local/lib/libopencv_fuzzy.so.4.3.0 /usr/local/lib/libopencv_hdf.so.4.3.0 /usr/local/lib/libopencv_hfs.so.4.3.0 /usr/local/lib/libopencv_img_hash.so.4.3.0 /usr/local/lib/libopencv_intensity_transform.so.4.3.0 /usr/local/lib/libopencv_line_descriptor.so.4.3.0 /usr/local/lib/libopencv_quality.so.4.3.0 /usr/local/lib/libopencv_rapid.so.4.3.0 /usr/local/lib/libopencv_reg.so.4.3.0 /usr/local/lib/libopencv_rgbd.so.4.3.0 /usr/local/lib/libopencv_saliency.so.4.3.0 /usr/local/lib/libopencv_stereo.so.4.3.0 /usr/local/lib/libopencv_structured_light.so.4.3.0 /usr/local/lib/libopencv_superres.so.4.3.0 /usr/local/lib/libopencv_surface_matching.so.4.3.0 /usr/local/lib/libopencv_tracking.so.4.3.0 /usr/local/lib/libopencv_videostab.so.4.3.0 /usr/local/lib/libopencv_viz.so.4.3.0 /usr/local/lib/libopencv_xfeatures2d.so.4.3.0 /usr/local/lib/libopencv_xobjdetect.so.4.3.0 /usr/local/lib/libopencv_xphoto.so.4.3.0 /usr/local/libtorch/lib/libtorch.so /usr/local/libtorch/lib/libc10.so /usr/local/lib/libopencv_shape.so.4.3.0 /usr/local/lib/libopencv_highgui.so.4.3.0 /usr/local/lib/libopencv_datasets.so.4.3.0 /usr/local/lib/libopencv_plot.so.4.3.0 /usr/local/lib/libopencv_text.so.4.3.0 /usr/local/lib/libopencv_dnn.so.4.3.0 /usr/local/lib/libopencv_ml.so.4.3.0 /usr/local/lib/libopencv_phase_unwrapping.so.4.3.0 /usr/local/lib/libopencv_optflow.so.4.3.0 /usr/local/lib/libopencv_ximgproc.so.4.3.0 /usr/local/lib/libopencv_video.so.4.3.0 /usr/local/lib/libopencv_videoio.so.4.3.0 /usr/local/lib/libopencv_imgcodecs.so.4.3.0 /usr/local/lib/libopencv_objdetect.so.4.3.0 /usr/local/lib/libopencv_calib3d.so.4.3.0 /usr/local/lib/libopencv_features2d.so.4.3.0 /usr/local/lib/libopencv_flann.so.4.3.0 /usr/local/lib/libopencv_photo.so.4.3.0 /usr/local/lib/libopencv_imgproc.so.4.3.0 /usr/local/lib/libopencv_core.so.4.3.0 -Wl,--no-as-needed,/usr/local/libtorch/lib/libtorch_cpu.so -Wl,--as-needed /usr/local/libtorch/lib/libc10.so -lpthread -Wl,--no-as-needed,/usr/local/libtorch/lib/libtorch.so -Wl,--as-needed
I've tried a lot of different combination of commands, but I cannot figure our what's wrong.
When I echo the TORCH_LIBRARIES variable, it returns:
torch;torch_library;/usr/local/libtorch/lib/libc10.so
If I change the libaries, for example to torch_cpu, I'm able to link OpenCV libraries.
set(TORCH_LIBRARIES torch_cpu)
I have no idea why Torch libraries are causing link errors with OpenCV in the same project.
Any suggestions would be great.
Not sure if this fixes your problem, but I had also a few problems like yours. It is working for me with a cmake file including this:
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(MyProject)
set(CMAKE_CXX_STANDARD 14)
list(APPEND CMAKE_PREFIX_PATH "folderToLibtorch/libtorch/share/cmake")
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lm -ldl")
add_executable(MyProject ...some project files...)
target_link_libraries(MyProject ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET MyProject PROPERTY CXX_STANDARD 14)
So make sure list(APPEND CMAKE_PREFIX_PATH "folderToLibtorch/libtorch/share/cmake") is included, this did the trick for me. Also take care to get the right libtorch version from pytorch maybe you should use the lower link and not the "pre-..." version.
Good Luck
The problem is in the version libtorch.
Please use libtorch-cxx11-abi-shared-with-deps not libtorch-shared-with-deps. It is library conflict between libtorch and opencv.
Solution here.
There is my version of CMakeList.txt with CUDA+LIBTORCH+OPENCV support:
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
SET(CUDA_HOME /usr/local/cuda)
SET(CMAKE_CUDA_COMPILER /usr/local/cuda/bin/nvcc)
SET(CUDA_TOOLKIT_ROOT_DIR /usr/local/cuda)
# SET(CUDA_CUBLAS_LIBRARIES /usr/local/cuda/lib64)
SET(CUDA_cublas_device_LIBRARY /usr/local/cuda/lib64)
# SET(CMAKE_CUDA_COMPILER_ENV_VAR /usr/local/cuda/bin/nvcc)
SET(CUDA_INCLUDE_DIRS /usr/local/cuda/include)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 50)
endif()
set(OpenCV_DIR /usr/local/lib/cmake/opencv4)
# set(OpenCV_DIR /usr/local/lib)
project(cmake_and_cuda LANGUAGES CXX CUDA)
include(CTest)
find_package(CUDA REQUIRED)
# libtorch with OpenCV support , with fixed BUG !
list(APPEND CMAKE_PREFIX_PATH ./libtorch)
find_package(Torch REQUIRED)
message(STATUS "TORCH_LIBRARIES = ${TORCH_LIBRARIES}")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}")
# ADD OWN CUDA FILES FOR BUILD LIBRARY.
add_library(particles_new_lib STATIC
torch_module_plus_cuda.cu
torch_module_plus_cuda.h
)
target_compile_features(particles_new_lib PUBLIC cxx_std_14)
# We need to explicitly state that we need all CUDA files in the
# particles_new_lib library to be built with -dc as the member functions
# could be called by other libraries and executables
set_target_properties( particles_new_lib
PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
add_executable(particle_cuda_test torch_and_cuda_call.cpp)
set_property(TARGET particle_cuda_test
PROPERTY CUDA_SEPARABLE_COMPILATION ON)
# LINK ALL LIBRARIES TO TARGET particle_cuda_test
target_link_libraries(particle_cuda_test PRIVATE ${TORCH_LIBRARIES} ${OpenCV_LIBS} particles_new_lib)
# LINK LIBRARIES
target_link_libraries(particle_cuda_test PRIVATE particles_new_lib)
set_property(TARGET particle_cuda_test PROPERTY CXX_STANDARD 14)

Undefined symbol using emcmake (emscripten and opencv)

I'm trying to build a minimalist project using OpenCV in the browser.
I've compiled OpenCV on my computer.
Here is the C++ code (josef.cpp):
#include <iostrem>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
int main(int argc, char **argv)
{
printf("Hello here\n");
cv::Mat m;
std::cout << m;
}
Here is the CMakeLists.txt :
cmake_minimum_required(VERSION 2.8)
project( josef )
# Give here the directory in which we have
# the file OpenCVConfig.cmake
set(OpenCV_DIR "/usr/local/lib/cmake/opencv4")
find_package( OpenCV REQUIRED )
add_executable( josef josef.cpp )
target_link_libraries( josef ${OpenCV_LIBS} )
Compiling with
cmake .
make
works perfectly well and provides an executable which produces the expected result:
Hello here
[]
My problem arises when trying with emscripten.
emcmake cmake .
produces lot of warnings like that one:
CMake Warning (dev) at /usr/local/lib/cmake/opencv4/OpenCVModules.cmake:393 (add_library):
ADD_LIBRARY called with SHARED option but the target platform does not
support dynamic linking. Building a STATIC library instead. This may lead
to problems.
Call Stack (most recent call first):
/usr/local/lib/cmake/opencv4/OpenCVConfig.cmake:126 (include)
CMakeLists.txt:7 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
Then
emmake make
fails on undefined symbols:
error: undefined symbol: _ZN2cv3Mat10deallocateEv
warning: Link with `-s LLD_REPORT_UNDEFINED` to get more information on undefined symbols
warning: To disable errors for undefined symbols use `-s ERROR_ON_UNDEFINED_SYMBOLS=0`
My question is : what do I wrong ? How to tell emscripten where are the famous missing symbols (these are the file .so if I understood correctly) ?
This is partially a hack solution.
In the file /usr/local/lib/cmake/opencv4/OpenCVModules.cmake, change every instances of "SHARED" by "STATIC".
In your cmake file, add the line
file( GLOB opencv_js "/path/to/opencvjs/opencv/build_js/lib/*.a")
This part supposes that you compiled opencv by hand.
then refer to my answer to my next question. (in short: use a canvas, do not use cv::imdecode.)

Configuring an c++ OpenCV project with Cmake

I consider this a fundamental step for creating projects that use OpenCV libraries so you don't need to manually include all the libraries. There is not detailed information on this topic, at least for a newbie that just wants to use OpenCV as soon as posible, so:
Which is the easiest and scalable way to create a multiplatform c++ OpenCV with Cmake?
First: create a folder Project containing two subfolders src and include, and a file called CMakeLists.txt.
Second: Put your cpp inside the src folder and your headers in the include folders.
Third: Your CMakeLists.txt should look like this:
cmake_minimum_required(VERSION 2.8)
PROJECT (name)
find_package(OpenCV REQUIRED )
set( NAME_SRC
src/main.cpp
)
set( NAME_HEADERS
include/header.h
)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
link_directories( ${CMAKE_BINARY_DIR}/bin)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
add_executable( name ${NAME_SRC} ${NAME_HEADERS} )
target_link_libraries( sample_pcTest ${OpenCV_LIBS} )
Fourth: Open CMake GUI and select the root folder as input and create a build folder for the output. Click configure, then generate, and choose the generator (VisualStudio, Eclipse, ...)
I am using opencv3.0 and cmake3.8,
config below work for me!
######## A simple cmakelists.txt file for OpenCV() #############
cmake_minimum_required(VERSION 2.8)
PROJECT(word)
FIND_PACKAGE( OpenCV REQUIRED )
INCLUDE_DIRECTORIES( ${OpenCV_INCLUDE_DIRS} )
ADD_EXECUTABLE(word main.c)
TARGET_LINK_LIBRARIES (word ${OpenCV_LIBS})
########### end ####################################

Error linking to OpenCV after restructure of code

I've just reorganised my code (which worked before) and am now getting an error message when I run my executable: The program can't start because opencv_core230d.dll is missing from your computer. The error is accurate, I only have .lib library files for OpenCV, but it worked before and I don't think this should be a problem, should it?
An extract from the cmake file is:
FIND_PACKAGE( OpenCV REQUIRED )
# Define LIBRARY and SRC_FILES to create my library
add_library(${LIBRARY} ${SRC_FILES})
target_link_libraries(${LIBRARY} ${OpenCV_LIBS} )
# Define appName and appFile to create application,
# and link to my library and OpenCV
add_executable(${appName} ${appFile})
target_link_libraries(${appName} ${LIBRARY} ${OpenCV_LIBS})
Am I doing anything obviously wrong, or what else might cause this error?
EDIT: I've now reduced this problem to a minimal example. Inside one directory test I have two files: testApp.cpp and CMakeLists.txt as follows:
testApp.cpp
#include <opencv2/opencv.hpp>
int main(int argc, char* argv[])
{
cv::namedWindow("Test");
cv::waitKey(0);
cv::destroyAllWindows();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(test)
FIND_PACKAGE( OpenCV REQUIRED )
add_executable(appName testApp.cpp)
target_link_libraries(appName ${OpenCV_LIBS})
message(STATUS "Linking testapp to: ${OpenCV_LIBS}")
With the error as before: opencv_highgui230d.dll is missing.
The problem is that the environment variable PATH does not point to the location where OpenCV's DLLs reside. Search inside OpenCV directories and if you can't find it you'll need to reinstall OpenCV.
Seems this is a common problem which simply needed some more research. To fix, I just added the OpenCV/bin directory to the PATH environmental variable. Still not sure why it was working previously though...

Resources