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 ####################################
Related
I'm using and like QtCreator to code and build my ROS projects written in c++.
Unfortunately the auto-completion for my own header files is not working: e.g. #include "LineTracker.hh"
Building the project works perfectly. And also the auto-completion for other external packages like ros or opencv is working.
Update 2.0: With QtCreator 3.6 the solution is not working
Update 1.0: Found a solution, see bottom!
Thats how my CMakeLists.txt looks:
cmake_minimum_required(VERSION 2.8.3)
project(line_tracking)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(catkin REQUIRED COMPONENTS
roscpp
tf
sensor_msgs
image_transport
cv_bridge
)
catkin_package()
include_directories(
include
${catkin_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}
)
add_executable(${PROJECT_NAME}
src/line_tracking.cpp
src/EDLineDetector.cpp
src/LineTracker.cpp
)
target_link_libraries(${PROJECT_NAME}
${catkin_LIBRARIES}
)
# --- QT CREATOR STUFF ---
#Add all files in subdirectories of the project in
# a dummy_target so qtcreator has access to all files
FILE(GLOB children ${CMAKE_SOURCE_DIR}/*)
FOREACH(child ${children})
IF(IS_DIRECTORY ${child})
file(GLOB_RECURSE dir_files "${child}/*")
LIST(APPEND extra_files ${dir_files})
ENDIF()
ENDFOREACH()
add_custom_target(dummy_${PROJECT_NAME} SOURCES ${extra_files})
#
The file/package structure looks standard like this:
CMakeLists.txt
|
+ -- src
|
+ -- include
How do I have to adapt my CMakeLists.txt that QtCreator finds my headers for autocompletion?
Thank you very much for your help!
Sidenote:
When I use the top CMakeLists.txt file of the catkin workspace in QtCeator and I include the header files under their package path like this: #include <packageName/include/headerFile.h> the auto-completion is working but the build is not working anymore. So this is only a bad and not userfriendly hack to get auto-completion during coding.
Update 1.0:
I found a solution which is working:
I create a library from all the (class) files which have header files, and link the library to the main file, instead of adding the files as executables. I posted it here as answer.
But I don't know why it is working like this and not without the way over the library. Any explanations?
Update 2.0:
I just upgraded to QtCreator 3.6 and there my solution with the library in not working anymore.
Does anybody know another solution?!
Update: This solution does NOT work with QtCreator 3.6
I found a solution to my own question. Not so much fun, but anyway, I spent a lot of time with that issue so here the solution, which is hopefully useful for others:
Auto-completion with CMakeLists.txt in QtCreator 3.5.1 for your own classes:
Create a library with all your classes: ADD_LIBRARY(myFilesLib src/class1.cpp ...)
Add your executable (main function): add_executable(${PROJECT_NAME} src/main.cpp)
Link your library to your executable: target_link_libraries(${PROJECT_NAME} myFilesLib)
With this way over the library, auto-completion is working in QtCreator!
For ROS (catkin) don't forget to link the ${catkin_LIBRARIES}.
Here the whole CMakeLists.txt:
cmake_minimum_required(VERSION 2.8.3)
project(example_project)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(catkin REQUIRED COMPONENTS
roscpp
)
catkin_package()
include_directories(
include
${catkin_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}
)
# Create a library with all your classes
add_library(myFilesLib
src/class1.cpp
src/class2.cpp
src/class3.cpp
)
target_link_libraries(myFilesLib
${catkin_LIBRARIES}
)
# add your executable
add_executable(${PROJECT_NAME}
src/main.cpp
)
# link the library with your classes to the executable
target_link_libraries(${PROJECT_NAME}
${catkin_LIBRARIES}
myFilesLib
)
I don't know why it is working only with the way over the library but it is working. Maybe somebody has an explanation?!
This is really annoying. Finally I figured out a solution, that works at Qt Creator 4.1.0, and probably works at other versions.
Write your include_directories correctly, so that compilation is OK.
Below the include_directories, add the following line. Note that the sequence matters, the following line must locate below the include_directories.
file(GLOB_RECURSE HEADERS */*.hpp */*.h)
Add ${HEADERS} # for qtcreator... in one of your add_executable. like:
add_executable(slam_pp_node
${HEADERS} # for qtcreator...
src/***.cpp
)
The above should be enough to solve the autocompletion problem. If not, add the following lines at the end of your CMakeList.txt:
file(GLOB_RECURSE EXTRA_FILES */*)
add_custom_target(${PROJECT_NAME}_OTHER_FILES ALL WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} SOURCES ${EXTRA_FILES})
Good luck!
I have a C++ project with this structure:
-- ProjectFolder
-- Project_Prototype1
-- Project_Prototype2
Project_Prototype1 has a CMakeLists file with this content:
cmake_minimum_required(VERSION 2.8)
project( Neuromarketing-RF )
find_package( Boost 1.58.0 REQUIRED COMPONENTS filesystem system )
include_directories( ${Boost_INCLUDE_DIRS} include src/external )
find_package( OpenCV 3 REQUIRED )
file(GLOB FACETRACKER_HEADERS "external/FaceTracker/include/FaceTracker/*.h")
file(GLOB FACETRACKER_SRC "external/FaceTracker/src/lib/*.cc")
file(GLOB SOURCES "src/*cpp")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "bin/")
add_executable( Neuromarketing-RF ${FACETRACKER_SRC} ${SOURCES} )
target_link_libraries( Neuromarketing-RF ${OpenCV_LIBS} ${Boost_LIBRARIES} )
target_compile_features( Neuromarketing-RF PRIVATE cxx_range_for )
Prototype1 is using an external library called FaceTracker .
In the Prototype2 I wanna access a file from Prototype1 but I don't want to redefine all dependencies from Prototype1 on Prototype2 CMakeLists (FaceTracker, Boost, etc...).
How can I write the Prototype2 CMakeLists to use Prototype1 without redefining everything manually?
Here is my current CMakeLists.txt for Prototype2:
cmake_minimum_required (VERSION 2.6)
project (Neuromarketing-CNN)
find_package(OpenCV REQUIRED)
find_package(Boost 1.58.0 REQUIRED COMPONENTS filesystem system)
add_subdirectory("../Neuromarketing-RF" "../Neuromarketing-RF/bin" )
file ( GLOB NM_RF_SRC "../Neuromarketing-RF/src/*.cpp" )
include_directories(include ../Neuromarketing-RF/include ${Boost_INCLUDE_DIRS} )
file(GLOB SOURCES "src/*.cpp")
add_executable (bin/Neuromarketing-CNN ${SOURCES} ${NM_RF_SRC} )
target_link_libraries(bin/Neuromarketing-CNN ${OpenCV_LIBS} ${Boost_LIBRARIES} )
target_compile_features( bin/Neuromarketing-CNN PRIVATE cxx_range_for )
The easiest way would be to create a file containing all the dependencies common to both CMakeList.txt files and use include(). For instance have a file names ProjectFolder/my-includes.cmake that contains the relevant find_package() statements, and in both CMakeList.txt files add a line
include ("../my-includes.cmake")
Everything defined in the included file is available to the including file.
This is a total cmake noob question I'm sure.
I'm working on an OpenCV project and wish to test something using the latest beta release. How can I specify the beta libraries without installing them onto my system? My beta opencv has been successfully built in:
/Users/paul/hacking/robotics/opencv/build/lib/
My current cmake has basically been lifted from the opencv samples and looks like this:
# cmake for Stereo Vision App
# your opencv/build directory should be in your system PATH
# set minimum required version for cmake
cmake_minimum_required(VERSION 2.8)
# define the project name
set(project_name "Stereo")
# set the project namee
project("${project_name}")
# add opencv package to the project
find_package( OpenCV REQUIRED )
MESSAGE("OpenCV version : ${OpenCV_VERSION}")
# add opencv include directories to the project
include_directories( ${OpenCV_INCLUDE_DIRS} )
# add include directory
include_directories (${Stereo_SOURCE_DIR})
# add library
add_library( CameraCalibrator CameraCalibrator.cpp)
# add executable
#add_executable( videoprocessing videoprocessing.cpp)
#add_executable( tracking tracking.cpp)
#add_executable( foreground foreground.cpp)
add_executable( calibrate calibrate.cpp)
add_executable( rightsideup rightsideup.cpp)
add_executable( live live.cpp)
add_executable( live2 live2.cpp)
add_executable( stereo-tune stereo-tune.cpp)
add_executable( project project.cpp)
add_executable( stereo_calibrate stereo_calibrate.cpp)
add_executable( capture_two_camera_chessboards capture_two_camera_chessboards.cpp)
add_executable( capture_stereo_chessboards capture_stereo_chessboards.cpp)
# link libraries
#target_link_libraries( videoprocessing ${OpenCV_LIBS})
#target_link_libraries( tracking ${OpenCV_LIBS})
#target_link_libraries( foreground ${OpenCV_LIBS})
target_link_libraries( rightsideup ${OpenCV_LIBS})
target_link_libraries( live ${OpenCV_LIBS})
target_link_libraries( live2 ${OpenCV_LIBS})
target_link_libraries( stereo-tune ${OpenCV_LIBS})
target_link_libraries( project ${OpenCV_LIBS})
target_link_libraries( stereo_calibrate ${OpenCV_LIBS})
target_link_libraries( capture_two_camera_chessboards ${OpenCV_LIBS})
target_link_libraries( capture_stereo_chessboards ${OpenCV_LIBS})
target_link_libraries( calibrate ${OpenCV_LIBS} CameraCalibrator)
I've tried using link_libraries and setting the version on the find package line to 3.0, however it always finds the system installed libraries 2.4.10
Edit 1:
cmake -DPCL_DIR:PATH="../../pcl/build" -DOpenCV_DIR:PATH="../../opencv/build" ..
Is not working for me for some reason. Likewise when I try to set these variables inside the CMake script it also does not work.
set(PCL_DIR "../../pcl/build" CACHE PATH "")
set(OpenCV_DIR "../../opencv/build" CACHE PATH "")
Many thanks!
Paul
You're going in the right direction. cmake's Find scripts look in the standard system paths first unless told otherwise. Each FIND script has its own set of cmake variables which you can set to alter the behaviour.
For FindOpenCV.cmake it seems to be OPENCV_BASE_DIR.
Here's a link to some source code:
https://github.com/rpavlik/cmake-modules/blob/master/FindOpenCV.cmake
Edit:
I don't fully understand, but the following seems to work with absolute paths
set(OpenCV_DIR "/Users/paul/hacking/robotics/opencv/build" CACHE PATH "")
set(PCL_DIR "/Users/paul/hacking/robotics/pcl/build" CACHE PATH "")
set(VTK_DIR "/Users/paul/hacking/robotics/VTK/build" CACHE PATH "")
At least less things to go wrong if I get the command line wrong, I no longer need to remember to do the following:
OpenCV_DIR=../../opencv/build cmake ..
In the PCL documentation it says to use:
set(PCL_DIR "/path/to/PCLConfig.cmake")
But this doesn't work for me.
I am using OpenCV 2.3 on Windows 7 32 bits with Visual C++ 2010.
My CMakeLists file looks like that:
SET( PROJECT_NAME Tennis_tracking )
PROJECT( ${PROJECT_NAME} )
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
FIND_PACKAGE( OpenCV REQUIRED )
ADD_EXECUTABLE( ${PROJECT_NAME} main.cpp )
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${OpenCV_LIBS} )
ADD_EXECUTABLE( histogram histogram.cpp )
TARGET_LINK_LIBRARIES( histogram ${OpenCV_LIBS} )
For example I'd like to create a custom function "getImageHistogram" for example (which already exists in OpenCV) that will be used by main.cpp. The header and main files are done, how do I link those in my CMakeLists?
Thank you very much.
As long as you are using C++ you can define this function within another (custom) namespace and call it as custom::getImageHistogram().
And for the CMake part, there's nothing special to be done since you are already adding that file to the build process:
ADD_EXECUTABLE( ${PROJECT_NAME} main.cpp )
My program uses giblib and Imlib2 library and it is built with cmake.
It works perfectly in my computer but not in other's.
I guess the reason is I installed every library what my program needs but other's doesn't.
My goal is making standalone program. (don't need to install any other library addtionally)
What should I add in cmake file?
projectDef.cmake source code
file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
X11/[^.]*.cpp
X11/[^.]*.h
X11/[^.]*.cmake
)
SOURCE_GROUP(X11 FILES ${PLATFORM})
add_definitions(
)
set (SOURCES
${SOURCES}
${PLATFORM}
)
add_x11_plugin(${PROJECT_NAME} SOURCES)
target_link_libraries(${PROJECT_NAME}
${PLUGIN_INTERNAL_DEPS}
)
include_directories(/usr/include/giblib)
include_directories(/usr/include/X11)
target_link_libraries(MyProject X11)
target_link_libraries(MyProject Imlib2)
target_link_libraries(MyProject giblib)
CMakeList.txt source code
cmake_minimum_required (VERSION 2.6)
set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")
Project(${PLUGIN_NAME})
file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
[^.]*.cpp
[^.]*.h
[^.]*.cmake
)
include_directories(${PLUGIN_INCLUDE_DIRS})
SET_SOURCE_FILES_PROPERTIES(
${GENERATED}
PROPERTIES
GENERATED 1
)
SOURCE_GROUP(Generated FILES
${GENERATED}
)
SET( SOURCES
${GENERAL}
${GENERATED}
)
include_platform()
Try starting with this options in your root CMakeLists.txt:
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
BUILD_SHARED_LIBS is only needed if your project has its own libraries (add_library).
With the -static linker flag, you need static libs for ALL your additional libraries too! One common problem when static linking is to avoid circular dependencies.