I'm trying to build a demo depending on GLEW and GLFW on macOS. I have installed GLEW and GLFW with brew and they both locate under /usr/local/Cellar. Then I use CMake to locate dependencies and my codes are as follows:
# for GLEW
set(GLEW_DIR /usr/local/Cellar/glew/2.1.0/lib/cmake/glew)
find_package(GLEW REQUIRED PATHS ${GLEW_DIR} NO_DEFAULT_PATH)
message(STATUS ${GLEW_INCLUDE_DIR})
# for GLFW
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
message(STATUS ${GLFW_INCLUDE_DIR})
But as a result the first message always prints /usr/local/include and the second prints nothing. What's the problem with my CMake code? Thanks.
Related
Summary
In Windows, CLion doesn't complain anything after cmake and before makefile.
All code seems to link correctly without error. I am able to see the reference, documents, linter and jump into cv::Mat or opencv.hpp header file with ctrl RMB.
CMake seems to correctly generate make files without error.
But the compile error occurs: undefined reference to OpenCV methods.
my setup
CMakeLists.txt:
cmake_minimum_required(VERSION 3.9)
project(test)
# Set compile version
set(CMAKE_CXX_STANDARD 17)
add_executable(test ./test.cpp )
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " libraries: ${OpenCV_LIBRARIES}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
target_link_libraries(test ${OpenCV_LIBRARIES})
The output seems correct
"D:\Program Files\JetBrains\CLion 2021.3.2\bin\cmake\win\bin\cmake.exe" -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - MinGW Makefiles" D:\repo\CS5330\test
-- OpenCV library status:
-- version: 4.5.5
-- libraries: opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_world
-- libraries: opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_world
-- include path: /path/to/scoop/apps/opencv/current/include
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/test/cmake-build-debug
[Finished]
And this generates CMakeCache.txt, which includes,
//The directory containing a CMake configuration file for OpenCV.
OpenCV_DIR:PATH= /path/to/scoop/apps/opencv/current/x64/vc15/lib
//Details about finding OpenCV
FIND_PACKAGE_MESSAGE_DETAILS_OpenCV:INTERNAL=[/path/to/scoop/apps/opencv/current][v4.5.5()]
As you see, system-wide environment variable OpenCV_DIR has been already set and read correctly by CLion.
Here is a simple test code, but failed to run
#include <opencv2/opencv.hpp>
int main() {
cv::Mat img = cv::imread("./test.jpg", -1);
cv::imshow("Mon image", img);
cv::waitKey(0);
return 0;
}
I also installed msys2 from winget, and from msys2 installed clang, make, MinGW-w64 GDB,cmake. Following this tutorial.
And tested through that toolchain instead of CLion bundled toolchain, it returns the same result.
OpenCV binary is from scoop.
For some reason, it has the same problem as one from homebrew. In opencv.hpp, includes headers are incorrect due to file hierarchy that opencv.hpp is inside opencv2 folder.
I changed all #include "opencv2/header.hpp" to #include "header.hpp", but it doesn't help, and vice versa.
Can't figure out the reason for hours.. Any help will be appreciated.
I'm attempting to add OpenMP to a project that is building with CMake. I'm having no problem building it on Linux with the standard CMake/OpenMP addition:
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
${OpenMP_EXE_LINKER_FLAGS}")
endif()
Unfortunately this doesn't seem to work on macOS targets. When cmake is called, the following error is given:
-- Could NOT find OpenMP_C (missing: OpenMP_C_FLAGS)
-- Could NOT find OpenMP_CXX (missing: OpenMP_CXX_FLAGS)
-- Could NOT find OpenMP (missing: OpenMP_C_FOUND OpenMP_CXX_FOUND)
I'm using macOS High Sierra (10.13.3) along with CMake 3.11. I've installed OpenMP 5.01 via brew, 'brew install libomp'. I've found some previous posts commenting on issues regarding these three but they all seem to deal with a previous way of installing OpenMP on macOS, "brew install clang-omp".
I'm thinking this might have something to do with CMake not support this OpenMP install as I'm able to use OpenMP no problem with standard makefiles. Any information provided would be much appreciated.
I've been able to answer my own question (apologies for not figuring this out beforehand, hopefully this can help others with the same issue).
It seems that a patch has been submitted to CMake to allow it to properly create buildsystems with the new OpenMP install: https://gitlab.kitware.com/cmake/cmake/merge_requests/1812
For others seeing this in the future, update to CMake 3.12 if it has been released at the time of reading.
I had the same problem and it took one complete day to find the solution. I am using Mac-Sierra 10.13.4. I want to use Opencv3 (I think the same problem also appears for opencv2) and openMP. I was actually using Clion as the IDE (CLion uses cmake to configure the project unlike other IDE), so I have to write the CMakeLists.txt file.
There was a conflict of using gcc as the compiler for openCV and openMP. If you use gcc as the compiler then it gives error for opencv as :
imwrite() on OS X error: Undefined symbols
You need to specifically use llvm compiler on OS X to resolve this issue. Following, I am giving the correct code for using OpenCV and OpenMP on Mac-Sierra:
cmake_minimum_required(VERSION 3.10)
project(MyOpenCVTest)
set(CMAKE_CXX_STANDARD 11)
add_executable(MyOpenCVTest main.cpp)
# set("OpenCV_DIR" "/modules/opencv/3.4.1/share/OpenCV/")
set(CMAKE_PREFIX_PATH "/usr/local/Cellar/opencv#3/")
set(OpenCV_INCLUDE_DIRS "/usr/local/Cellar/opencv#3/include/")
set(OpenCV_LIBS "/usr/local/Cellar/opencv#3/lib/")
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV library status:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
if(UNIX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=gnu++0x")
endif()
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/6.0.0/bin/clang")
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/6.0.0/bin/clang++")
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/6.0.0/lib")
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/6.0.0/include")
OPTION (USE_OpenMP "Use OpenMP to enamble <omp.h>" ON)
# Find OpenMP
if(APPLE AND USE_OpenMP)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(OpenMP_C "${CMAKE_C_COMPILER}")
set(OpenMP_C_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_C_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_C_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_C_LIB_NAMES})
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(OpenMP_CXX "${CMAKE_CXX_COMPILER}")
set(OpenMP_CXX_FLAGS "-fopenmp=libomp -Wno-unused-command-line-argument")
set(OpenMP_CXX_LIB_NAMES "libomp" "libgomp" "libiomp5")
set(OpenMP_libomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libgomp_LIBRARY ${OpenMP_CXX_LIB_NAMES})
set(OpenMP_libiomp5_LIBRARY ${OpenMP_CXX_LIB_NAMES})
endif()
endif()
if(USE_OpenMP)
find_package(OpenMP REQUIRED)
endif(USE_OpenMP)
if (OPENMP_FOUND)
include_directories("${OPENMP_INCLUDES}")
link_directories("${OPENMP_LIBRARIES}")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
# set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif(OPENMP_FOUND)
include_directories( ${OpenCV_INCLUDE_DIRS} )
target_link_libraries( MyOpenCVTest ${OpenCV_LIBS})
TARGET_LINK_LIBRARIES(MyOpenCVTest opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs)
You might want to set e.g. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread") such that the linker automatically detects the appropriate pthread library
Do
brew reinstall llvm
to install llvm compiler.
Please note that, you can't use gcc compiler on Mac-Sierra for your project which needs openMP and also openCV. You need to use llvm compiler.
Verify the correct location of llvm and openCV installation directory.
My high level goal is to install the BGSlibrary which requires boost for python on Windows 10 using Visual Studio 2017. I compiled opencv and boost (1.64.0) from source using cmake 3.9.0. During cmake for BGSLIBRARY I get
$ cmake -DBGS_PYTHON_SUPPORT=ON -DBOOST_ROOT="C:/Program Files/boost_1_64_0/" ..
-- BGSLIBRARY WITH PYTHON SUPPORT: ON
-- OpenCV library status:
-- version: 3.3.0
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.9/ Modules/FindBoost.cmake:1877 (message):
Unable to find the requested Boost libraries.
Boost version: 1.64.0
Boost include path: C:/Program Files/boost_1_64_0
Could not find the following Boost libraries:
boost_python
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the
directory containing Boost libraries or BOOST_ROOT to the location of
Boost.
Call Stack (most recent call first):
CMakeLists.txt:75 (find_package)
I've seen lots of questions on the cmake findboost module. Okay lets start from here.
I downloaded and extract boost 1.64.0 and placed it here
I ran bootstrap.bat and .b2 to generate the build boost
C:\Program Files\boost_1_64_0>b2 toolset=msvc-14.1 --with-python --user-config=user-config.jam
with a user config
import toolset : using ;
using msvc : 14.1 ;
using python
: 2.7 # Version
: C:\\Python27\\python.exe # Interpreter
: C:\\Python27\\include # inc dir
: C:\\Python27\\libs # link libs
: # conditions
;
I can see python source here
and can confirm that from within the Visual Studio 2017 command prompt I build boost with python support and it finds all targets successfully.
I can see a bunch of "python" .lib files here. Reading other questions suggests that is where it goes.
But I can't seem to get cmake to see it.
I've tried changing the name libboost_python to boost_python. I've tried pointing in cmake -DBOOST_ROOT, or -DBOOST_LIBRARYDIR (or non-debg, -BOOST_LIBRARYDIR). I've tried adding to the lib dir to PATH. But nothing seems to work. Is this a cmake problem, a incomplete boost installation or a problem with BGSLibrary?
EDIT
To answer #utopia, the CMakeList section in question reads
if(BGS_PYTHON_SUPPORT)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS python)
find_package(PythonLibs REQUIRED)
message(STATUS "Boost library status:")
message(STATUS " version: ${Boost_VERSION}")
message(STATUS " libraries: ${Boost_LIBRARIES}")
message(STATUS " include path: ${Boost_INCLUDE_DIRS}")
message(STATUS "Python library status:")
message(STATUS " version: ${PYTHON_VERSION}")
message(STATUS " libraries: ${PYTHON_LIBRARIES}")
message(STATUS " include path: ${PYTHON_INCLUDE_DIRS}")
endif()
Does this mean that the .lib should be literally named python.lib? With no other characters or perhaps boost_python.lib. Is it that specific?
Building Boost.Python
#utopia led me to the right solution. The .lib needs to be literally named boost_python.lib, not appended with the visual studio compiler version, boost version etc. I was able to successfully build after that, no cmake flags needed.
My project need four libraries including MPI, BOOST, VTK and SQLITE3. Since BOOST and SQLITE3 are too old, I installed new version of the two libraries and the old version are not uninstalled:
BOOST # alternative BOOST
|___include
|___lib
|
SQLITE # alternative SQLITE
|___bin
|___include
|___lib
|___share
|
Mypoject
|___src
| |___CMakeLists
| |___.cpp and .h file
|
|___CMakeLists
And I used FindSQLite3.cmake to find the alternative SQLite3:
# Look for the header file.
FIND_PATH(SQLITE3_INCLUDE_DIR sqlite3.h /export/home/hh/hh/sqlite/include)
# Look for the library.
FIND_LIBRARY(SQLITE3_LIBRARY sqlite3 /export/home/hh/hh/sqlite/lib)
# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE.
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR)
# Copy the results to the output variables.
IF(SQLITE3_FOUND)
SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY})
SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR})
ELSE(SQLITE3_FOUND)
SET(SQLITE3_LIBRARIES)
SET(SQLITE3_INCLUDE_DIRS)
ENDIF(SQLITE3_FOUND)
MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)
I am trying to link alternative libraries by following lines:
# CMake version
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
SET(VERSION 0.1)
SET(SOVERSION 1)
# searching ENV{PATH} to find mpicc and
# store the path of mpicc to MPI_INTEL_C
FIND_PATH(MPI_INTEL_C mpicc $ENV{PATH})
# searching ENV{PATH} to find mpicxx and
# store the path of mpicc to MPI_INTEL_CXX
FIND_PATH(MPI_INTEL_CXX mpicxx $ENV{PATH})
IF(MPI_INTEL_C AND MPI_INTEL_CXX)
MESSAGE(STATUS "Intel MPI compiler is used.")
# set C++ complier as mpicxx, and set C complier as mpicc
SET(CMAKE_CXX_COMPILER mpicxx)
SET(CMAKE_C_COMPILER mpicc)
ENDIF(MPI_INTEL_C AND MPI_INTEL_CXX)
find_package(VTK REQUIRED NO_MODULE)
IF(VTK_FOUND)
MESSAGE(STATUS "VTK IS USED")
include(${VTK_USE_FILE})
ELSE()
MESSAGE("VTK IS NOT FOUND")
ENDIF(VTK_FOUND)
list(APPEND CMAKE_MODULE_PATH "/export/home/hh/hh/iRoot-make/cmake")
FIND_PACKAGE(SQLite3 REQUIRED)
MESSAGE(STATUS "${SQLITE3_INCLUDE_DIRS}")
MESSAGE(STATUS "${SQLITE3_LIBRARY}")
# try to link boost--error
INCLUDE_DIRECTORIES(/export/home/hh/hh/boost/include)
LINK_DIRECTORIES(/export/home/hh/hh/boost/lib)
find_package(MPI REQUIRED)
IF(MPI_FOUND)
MESSAGE(STATUS "MPI IS USED")
INCLUDE_DIRECTORIES(${MPI_INCLUDE_PATH})
ELSE()
MESSAGE("MPI IS NOT FOUND")
ENDIF(MPI_FOUND)
aux_source_directory(. DIR_SRCS)
ADD_EXECUTABLE(test ${DIR_SRCS})
#TARGET_LINK_LIBRARIES(iRoot)
# set location of binary generated by the program,
# here PROJECT_BINARY_DIR = DIR OF build
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
# set location of lib generated by the program
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
install(TARGETS test DESTINATION bin)
CMake could not find the alternative SQLite3, and could find the old version:
-- /usr/include
-- /usr/lib64/libsqlite3.so
but the new version is located at:
/export/home/hh/hh/sqlite/include
/export/home/hh/hh/sqlite/lib/libsqlite3.so
I am very new to CMAKE, please help me, thank you in advance!
I will explain this using boost as an example. This is how I have it done in my setup.
Let's assume the newer boost version is installed in:
/export/home/hh/hh/Boost/boost-1_60/boost/include/
/export/home/hh/hh/Boost/lib
Now in CMakeLists.txt add these paths to CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH:
LIST (APPEND CMAKE_INCLUDE_PATH "/export/home/hh/hh/Boost/boost-1_60")
LIST (APPEND CMAKE_LIBRARY_PATH "/export/home/hh/hh/Boost/lib)
Then call FindPackage mentioning the minimum required version and optionally the required library components which are built into .so:
FIND_PACKAGE (Boost 1.60 COMPONENTS "program_options" "log" "system" "filesystem" "thread" "python" REQUIRED)
This should work similarly for other libraries too.
Update:
Add to CMakeLists.txt paths to your custom cmake modules, for example the path where FindSQLite3.cmake is located:
LIST (APPEND CMAKE_MODULE_PATH "${MAINFOLDER}/tools/share/cmake")
Then call: FIND_PACKAGE(SQLite3 REQUIRED)
Also remove: /export/home/hh/hh/sqlite/include and /export/home/hh/hh/sqlite/lib from FindSQLite3.cmake but have them added in a similar to boost way.
Instead of hardcoding these settings in the CMakeLists.txt you should change appropriate value in the cache (builddir/CMakeCache.txt). You can do this
manually
with cmake -D VARNAME=value .
with cmake GUI app
I'm writing a Python extension module in C++ using Boost.Python. However, I
would like to use a newer version of the Boost library than the system
installation offers. This newer version of boost is contained in
BOOST_ROOT=$HOME/opt/boost/1.55.0.
Following this guide on how
to use RPath in CMake I came up with the following CMakeLists.txt.
cmake_minimum_required(VERSION 2.8)
project("test")
set(PROJECT_DESC "Test Boost.Python")
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
add_definitions(-std=c++11 -Wall -Wextra -pedantic)
find_package(PythonInterp REQUIRED)
find_package(PythonLibsNew REQUIRED)
find_package(Boost COMPONENTS python REQUIRED)
message(STATUS "Using Boost installation in:")
message(STATUS " INCLUDE: ${Boost_INCLUDE_DIRS}")
message(STATUS " LIB: ${Boost_LIBRARIES}")
include_directories(
${PROJECT_SOURCE_DIR}
${PYTHON_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
macro(add_python_module _name _srccpp)
PYTHON_ADD_MODULE(${_name} ${_srccpp})
target_link_libraries(${_name} ${Boost_LIBRARIES})
endmacro()
add_python_module(ownership ownership.cpp)
Then I run the following commands to build the module
mkdir build; cd build
cmake -DCMAKE_INSTALL_PATH="$BOOST_ROOT/lib" ..
make
The status message after running cmake points to the right boost
installation. (The CMake boost module picks up the environment variable
$BOOST_ROOT) I.e. the CMake variable Boost_LIBARIES points to
$BOOST_ROOT/lib/libboost_python.so.
But, if I check which libraries would actually be used, the system libraries
are listed:
$ ldd ownership.so
# ...
libboost_python.so.1.53.0 => /usr/lib64/libboost_python.so.1.53.0 (0x00007f09abfc1000)
# ...
This is version 1.53, even though the status message above explicitely pointed
to 1.55.
What am I doing wrong? How can I get ldd to pick the library in
$BOOST_ROOT/lib/libboost_python.so.1.55.0?
First of all as I already mentioned in commens you don't need to use CMake RPATH-manipulations
options. Example: http://pastebin.com/UDyYbQ1d, output: standard and custom
Do you know of a way of convincing CMake otherwise even if LIBRARY_PATH is set
This issue is not related to CMake, it's compiler responsibility. Read this discussion.
Solution
You can clear LIBRARY_PATH if you set BOOST_ROOT variable explicitly. And you can check
environment variable in CMakeLists.txt to avoid this problem in future:
string(COMPARE NOTEQUAL "$ENV{LIBRARY_PATH}" "" library_path_warning)
if(library_path_warning)
message(
WARNING
"LIBRARY_PATH environment variable is not empty ($ENV{LIBRARY_PATH}) "
"This may cause dynamic linking errors!"
)
endif()