FindFoo.cmake:
# Foo_FOUND - system has Foo
# Foo_INCLUDE_DIRS - the Foo include directories
# Foo_LIBRARIES - link these to use Foo
# Foo_VERSION
# Foo_DEFINITIONS - compiler switches required for using Foo
find_package(PkgConfig)
pkg_check_modules(PC_Foo QUIET Foo)
find_path(Foo_INCLUDE_DIR Foo/Foo.h
PATHS ${PC_Foo_INCLUDEDIR} ${PC_Foo_INCLUDE_DIRS}
)
find_library(Foo_LIBRARY Foo
PATHS ${PC_Foo_LIBDIR} ${PC_Foo_LIBRARY_DIRS}
)
set(Foo_VERSION ${PC_Foo_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo
FOUND_VAR Foo_FOUND
REQUIRED_VARS
Foo_LIBRARY
Foo_INCLUDE_DIR
VERSION_VAR Foo_VERSION
)
if(Foo_FOUND)
set(Foo_LIBRARIES ${Foo_LIBRARY})
set(Foo_INCLUDE_DIRS ${Foo_INCLUDE_DIR})
set(Foo_DEFINITIONS ${PC_Foo_CFLAGS_OTHER})
endif()
mark_as_advanced(
Foo_INCLUDE_DIR
Foo_LIBRARY
)
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)
PROJECT(sandbox)
set(CMAKE_AUTOMOC ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
FIND_PACKAGE(Qt5Core REQUIRED)
find_package(Foo REQUIRED)
include_directories(${Foo_INCLUDE_DIRS})
SET(sandbox_SOURCES main.cpp)
ADD_EXECUTABLE(sandbox ${sandbox_SOURCES})
QT5_USE_MODULES(sandbox Core)
TARGET_LINK_LIBRARIES(sandbox ${Foo_LIBRARIES})
#include <Bar1.h> works in my program whereas #include <Foo/Bar1.h> doesn't. and the real problem is that i can't build my program because Bar1.h contains #include <Foo/Bar2.h> and:
...Foo/Bar1.h: fatal error: Foo/Bar2.h: No such file or directory
compilation terminated.
CMake 3.5.1
looks like the problem was CMake cache. i deleted everything from the CMakeFiles directory and then CMake couldn't configure the project:
Could NOT find Foo (missing: Foo_INCLUDE_DIR)
i had to add PATH_SUFFIXES to find_path(), and all the problems are gone.
Related
I built Open3D from source into a /home/user/custom_location/Open3D/build
I have a project with a dependency on Open3D and a CMakeLists.txt like this:
cmake_minimum_required(VERSION 3.12)
project(graph_filter)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)
# Pybind11
find_package(pybind11 REQUIRED)
# OpenMP
find_package(OpenMP REQUIRED)
# Eigen
find_package(Eigen3 3.3 REQUIRED NO_MODULE)
# Open3D
list(APPEND CMAKE_INSTALL_PREFIX "~/libraries/")
find_package(Open3D HINTS ${CMAKE_INSTALL_PREFIX}/lib/CMake)
list(APPEND Open3D_LIBRARIES dl)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Open3D_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${Open3D_EXE_LINKER_FLAGS}")
include_directories(${Open3D_INCLUDE_DIRS})
link_directories(${Open3D_LIBRARY_DIRS})
pybind11_add_module(
graph_filter
wrapper.cpp
)
target_link_libraries(graph_filter PRIVATE ${Open3D_LIBRARIES} Eigen3::Eigen OpenMP::OpenMP_CXX)
How can I link it? When I run
INSTALL_DIR=/home/user/custom_location/Open3D/build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}```
I am getting:
Could NOT find Open3D (missing: Open3D_DIR)
fatal error: Open3D/Open3D.h: No such file or directory
2 | #include <Open3D/Open3D.h>
What is more confusing is the contents of Open3D/build folder after building from source.
I just want to resolve this dependency on Open3D. Thanks for any help!!!
I have downloaded the HDFql library and put the whole lot in /usr/local/ in my linux system. I now wish to use this library in a ROS application, so I have tried to link it in my CMakeList, which looks as following:
cmake_minimum_required(VERSION 3.2)
project(data_generator)
add_compile_options(-std=c++11)
set(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
set(HDFQL_ROOT "/usr/local/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
find_library(HDFQL_LIB HDFql)
if (HDFQL_LIB)
message("Library(HDFQL_LIB) found in ${HDFQL_LIB}")
else()
message(FATAL_ERROR "Library (HDFQL_LIB) not found")
endif()
cs_add_executable(
${PROJECT_NAME}
src/main.cpp
src/data_create.cpp
src/event_definitions.cpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBRARIES}
${HDFQL_LIB}
)
# CMake Indexing
FILE(GLOB_RECURSE LibFiles "include/*")
add_custom_target(headers SOURCES ${LibFiles})
cs_install()
cs_export()
When I build this, it works fine and outputs the message:
Library(HDFQL_LIB) found in /usr/local/hdfql-2.1.0/lib/libHDFql.so
with the following in my main.cpp file:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
the output is: HDFql version: 2.1.0.
However, as soon as I try to actually use functions of the library - for example:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
HDFql::execute("CREATE FILE /home/user/test.h5");
I get the error:
main.cpp:(.text+0x1858): undefined reference to `HDFql::execute(char const*)'
This suggests to me that while CMake has no issue with the includes, it is having trouble linking the actual library (ie including the libHDFql.a/libHDFql.so files). Can anyone tell me what I'm doing wrong here?
Many thanks!
The problem was that I needed to include the library /usr/local/hdfql-2.1.0/wrapper/cpp/libHDFql.so, where I was using /usr/local/hdfql-2.1.0/lib/libHDFql.so. It's pretty maddening, since the reference manual doesn't make any mention of this and I spent way too long figuring this out. Ohwell, I hope this helps anyone else with this problem.
For reference, here is a minimal catkin-style CMakeLists that will work:
cmake_minimum_required(VERSION 3.2)
project(project_name)
add_compile_options(-std=c++11)
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
set(HDFQL_ROOT "path/to/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
cs_add_executable(
${PROJECT_NAME}
# your source file 1
# your source file 2
# ...
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(
${PROJECT_NAME}
${OpenCV_LIBRARIES}
)
target_link_libraries(
${PROJECT_NAME}
"${HDFQL_ROOT}/wrapper/cpp/libHDFql.so"
)
Of course the absolute paths aren't very pretty, the alternative is to add /usr/local/hdfql-2.1.0/lib to the environment variable CMAKE_PREFIX_PATH (eg export CMAKE_PREFIX_PATH="/usr/local/hdfql-2.1.0/lib:$CMAKE_PREFIX_PATH").
I am new to C++ and have just started to use Cmake for linking the libraries to my project. I need to use a library:
https://github.com/Gnimuc/FastPD
Fortunately, I managed to build the library using Cmake (in my build there is no *.lib file at all), but I don't know how to link it to my project. I mean that I don't know how to add it to my cmakelists.txt :
(PS. I'm also using two other libraries ITK and VTK; but I can't link the above mentioned library to my project or main.cpp.)
################################################
cmake_minimum_required(VERSION 2.8)
project(My_project)
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
if (ITKVtkGlue_LOADED)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
else()
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
set(Glue ItkVtkGlue)
endif()
add_executable(My_project MACOSX_BUNDLE main.cpp)
target_link_libraries(My_project
${Glue} ${VTK_LIBRARIES} ${ITK_LIBRARIES})
################################################
Thanks in advance for your helps,
Assuming you installed the library and its header files, you can then search for the header files using find_path, and add the found path to the include directories. Then you can search for the library by using find_library, and add the library with the target_link_libraries command.
I tried both shared and static types for creation of the library. In the case of shared, no *.lib file was created, and in the case of static, my project couldn't link to the library. Therefore, in my project's CmakeLists.txt, I decided to add all the *.cpp and headers as libraries and then link them together (as I didn't know the dependency among them!!!), and finally, I linked them to my project. Perhaps it does not make sense but it works; hope it helps you:
CmakeLists.txt
##############################################
cmake_minimum_required(VERSION 2.6)
set(PROJ_NAME PROJECT46)
PROJECT(${PROJ_NAME})
# Prevent compilation in-source
if( ${CMAKE_BINARY_DIR} STREQUAL ${PROJECT_SOURCE_DIR} )
Message( " " )
Message( FATAL_ERROR "Source and build directories are the same.
Create an empty build directory,
change into it and re-invoke cmake")
endif()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support.
Please use a different C++ compiler.")
endif()
##############################################
## External libraries
##############################################
list( APPEND CMAKE_MODULE_PATH
${PROJECT_SOURCE_DIR}/cmake
)
# Blitz
find_package( Blitz++ REQUIRED )
list( APPEND PROJ_INCLUDE_DIRS
${Blitz++_INCLUDE_DIR}
)
list( APPEND
PROJ_LIB
${Blitz++_LIBRARIES}
)
# ITK and VTK
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
if (ITKVtkGlue_LOADED)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
else()
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
set(Glue ItkVtkGlue)
endif()
##############################################
# FASTPD
add_library(FASTPD Fast_PD.cpp Fast_PD.h common.h block.h)
add_library(GRAPH graph.h graph.cpp)
add_library(linked LinkedBlockList.h LinkedBlockList.cpp)
add_library(MAXFLOW maxflow.cpp)
include_directories(${PROJ_INCLUDE_DIRS})
add_executable(${PROJ_NAME} main.cpp)
target_link_libraries(linked MAXFLOW)
target_link_libraries(GRAPH linked)
target_link_libraries(FASTPD GRAPH)
target_link_libraries(${PROJ_NAME} FASTPD)
target_link_libraries(${PROJ_NAME}
${PROJ_LIB} ${Glue} ${VTK_LIBRARIES} ${ITK_LIBRARIES}
)
I have a C++ header file which has the following lines:
#include <QXmlSimpleReader>
#include <QXmlDefaultHandler>
and my cmake has the following lines:
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Xml REQUIRED)
When running CMake I get the following error message:
QXmlSimpleReader: No such file or directory
#include <QXmlSimpleReader>
What am I doing wrong?
For some reason it do not adds to project include dirs.
Add this one to your cmake
INCLUDE_DIRECTORIES( ${Qt5Xml_INCLUDE_DIRS} )
I guess you forgot to link against Qt5xml. A working example from the documentation for cmake 2.8.11 and later, modified to link against Qt5Xml:
cmake_minimum_required(VERSION 2.8.11)
project(testproject)
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Xml)
# Tell CMake to create the helloworld executable
add_executable(helloworld WIN32 main.cpp)
# Use the Widgets module from Qt 5.
target_link_libraries(helloworld Qt5::Xml)
So I've been trying to get my programs with QPrinter to work compile with cmake+mingw+qt5.2 but I'm having issues: the following test program doesn't compile because it cant find QPrinter which should be part of QtCore
#include <QPrinter>
#include <QApplication>
#include <windows.h>
int main()
{
QApplication a( argc, argv );
return 0;
} // end
this is my cmake file
SET(CMAKE_C_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/gcc.exe)
SET(CMAKE_CXX_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/g++.exe)
cmake_minimum_required(VERSION 2.8)
PROJECT (test_prog)
add_definitions(-std=c++11)
SET( test_prog_SRCS test.cpp)
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Widgets finds its own dependencies.
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
include_directories(
${Qt5Widgets_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Core_INCLUDE_DIRS}
)
add_executable(test_prog WIN32 ${test_prog_SRCS})
target_link_libraries(test_prog ${Qt5Widgets_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} )
The Error is:
test.cpp:1:20: fatal error: QPrinter: No such file or directory
#include <QPrinter>
Does anyone know the right incantations to get this to work?
With CMake 2.8.11:
SET(CMAKE_C_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/gcc.exe)
SET(CMAKE_CXX_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/g++.exe)
cmake_minimum_required(VERSION 2.8.11)
PROJECT (test_prog)
add_definitions(-std=c++11)
SET( test_prog_SRCS test.cpp)
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5PrintSupport REQUIRED)
add_executable(test_prog WIN32 ${test_prog_SRCS})
target_link_libraries(test_prog Qt5::PrintSupport)