Why does gcc can't find opencv.hpp file? - c++

I'm quite new to CMake, but I want to build a test .cpp file that includes OpenCV and shows me an image. I have built OpenCV in the path /usr/local and I have here folder with opencv.hpp file - /usr/local/include/opencv4/opencv2/opencv.hpp. Here is my CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0)
project(cpp_proj)
find_package(OpenCV REQUIRED)
add_executable(cpp_proj opencv_cpp.cpp)
include_directories(${OPENCV4_INCLUDES})
target_link_libraries(cpp_proj )
I opened ~./bashrc and added there lines:
export OPENCV4_INCLUDES=/usr/local/include/
export OPENCV4_LIBRARIES=/usr/local/lib/
export PATH=$PATH:$OPENCV4_LIBRARIES
export PATH=$PATH:$OPENCV4_INCLUDES
When I run cmake in bash - everything is ok and even find_package finds OpenCV. But when I'm trying to run make it gives me a error:
pi#raspberrypi:~/Desktop/cpp_proj/build $ cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/Desktop/cpp_proj/build
pi#raspberrypi:~/Desktop/cpp_proj/build $ make
[ 50%] Building CXX object CMakeFiles/cpp_proj.dir/opencv_cpp.cpp.o
/home/pi/Desktop/cpp_proj/opencv_cpp.cpp:1:10: fatal error: opencv2/opencv.hpp: No such file or directory
#include <opencv2/opencv.hpp>
^~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/cpp_proj.dir/build.make:63: CMakeFiles/cpp_proj.dir/opencv_cpp.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/cpp_proj.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
I found questions with the same problem, but they didn't help me. What I am doing wrong? What could be the reason of this? Thanks!

In order to use a library you must specify the include directory as well as the libs.
With find_package (in module mode), in your case it should populate the variables OpenCV_INCLUDE_DIRS and OpenCV_LIBS for you to use.
So I recommend to add / alter your code to add the include directory & link the library (such as below)
target_include_directories(${CMAKE_PROJECT_NAME} public ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${CMAKE_PROJECT_NAME} public ${OpenCV_LIBS})
I don't believe you ever need to touch ~./bashrc when using find_package

Related

Issue linking c++ library with cmake

I am trying to link the following library : nngpp
using the following commands
mkdir build
cd build
cmake ..
make
make install
However when testing the demos or using the library in a project with the following in CMakeLists.txt :
...
add_executable(target main.cpp)
target_link_libraries(target nngpp)
I get the following error:
fatal error: 'nngpp/nngpp.h' file not found
#include <nngpp/nngpp.h>
^~~~~~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/rest.dir/rest/server.o] Error 1
make[1]: *** [CMakeFiles/rest.dir/all] Error 2
make: *** [all] Error 2
note : The library is header-only. but I don't want to copy it in my project.
With
find_package(nngpp)
using the library is straightforward:
add_executable(target main.cpp)
target_link_libraries(target nng::nngpp)
Here nng::nngpp is IMPORTED library, so it cares about include directories for you.
It's hard to know exactly what's wrong without more information. I would suggest running make VERBOSE=1. This will show you the command line that is being executed when trying to compile the file that gives you the error.
Look in the command line for include flags (e.g. -I flags if you're using gcc). Find the directory for nngpp and double-check if your header files are in there, and what the correct path relative to that directory is to reference the header file. Maybe you need to only #include <nngpp.h> instead?
The following worked :
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(comm)
set(CMAKE_CXX_STANDARD 11)
find_package(nng REQUIRED)
find_package(Threads)
find_package(nngpp REQUIRED)
add_executable(server src/tfo-server.cpp)
target_link_libraries(server nng::nng nng::nngpp)
This also worked:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(comm)
set(CMAKE_CXX_STANDARD 11)
add_executable(server src/tfo-server.cpp)
include_directories(server /usr/local/include)

How to link SDL2 manually in CMake

Recently I have started to learn CMake. To practice, I am trying to link SDL2 manually. I know that there is another way around using find_file which is easy. But I want to do it myself for practice.
I get an error when I try to link the libSDL2main.a file (running the Makefile using cmd mingw32-make)
[ 50%] Linking CXX executable exe0.exe
c:/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: cannot find -llibSDL2main
collect2.exe: error: ld returned 1 exit status
CMakeFiles\exe0.dir\build.make:105: recipe for target 'exe0.exe' failed
mingw32-make[2]: *** [exe0.exe] Error 1
CMakeFiles\Makefile2:94: recipe for target 'CMakeFiles/exe0.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/exe0.dir/all] Error 2
Makefile:102: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
Here is my CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(SDL_Test_Project)
include_directories(include)
add_executable(exe0 main.cpp)
target_link_libraries(exe0 libSDL2main.a)
Here main.cpp is only a source file. I have put SDL2.dll and libSDL2main.a into the root of the project directory. (I used the CMake GUI to generate the Makefile in Windows 10).
If you want to link to the SDL2 libraries directly in target_link_libraries() (without defining IMPORTED targets, or using find_library()), use the full path to each library. The CMAKE_SOURCE_DIR variable provides the full path to the root directory of the CMake project:
target_link_libraries(exe0 PRIVATE
mingw32
${CMAKE_SOURCE_DIR}/libSDL2main.a
${CMAKE_SOURCE_DIR}/SDL2.dll
)
Note, for SLD2, you may also have to add the mingw32 to this command when using MinGW for compilation.

CMakeLists: Adding source files from Github with ExternalProject

I'm writing a small catkin wrapper for the Beckhoff ADS library. I would like to install the files from the AdsLib folder but without using the CMake file from Beckhoff.
I just want to copy the files in order to add them to my library in my own CMakeLists. This works fine if I copy the files manually. But I would like to build directly using the latest files from the Github source.
I tried every possible combination I could find here on stackoverflow, but somehow couldn't make it work.
cmake_minimum_required(VERSION 2.8.3)
project(ads_catkin)
find_package(catkin_simple REQUIRED)
catkin_simple()
include(ExternalProject)
ExternalProject_Add(ads
PREFIX ${CMAKE_BINARY_DIR}/ads
GIT_REPOSITORY https://github.com/Beckhoff/ADS.git
GIT_TAG master
CONFIGURE_COMMAND ""
#GIT_TAG 6b3a03009a757cf651fe44d8be7b6df698028f0e
UPDATE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(ads source_dir)
cs_add_library(${PROJECT_NAME}
${source_dir}/AdsLib/AdsDef.cpp
)
cs_install()
cs_export()
The first time I'm building with catkin_tools, this gives me:
Errors << ads_catkin:cmake /home/xxx/xxx_ws/logs/ads_catkin/build.cmake.000.log
CMake Error at /home/xxx/xxx_ws/devel/share/catkin_simple/cmake/catkin_simple-extras.cmake:150 (add_library):
Cannot find source file:
/home/xxx/xxx/build/ads_catkin/ads/src/ads/AdsLib/AdsDef.cpp
Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp
.hxx .in .txx
Call Stack (most recent call first):
CMakeLists.txt:23 (cs_add_library)
CMake Error: CMake can not determine linker language for target: ads_catkin
CMake Error: Cannot determine link language for target "ads_catkin".
Then, the second time I run the build tool over the same code, the files get actually cloned, but I end up with this error:
Errors << ads_catkin:make /home/xxx/xxx_ws/logs/ads_catkin/build.make.000.log
make[2]: *** No rule to make target 'CMakeFiles/ads_catkin.dir/build'. Stop.
make[1]: *** [CMakeFiles/ads_catkin.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Cloning into 'ads'...
Already on 'master'
make: *** [all] Error 2
Btw: cs_add_library is the catkin_simple form for add_library and target_link_libraries.
Update:
Getting closer... adapting the solution from #Tsyvarev to my file:
cmake_minimum_required(VERSION 2.8.3)
project(ads_catkin)
find_package(catkin_simple REQUIRED)
catkin_simple()
include(ExternalProject)
ExternalProject_Add(ads
PREFIX ${CATKIN_DEVEL_PREFIX}/ads
GIT_REPOSITORY https://github.com/Beckhoff/ADS.git
GIT_TAG 6b3a03009a757cf651fe44d8be7b6df698028f0e
#GIT_TAG master
CONFIGURE_COMMAND ""
UPDATE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
BUILD_BYPRODUCTS
<SOURCE_DIR>/AdsLib/AdsDef.cpp
<SOURCE_DIR>/AdsLib/AdsLib.cpp
<SOURCE_DIR>/AdsLib/AmsConnection.cpp
<SOURCE_DIR>/AdsLib/AmsPort.cpp
<SOURCE_DIR>/AdsLib/AmsRouter.cpp
<SOURCE_DIR>/AdsLib/Frame.cpp
<SOURCE_DIR>/AdsLib/Log.cpp
<SOURCE_DIR>/AdsLib/NotificationDispatcher.cpp
<SOURCE_DIR>/AdsLib/Sockets.cpp
<SOURCE_DIR>/AdsLib/AdsDef.h
<SOURCE_DIR>/AdsLib/AdsLib.h
<SOURCE_DIR>/AdsLib/AdsNotification.h
<SOURCE_DIR>/AdsLib/AmsConnection.h
<SOURCE_DIR>/AdsLib/AmsHeader.h
<SOURCE_DIR>/AdsLib/AmsPort.h
<SOURCE_DIR>/AdsLib/AmsRouter.h
<SOURCE_DIR>/AdsLib/Frame.h
<SOURCE_DIR>/AdsLib/Log.h
<SOURCE_DIR>/AdsLib/NotificationDispatcher.h
<SOURCE_DIR>/AdsLib/RingBuffer.h
<SOURCE_DIR>/AdsLib/Router.h
<SOURCE_DIR>/AdsLib/Semaphore.h
<SOURCE_DIR>/AdsLib/Sockets.h
<SOURCE_DIR>/AdsLib/wrap_endian.h
<SOURCE_DIR>/AdsLib/wrap_socket.h
)
ExternalProject_Get_Property(ads SOURCE_DIR)
include_directories(
${SOURCE_DIR}/AdsLib
)
cs_add_library(AdsLib
${SOURCE_DIR}/AdsLib/AdsDef.cpp
${SOURCE_DIR}/AdsLib/AdsLib.cpp
${SOURCE_DIR}/AdsLib/AmsConnection.cpp
${SOURCE_DIR}/AdsLib/AmsPort.cpp
${SOURCE_DIR}/AdsLib/AmsRouter.cpp
${SOURCE_DIR}/AdsLib/Frame.cpp
${SOURCE_DIR}/AdsLib/Log.cpp
${SOURCE_DIR}/AdsLib/NotificationDispatcher.cpp
${SOURCE_DIR}/AdsLib/Sockets.cpp
)
add_dependencies(AdsLib ads)
cs_install()
install(DIRECTORY ${SOURCE_DIR}/AdsLib/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".cpp" EXCLUDE
)
cs_export()
I tried to include the header files in my AdsLib library. But I still get an error:
In file included from /home/xxx/xxx_ws/src/xxx/nav_controller/src/controller.cpp:19:0:
/home/xxx/xxx_ws/src/xxx/nav_controller/include/nav_controller/controller.h:27:10: fatal error: AdsLib.h: No such file or directory
#include "AdsLib.h"
^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/nav_controller.dir/src/controller.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
In file included from /home/xxx/xxx_ws/src/xxx/nav_controller/src/test.cpp:22:0:
/home/xxx/xxx_ws/src/xxx/nav_controller/include/nav_controller/controller.h:27:10: fatal error: AdsLib.h: No such file or directory
#include "AdsLib.h"
^~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/nav_controller.dir/src/test.cpp.o] Error 1
make[1]: *** [CMakeFiles/nav_controller.dir/all] Error 2
make: *** [all] Error 2
The CMake error Cannot find source file means a simple thing: Nothing tells CMake that given source file is generated and the file itself is absent.
Because the file is generated in ExternalProject_Add, you need to adjust corresponded target-level dependency:
add_dependency(ads_catkin ads)
This command should be issued after both add_library() and ExternalProject_Add calls which create corresponded targets. This command tells CMake that the library should be built only after all steps for the external project has been performed.
You still need to tell CMake that the source file is generated. There are two ways for doing this.
Set GENERATED property:
set_source_files_properties(${source_dir}/AdsLib/AdsDef.cpp PROPERTIES GENERATED TRUE)
This prevents CMake to search the file on the configuration stage.
List file in the BYPRODUCTS option for the target which generates it. For the target created by ExternalProject_Add command this is achieved by additional option to that command
BUILD_BYPRODUCTS <SOURCE_DIR>/AdsLib/AdsDef.cpp
This also sets GENERATED property for the source file, as in the first case. But BYPRODUCTS also makes your project usable for Ninja users.
(In the option above expression <SOURCE_DIR> is a special way to refer to ExternalProject's source directory. It is usable for some ExternalProject's options, and BUILD_BYPRODUCTS is one of them).
Technically, CMake should be smart enough for adding target-level dependencies (the effect of add_dependency(ads_catkin ads)) automatically when it sees corresponded BYPRODUCTS option. But this feature is described only for 3.16 version, and I don't know whether it works in older versions.
In the end, even with the good help from #Tsyvarev, I couldn't make it work using ExternalProject_Add. Part of the solution is to manually export the library with cs_export(INCLUDE_DIRS ${ads}), which didn't work with ExternalProject_Add, because the files were not available at this time.
In the end, I included the DownloadProject module, which is a predecessor of FetchContent, in my package. This does what it should.

CMAKE and MKOCTFILE

I'm working on a C/C++ project and I'm using CMAKE 3.5.2 for build. However, now I must to include a C++ file which uses Octave functions. I am able to compile this source file directly by line command using this command: mkoctfile --link-stand-alone new_oct_file -o final_library.
I'm struggling to do CMAKE execute this command. I've tried to use an add_custom_command, but it didn't work. Can someome help me?
My CMAKE has the following structure
cmake_minimum_required(VERSION 2.8)
project(final_library)
add_executable(final_library program.c
./Commons/util.c
./Tools/xulambs_tool.cpp)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
include_directories(/usr/include/octave-4.0.0/octave)
install(TARGETS final-library RUNTIME DESTINATION bin)
add_subdirectory(Commons)
add_subdirectory(Tools)
I've tried to add the following command (it does not work):
set(MKOCTFILE "mkoctfile")
set(OCTARG "--link-stand-alone")
add_custom_command(TARGET reordering-library
PRE_LINK
COMMAND ${MKOCTFILE} ARGS ${OCTARG} ./Tools/tool_octave.cpp)
The compilation output is
[ 4%] Linking CXX executable final-library
g++: error: ./Tools/tool_octave.cpp: No such file or directory
g++: fatal error: no input files
compilation terminated.
CMakeFiles/final-library.dir/build.make:694: recipe for target 'final-library' failed
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/final-library.dir/all' failed
Makefile:127: recipe for target 'all' failed
make[2]: *** [final-library] Error 1
make[1]: *** [CMakeFiles/final-library.dir/all] Error 2
make: *** [all] Error 2
Thanks.
I had the same problem as you and I fixed it by adding the liboctinterp.so in the target_link_libraries of the CMakeLists.txt file.
My current cmake file contains the following:
add_executable(MyEXE main.cc)
target_link_libraries(MyEXE liboctave.so liboctinterp.so)
The command at pre link is probably not executed in the source directory, so the relative path you used in the script will be invalid. Try using an absolute path, something like:
add_custom_command(TARGET reordering-library
PRE_LINK
COMMAND ${MKOCTFILE} ARGS ${OCTARG}
"${CMAKE_CURRENT_SOURCE_DIR}/Tools/tool_octave.cpp"
)

C++ / compilation of a program fatal error: QtGui/qwidget.h: No such file or directory

I've downloaded a linux application which required qt4.
I have it already on my computer.
I have this following error when I want to compile the program using make in the terminal.
[ 6%] Building CXX object CMakeFiles/util_convert.dir/moc_planeviewer.cxx.o
In file included from /usr/include/qt4/QtGui/QMainWindow:1:0,
from /home/Desktop/plane/src/planeviewer.h:3,
from /home/Desktop/plane/src/moc_planeviewer.cxx:9:
/usr/include/qt4/QtGui/qmainwindow.h:45:27: fatal error: QtGui/qwidget.h: No such file or directory
#include <QtGui/qwidget.h>
^
compilation terminated.
make[2]: *** [CMakeFiles/util_convert.dir/moc_planviewer.cxx.o] Error 1
make[1]: *** [CMakeFiles/util_convert.dir/all] Error 2
make: *** [all] Error 2
I don't understand because I checked already everything.
I have the following input for those different commands line:
qmake --version
QMake version 2.01a
Using Qt version 4.8.6 in /usr/lib/x86_64-linux-gnu
locate qwidget.h
/opt/qt/5.4/android_armv7/include/QtWidgets/qwidget.h
/opt/qt/5.4/gcc_64/include/QtWidgets/qwidget.h
/usr/include/qt4/Qt/qwidget.h
/usr/include/qt4/QtGui/qwidget.h
So the file already exists.
The CmakeList in case
find_package(Boost 1.58 REQUIRED COMPONENTS serialization program_options python)
find_package(PythonLibs 2.6 REQUIRED)
set(QT_USE_QTSVG TRUE)
set(QT_USE_QTXML TRUE)
set(QT_USE_QTOPENGL TRUE)
find_package(OpenGL)
find_package( Qt4 REQUIRED )
INCLUDE_DIRECTORIES("${Boost_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES("${PYTHON_INCLUDE_PATH}")
INCLUDE_DIRECTORIES(${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR} ${QT_QTSVG_INCLUDE_DIR}
${QT_QTXML_INCLUDE_DIR} ${QT_QTOPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIRS})
QT4_WRAP_UI(util_convert_FORMS planeviewer.ui)
QT4_WRAP_CPP(util_convert_MOCS planeviewer.h planewidget.h)
ADD_EXECUTABLE(util_convert ${util_convert_FORMS} ${util_convert_MOCS} plane.cpp util_convert.cpp planeviewer.cpp planewidget.cpp objects.cpp coordinates.cpp utils.cpp)
TARGET_LINK_LIBRARIES(util_convert ${Boost_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTSVG_LIBRARY}
${QT_QTXML_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES})
How I compile:
Go to src/ then do cmake . and finally make.
The error happened at the make step.
Before posting this, I already searched on the internet but didn't find a solution yet.
Can someone helps me ?
The problem is in INCLUDE_DIRECTORIES. I think that in your example QT_QTGUI_INCLUDE_DIR variable has value /usr/include/qt4/QtGui, but you need add /usr/include/qt4 to INCLUDE_DIRECTORIES, because in code include statement useses path <QtGui/qwidget.h>:
INCLUDE_DIRECTORIES("/usr/include/qt4")
Thanks to #gomons, I was able to compile it.
I added in the CmakeList the following line:
INCLUDE_DIRECTORIES("/usr/include/qt4/")