This question already has answers here:
CMake link to external library
(6 answers)
Closed 1 year ago.
I am trying to compile a small project that uses a library (a header file and a .so file) for reading in images from a camera (on a RPI). The vendor (Arducam) provided a makefile example file, but not a CMake example file. The project is composed of:
test.cpp(main file),
arducam_mipicamera.h, and
libarducam_mipicamera.so.
The makefile that compiles the project successfully is:
CROSS_PREFIX ?=
CC := $(CROSS_COMPILE)gcc
CXX := $(CROSS_COMPILE)g++
CFLAGS ?= -I. -g -O0 -std=gnu11
OPENCV_LIB = $(shell pkg-config --cflags --libs opencv)
ifeq ($(OPENCV_LIB), )
OPENCV_LIB = $(shell pkg-config --cflags --libs opencv4)
endif
CXXFLAGS?= -I. -g -std=gnu++11 ${OPENCV_LIB}
LDFLAGS ?=
LIBS := -larducam_mipicamera -lpthread
OLIB := lib
examples:= test
all: $(examples)
test : test.cpp
$(CXX) $(CXXFLAGS) -o $# $^ $(LIBS)
clean:
-rm -f *.o
-rm -f $(examples)
.PHONY: install
install:
sudo install -m 644 $(OLIB)/libarducam_mipicamera.so /usr/lib/
And the CMakefile I have so far is:
cmake_minimum_required(VERSION 3.11)
project( DisplayImage )
set(CMAKE_CXX_STANDARD 11)
find_package( OpenCV REQUIRED )
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable( DisplayImage test.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
I am confused on how to add the arducam library to the CMakefile. The header file is in the same directory as the main file and the .so file is in a subdirectory under.
How do I go about adding this simple library to the CMakefile, so that it compiles successfully (like the makefile)? This is not meant to be a dumb question, I just finished reading the CMake documentation. I am just confused about how to go about adding this library to the CMakefile. Does it involve using calls like link_directories() and target_link_libraries()?
The CMakefile should work if you add two more lines.
If the library is called arducam_mipicamera (which it looks like in this case), then you can use find_library(). And if the .so library file is in a subdirectory, the command should simply come out to:
find_library(ARDUCAM_LIBRARY arducam_mipicamera HINTS /*)
Where the first parameter is the name of your library (within the context of the CMakefile, you can rename this to whatever you want) and the last parameter gives the command a hint where the library is located (in this case a subdirectory).
Don't forget to link the library to target!
target_link_libraries( DisplayImage ${ARDUCAM_LIBRARY} )
The final CMakefile should come out to:
cmake_minimum_required(VERSION 3.11)
project( DisplayImage )
set(CMAKE_CXX_STANDARD 11)
find_library(ARDUCAM_LIBRARY arducam_mipicamera HINTS /*)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable( DisplayImage test.cpp )
target_link_libraries( DisplayImage ${OpenCV_LIBS} )
target_link_libraries( DisplayImage ${ARDUCAM_LIBRARY} )
Related
I would like to build a C++ library using cmake.
The library would require a on-the-fly opencv download and build then this library will be used in an other cmake project as a library.
The project structure is like that:
template_matching_project
|
|-- build
|-- template_matching_project
| |
| |-- template_matching_library
| |
| | -- src
| | -- include
| | -- CMakeLists.txt
|-- main.cpp
|-- CMakeLists.txt
The template_matching_library performs some image processing using opencv, there is the content of its cmake file in template_matching_project/template_matching_library/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 11)
project(template_matching)
# third party
include(ExternalProject)
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/3rdparty)
set(EXTERNAL_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}/Download)
# OpenCV
ExternalProject_Add(opencv-contrib
GIT_REPOSITORY https://github.com/opencv/opencv_contrib.git
GIT_TAG e6f32c6
SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv-contrib"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
ExternalProject_Add(opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 01b2c5a
SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv"
CMAKE_ARGS
-DBUILD_DOCS:BOOL=OFF
...
)
add_dependencies(opencv opencv-contrib)
# set source directories
set(PROJECT_SOURCE_DIR source)
set(INCLUDE_DIR include)
# set source files
file(GLOB_RECURSE SRCS ${PROJECT_SOURCE_DIR}/*)
file(GLOB_RECURSE HEADERS ${INCLUDE_DIR}/*)
# build library
link_directories(${EXTERNAL_INSTALL_LOCATION}/opencv/lib)
include_directories(${EXTERNAL_INSTALL_LOCATION}/opencv/include/opencv4)
include_directories(${INCLUDE_DIR})
add_library(${PROJECT_NAME} SHARED ${SRCS} ${HEADERS})
add_dependencies(${PROJECT_NAME} opencv)
target_link_libraries(${PROJECT_NAME} opencv_core opencv_highgui opencv_imgproc)
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})
The template_matching_library is correctly build with this cmake, but the build of the main.cpp executable fails
Here is the template_matching_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 11)
project(markers)
# include library
add_subdirectory(template_matching_library)
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/3rdparty)
include_directories(${EXTERNAL_INSTALL_LOCATION}/opencv/include/opencv4)
# add file to compile
set(SRCS main.cpp)
# add executable
add_executable(${PROJECT_NAME} ${SRCS})
# add dependencies
target_link_libraries(${PROJECT_NAME} template_matching)
Then trying the build with the convetional
cd build
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug
make
I have the following error
[ 95%] Building CXX object CMakeFiles/markers.dir/main.cpp.o
[100%] Linking CXX executable markers
/usr/bin/ld: cannot find -lopencv_core
/usr/bin/ld: cannot find -lopencv_highgui
/usr/bin/ld: cannot find -lopencv_imgproc
collect2: error: ld returned 1 exit status
Any suggestion to solve my problem? Should I change one/both of those CMakeLists.txt.
Thanks.
I have it worked with those two CMakeLists.txt, if some have any suggestions or better solution.
template_matching_project/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 11)
project(markers)
add_subdirectory(template_matching_library)
set(SRCS main.cpp)
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} template_matching ${OpenCV_LIBS})
template_matching_project/template_matching_library/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 11)
project(template_matching)
# third party
include(ExternalProject)
set(EXTERNAL_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/3rdparty)
set(EXTERNAL_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}/Download)
# OpenCV
ExternalProject_Add(opencv-contrib
GIT_REPOSITORY https://github.com/opencv/opencv_contrib.git
GIT_TAG e6f32c6
SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv-contrib"
...
)
ExternalProject_Add(opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 01b2c5a
SOURCE_DIR "${EXTERNAL_DOWNLOAD_LOCATION}/opencv"
CMAKE_ARGS
-DBUILD_DOCS:BOOL=OFF
...
-DOPENCV_EXTRA_MODULES_PATH:PATH=${EXTERNAL_DOWNLOAD_LOCATION}/opencv-contrib/modules
)
add_dependencies(opencv opencv-contrib)
set(OpenCV_DIR ${EXTERNAL_INSTALL_LOCATION}/opencv/lib/cmake/opencv4)
find_package(OpenCV REQUIRED PATHS ${EXTERNAL_INSTALL_LOCATION}/opencv)
# set source directories
set(PROJECT_SOURCE_DIR source)
set(INCLUDE_DIR include)
# set source files
file(GLOB_RECURSE SRCS ${PROJECT_SOURCE_DIR}/*)
file(GLOB_RECURSE HEADERS ${INCLUDE_DIR}/*)
# build library
include_directories(${EXTERNAL_INSTALL_LOCATION}/opencv/include/opencv4)
include_directories(${INCLUDE_DIR})
add_library(${PROJECT_NAME} SHARED ${SRCS} ${HEADERS})
add_dependencies(${PROJECT_NAME} opencv)
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})
Nevertheless, using my two CMakeLists.txt, I do have to run twice cmake and make commands, unless I have a links errors with opencv, like the following:
cd build
cmake .. -G "Unix Makefiles
make
cmake .. -G "Unix Makefiles
make
Is there a way to have work with a single run cmake/make?
I try some FetchContent but was not able to make it worked. My cmake version is 3.5.1
When cross-compiling the Azure IoT SDK for C with CMake, it also tries to build some samples. But it doesn't link these samples against libcurl, i.e. -lcurl is missing from the corresponding command line. Thus I am getting a lot of undefined references. For example:
../../../c-utility/libaziotsharedutil.a(httpapi_curl.c.o): In function `HTTPAPI_Init':
httpapi_curl.c:(.text+0x408): undefined reference to `curl_global_init'
This is how I call the build script:
cd azure-iot-sdk-c/build_all/linux && ./build.sh --toolchain-file ../../../_toolchain.cmake -cl --sysroot=$(ROOTFS_STAGING_PATH)
And this is how my toolchain file looks like:
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_PROCESSOR arm)
SET(CMAKE_C_COMPILER $ENV{TOOLCHAIN_PATH}/bin/$ENV{LNXP_TARGET}-gcc)
SET(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN_PATH}/bin/$ENV{LNXP_TARGET}-g++)
SET(CMAKE_SYSROOT $ENV{ROOTFS_STAGING_PATH})
SET(CMAKE_FIND_ROOT_PATH $ENV{ROOTFS_STAGING_PATH})
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CURL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/include)
SET(CURL_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/lib)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/include)
LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../../Supplies/curl/lib)
SET(use_default_uuid ON CACHE BOOL "")
SET(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "")
I am misusing the toolchain file to set some options, because the build script doesn't let me set the options directly.
This is what the command line to build the samples looks like:
/<toolchain path>/arm-sc1x5-linux-gnueabihf-gcc --sysroot=/<sysroot path> --sysroot=/<sysroot path> -fPIC -Werror -rdynamic CMakeFiles/iothub_convenience_sample.dir/iothub_convenience_sample.c.o CMakeFiles/iothub_convenience_sample.dir/__/__/__/certs/certs.c.o -o iothub_convenience_sample -L/<curl path>/lib -Wl,-rpath,/<curl path>/lib:/usr/local/lib ../../libiothub_client.a ../../libiothub_client_http_transport.a ../../libiothub_client_amqp_transport.a ../../libiothub_client_amqp_ws_transport.a ../../../uamqp/libuamqp.a ../../../c-utility/libaziotsharedutil.a ../../libiothub_client_mqtt_transport.a ../../libiothub_client_mqtt_ws_transport.a ../../../umqtt/libumqtt.a ../../../libparson.a ../../../c-utility/libaziotsharedutil.a /<sysroot path>/usr/local/lib/libssl.so /<sysroot path>/usr/local/lib/libcrypto.so -lpthread -lm -lrt
What am I doping wrong?
I am trying to create the script to compile and run as mentioned by emscirpten.
This is the command I wish to create a cmake file for.
./emcc -std=c++11 -O3 -I.. ~/DLIB/dlib-19.4/dlib/all/source.cpp -I/home/akshay/DLIB/dlib-19.4 -I/usr/include/X11/ -lpthread -lX11 -lopencv_imgcodecs -o webca.js ~/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp -ldlib `pkg-config opencv --cflags --libs`
So far I have come up with this. This is my CMAKELists.txt file.
cmake_minimum_required(VERSION 3.5.1)
project(DLIB)
SET(CMAKE_BUILD_TYPE_INIT "Release")
set(CMAKE_CXX_STANDARD 11)
if (${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
set(CMAKE_C_COMPILER "emcc")
endif ()
if(NOT DEFINED OpenCV_PREFIX)
set(OpenCV_PREFIX ${CMAKE_INSTALL_PREFIX})
endif()
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
set(DLIB_SRC "/home/akshay/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp")
add_library(DLIB_static ${DLIB_SRC})
set(OpenCV_PREFIX /usr/share/OpenCV/OpenCVConfig.cmake)
include_directories(/usr/include/X11 /home/akshay/DLIB/dlib-19.4 /home/akshay/DLIB/dlib-19.4/dlib/all/source.cpp)
set_target_properties(DLIB_static PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")
find_package(PkgConfig REQUIRED)
find_package(OpenCV REQUIRED
PATHS ${OpenCV_PREFIX}/lib/cmake/
${OpenCV_PREFIX}/share/OpenCV/
NO_DEFAULT_PATH)
find_library(OpenCV REQUIRED PATHS ${OpenCV_PREFIX}/lib/cmake/
${OpenCV_PREFIX}/share/OpenCV/
NO_DEFAULT_PATH)
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -O3 -lpthread -lX11 -lopencv_imgcodecs -ldlib `pkg-config opencv --cflags --libs`")
#file(GLOB_RECURSE CORE_HDR src/.h)
#file(GLOB_RECURSE CORE_SRC src/.cpp)
add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
add_executable(DLIB /home/akshay/DLIB/dlib-19.4/examples/webcam_face_pose_ex.cpp)
When I run this command :cmake -DCMAKE_PREFIX_PATH=/usr/share/OpenCV/OpenCVConfig.cmake -DCMAKE_BUILD_TYPE=Debug -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/akshay/Downloads/emsdk-portable/emscripten/1.37.16/cmake/Modules/Platform/Emscripten.cmake . && make
It gives me an error like so :
CMake Error at CMakeLists.txt:25 (find_package):
Could not find a package configuration file provided by "OpenCV" with any
of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
provides a separate development package or SDK, be sure it has been
installed.
It seems to not be able to find the CMAKE_PREFIX_PATH or that I am not setting it correctly.
I have just started fiddling around with CMAKE since yesterday. I may have very little clue about what I have done. Have tried some of the other SO answers as well.
Any help will be appreciated
You simply need to set the OpenCV_DIR to the path where OpenCV is installed, for example:
cmake -DOpenCV_DIR=/usr/local/share/OpenCV ..
How can i use tcov on Solaris in make file? My make file makes .o files and then the .so files which is copying to the lib's folder. I work with Oracle BRM
CFLAGS_solaris= -g -xcg92 -xprofile=tcov
C++FLAGS_solaris= -g -library=%none -DPIN_NOT_USING_OSTREAM
CPPFLAGS = -I$(INCDIR) -I$(INCDIR_MDS) -DPCMCPP_CONST_SAFE
LDFLAGS_solaris= -G
SL_EXT_solaris= so
and i tried also:
this makes the .so file;
$(LIBBILL): $(OBJECTS) $(C++_OBJECTS) $(INCFILES) Makefile
$(C++) -o $(LIBBILL) $(LDFLAGS) $(OBJECTS) $(C++_OBJECTS) -lm -lpsiu_for_cm -xprofile=tcov
and this makes the .o files
$(OBJECTS): $(INCFILES) Makefile $(FILES)
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(FILES)
the result of that is the brm can't start.
If someone is looking for an answer I found the solution. You have to use
-xprofile=tcov while compiling .o files and also when you links .so file ;)
I am currently try to compile these files using HDF5
I have directly linked and included everything necessary ( I think) but still the compile unable to find the files that is needed
This is my Makefile:
CC = h5cc
FC = h5fc
LD = h5fc
FDEBUG = -std -g -traceback
CFLAGS = -g -O0 -Wall -pedantic
FFLAGS = -g -O0 -Wall -I$(H5DIR)/include -L$(H5DIR)/lib/libhdf5hl_fortran.a
LDFLAGS = -I$(H5DIR)/include -L$(H5DIR)/lib/libhdf5hl_fortran.a
#LDFLAGS = -I$(MKLROOT)/include -L$(MKLROOT) -mkl=sequential
# -opt-block-factor=16 -opt-prefetch=4 \
.SUFFIXES:
.SUFFIXES: .c .f .f90 .F90 .o
OBJS = timing.o \
kinds.o \
rw_matrix.o \
EXE = matmul_omp.exe
all: $(EXE)
$(EXE): $(OBJS) matmul_omp.o
$(LD) $(LDFLAGS) -o $# $^
.f90.o:
-$(RM) -f $*.o $*.mod
$(FC) $(FFLAGS) -c $<
.c.o:
$(CC) $(CFLAGS) -c $<
.PHONEY: clean
clean:
THis is the err:
h5fc -I/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/include -L/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/lib/libhdf5hl_fortran.a -o matmul_omp.exe timing.o matmul_omp.o
gfortran: /usr/lib64/libhdf5hl_fortran.a: No such file or directory
gfortran: /usr/lib64/libhdf5_hl.a: No such file or directory
gfortran: /usr/lib64/libhdf5_fortran.a: No such file or directory
gfortran: /usr/lib64/libhdf5.a: No such file or directory
As you can see that I directly link libhdf5hl_fortran.a. but i dont know why the error is giving a different directory /usr/lib64/
I think you have a couple of things wrong here.
If you are using h5fc then you shouldn't need to add all the include and lib paths. That is the whole point of the helper applications.
You are adding the paths that have Intel, yet your h5fc has a GNU (gfortran) error.
The gfortran build of HDF5 looks as if it does not have the fortran bindings built.
I would suggest trying the following. Using the full paths (as you have done) but call ifort instead of h5fc:
ifort -I/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/include \
-L/curc/tools/x_86_64/rh6/hdf5/1.8.13/szip/2.1/zlib/1.2.8/jpeglib/9a/openmpi/1.8.2/intel/13.0.0/lib/libhdf5hl_fortran.a \
-o matmul_omp.exe timing.o matmul_omp.o