How could I replace a find_package of CMakeList by its installation directory? - cmake

I need to install SFML by sources but I can't run cmake because a package is not installed (xcb-image)
I installed this packages by sources, but how can I tell CMake that this package is installed, and that it needs to look at a special directory?
if(NOT SFML_OPENGL_ES)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
if(SFML_OS_LINUX OR SFML_OS_FREEBSD)
find_package(XCB COMPONENTS xlib_xcb image randr REQUIRED)
if(NOT LIBXCB_FOUND)
message(FATAL_ERROR "Xcb library not found")
endif()
include_directories(${LIBXCB_INCLUDE_DIRS})
endif()
endif()
I don't have root access.

Try adding your xcb /include and /lib directory to your CMakeLists, by adding the following lines :
INCLUDE_DIRECTORIES(/path/to/your/xcb/include)
LINK_DIRECTORIES(/path/to/your/xcb/lib)
Otherwise, if that didn't work and you have a cmake file for cxb (sth like xcb.cmake), Create a folder named cmake/Modules/ under your project root, add xcb.cmake under that folder, and in the root CMakeLists.txt, include the following code:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
For a better understanding, take a look at CMake:How To Find Libraries
Hope that helps !

Related

How to fix CMakeList for project build with SDL_image?

I try to build project with SDL2_image, but have such error:
CMake Error at CMakeLists.txt:9 (find_package):
By not providing "FindSDL2_image.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"SDL2_image", but CMake did not find one.
Could not find a package configuration file provided by "SDL2_image" with
any of the following names:
SDL2_imageConfig.cmake
sdl2_image-config.cmake
Add the installation prefix of "SDL2_image" to CMAKE_PREFIX_PATH or set
"SDL2_image_DIR" to a directory containing one of the above files. If
"SDL2_image" provides a separate development package or SDK, be sure it has
been installed.
If compile project with CTRL+F5, it works fine.
I work with ubuntu 20.04, Clion, also add FindSDL2_image.cmake to cmake/Modules. Can someone help with it?
My CMakeList.txt:
cmake_minimum_required(VERSION 3.17)
project(POng2)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_INCLUDE_DIR}
${SDL2_IMAGE_INCLUDE_DIR}
${SDL2_TTF_INCLUDE_DIR})
add_executable(POng2 main.cpp Game.h Game.cpp Paddle.h Paddle.cpp Entity.h Entity.cpp Ball.h
Ball.cpp Board.h Board.cpp Score.h Score.cpp)
target_link_libraries(POng2 ${SDL2_LIBRARY}
${SDL2_IMAGE_LIBRARIES}
${SDL2_TTF_LIBRARIES})

Create CMake/CPack <Library>Config.cmake for shared library

I have the simplest possible c-library which builds and is packed using the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project (libfoo C)
add_library(foo SHARED impl.c)
target_link_libraries(foo)
install(TARGETS foo LIBRARY DESTINATION lib/)
install(FILES public_header.h DESTINATION include/libfoo)
set(CPACK_GENERATOR "TGZ")
include(CPack)
Working example is located here: https://github.com/bjarkef/cmake-simple/tree/master/libfoo
I execute mkdir -p build; (cd build/; cmake ../; make all package;) to build a .tar.gz package with the compiled shared library along with its public header file. This is all working fine.
Now I wish to modify the CMakeLists.txt to create the FooConfig.cmake and FooConfigVersion.cmake files needed for CMake find_package in a different project to find the foo library. How do I do this?
I have discovered I should used the CMakePackageConfigHelpers: configure_package_config_file and write_basic_package_version_file, and I should create a FooLibraryConfig.cmake.in file. However I cannot figure out how to put it all together.
Note that it is important the the resulting .cmake files only contains relative paths.
I have cmake module included in the top level CmakeList.txt:
# Generate and install package config files
include(PackageConfigInstall)
Within the generic PackageConfigInstall.cmake file, the config files are created from the cmake.in files, and installed. This module can be reused for other packages.
include(CMakePackageConfigHelpers)
# Generate package config cmake files
set(${PACKAGE_NAME}_LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}${PACKAGE_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
configure_package_config_file(${PACKAGE_NAME}-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DIR}/${PACKAGE_NAME}
PATH_VARS LIB_INSTALL_DIR INCLUDE_INSTALL_DIR APP_INCLUDE_INSTALL_DIR )
configure_file(${PACKAGE_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake #ONLY)
# Install package config cmake files
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}-config-version.cmake
DESTINATION
${CMAKE_INSTALL_DIR}/${PACKAGE_NAME}
COMPONENT
devel
)
You'll need a package file for your library, such as your_lib-config.cmake.in, which will become your_lib-config.cmake. This will contain the include and library variables that can be used.
get_filename_component(YOUR_LIB_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# flag required by CMakePackageConfigHelpers
#PACKAGE_INIT#
set_and_check(YOUR_LIB_INCLUDE_DIR #PACKAGE_YOUR_LIB_INCLUDE_INSTALL_DIR#/hal)
set_and_check(YOUR_LIB_LIBRARY #PACKAGE_LIB_INSTALL_DIR#/#CMAKE_STATIC_LIBRARY_PREFIX##PROJECT_NAME_LIB##CMAKE_STATIC_LIBRARY_SUFFIX#)
set_and_check(YOUR_LIB_LIBRARIES #PACKAGE_LIB_INSTALL_DIR#/#CMAKE_STATIC_LIBRARY_PREFIX##PROJECT_NAME_LIB##CMAKE_STATIC_LIBRARY_SUFFIX#)
You'll also want a config-version.cmake.in file like this:
set(PACKAGE_VERSION #PACKAGE_VERSION#)
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
There's quite a bit to the packaging scripts to get it all to work just right. I went through a lot of trial and error to finally get something that works on different targets (both linux server and embedded target). I might have left something out, so please just comment and I'll update answer.

Cmakelist working outside of Clion

I've wanted to use Clion for awhile but I've always had trouble with Cmake. Armed with Cygwin, I've almost gotten this stupid thing to work.
The issue is while I can compile a cmake file from within a cygwin terminal, in Clion I am told it cannot find the library I want.
Error:A required package was not found
The cmakelist.txt file
cmake_minimum_required(VERSION 3.3)
project(Test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(PKG_CONFIG_PATH /usr/lib/pkgconfig)
set(PKG_CONFIG_EXECUTABLE /usr/bin/pkg-config.exe)
set(SOURCE_FILES main.cpp)
add_executable(Test ${SOURCE_FILES})
INCLUDE(FindPkgConfig)
pkg_check_modules(SDL2 REQUIRED "sdl2")
MESSAGE(STATUS "SDL library: " ${SDL2_LDFLAGS})
TARGET_LINK_LIBRARIES(Test ${SDL2_LDFLAGS})
I have no idea if setting the variables PKG_CONFIG_PATH and others work, but they successfully build a makefile for my use in cygwin that builds correctly.
I've deleted the cache, remade the project and everything. It just refuses to work in Clion
If I understood correctly, your cmake config is unable to find SDL library. I found it better to use find_package command instead of pkg_check_modules.
In order to find_package(SDL2) to work, there must be FindSDL2.cmake module in directory, specified by CMAKE_MODULE_PATH variable (usually, it is cmake/Modules directory inside your source tree).
FindSDL2.cmake is not a part of CMake, but you can find one online easily (check my own modules, for example: https://github.com/dragn/cmake-modules).
Refer to this doc for details: https://cmake.org/Wiki/CMake:How_To_Find_Libraries.
Put FindSDL2.cmake to cmake/Modules directory and add this to your CMakeLists.txt:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/Modules)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})
...
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARY})
NOTE: Sadly, it appears that Leonardo has not succeeded in finding volunteers for maintaining FindSDL2.cmake in SDL community: https://cmake.org/Bug/view.php?id=14826.

Issues Configuring CLion, Cmake, and SFML

I am currently trying to configure my Cmake file to include the SFML libraries.
My CMakeLists.txt. I'm using OS X Yosemite if that matter at all.
cmake_minimum_required(VERSION 2.8.4)
project(SFMLTest)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=lib++")
set(SOURCE_FILES main.cpp)
add_executable(SFMLTest ${SOURCE_FILES})
#Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/Users/Home/SFML-2.2-osx-clang-universal/cmake/Modules" ${CMAKE_MODULE_PATH})
find_package(SFML 2.2 REQUIRED system window graphics network audio)
if (SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${main.cpp} ${SFML_Libraries})
endif()
and the error I am currently getting is
Error:By not providing "FindSFML.cmake" in CMAKE_MODULE_PATH this project has asked
CMake to find a package configuration file provided by "SFML", but CMake did notfind one.
Could not find a package configuration file provided by "SFML" (requested version 2.2)
with any of the following names:
SFMLConfig.cmake sfml-config.cmake
Add the installation prefix of "SFML" to CMAKE_PREFIX_PATH or
set "SFML_DIR"to a directory containing one of the above files.
If "SFML" provides a separate development package or SDK, be sure it has been installed.
my FindSFML.cmake is located at
/Users/Home/SFML-2.2-osx-clang-universal/cmake/Modules
Your question says the full path to the find module is
/Users/Home/SFML-2.2-osx-clang-universal/cmake/Modules/FindSFML.cmake
But you're adding ${CMAKE_SOURCE_DIR}/Users/Home/SFML-2.2-osx-clang-universal/cmake/Modules to your CMAKE_MODULE_PATH. ${CMAKE_SOURCE_DIR} is the absolute path to the directory containing the top-level CMakeLists.txt file. If you know the absolute path to the module file you want to include, you should most certainly not prefix it with the source tree path. Just change the line to this:
set(CMAKE_MODULE_PATH "/Users/Home/SFML-2.2-osx-clang-universal/cmake/Modules" ${CMAKE_MODULE_PATH})
Also note that since you have REQUIRED specified among the arguments to find_package(), CMake will terminate with an error if the package cannot be found. Having if(SFML_FOUND) is therefore pointless.
This solution is perfect: https://oxymeos.shost.ca/article.php?about=work_with_the_SFML_in_CLion. I recommend it! It worked for me
You create a folder named "cmake_modules" at the root of the project and you place in this folder the "FindSFML.cmake" file (on Windows and Mac OS X: "[Your_SFML Location]/cmake/Modules/FindSFML.cmake", and on Linux: "[Your_SFML_location]/share/SFML/cmake/Modules/FindSFML.cmake".
The CMake configuration file (CMakeLists.txt) is then presented in this form:
cmake_minimum_required(VERSION 3.7)
project([your_project])
# Define the source and the executable
set(EXECUTABLE_NAME "[name_executable]")
add_executable(${EXECUTABLE_NAME} [project_files])
# Detect and add SFML
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
find_package(SFML 2 REQUIRED system window graphics network audio)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
endif()

cpack component level install

For the example CMakeLists.txt attached to CMake wiki. I also added below what is the actual make command to create just the component based TGZ. I am confused and not seeing any help in the documents.
CMakeLists.txt
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
project(MyLib)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "Install path prefix prepended on to install directories." FORCE)
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CPACK_PACKAGE_NAME "MyLib")
set(CPACK_PACKAGE_VENDOR "CMake.org")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyLib - CPack Component Installation Example")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example")
add_library(mylib mylib.cpp)
add_executable(mylibapp mylibapp.cpp)
target_link_libraries(mylibapp mylib)
install(TARGETS mylib
ARCHIVE
DESTINATION lib
COMPONENT libraries)
install(TARGETS mylibapp
RUNTIME
DESTINATION bin
COMPONENT applications)
install(FILES mylib.h
DESTINATION include
COMPONENT headers)
set(CPACK_COMPONENTS_ALL applications libraries headers)
set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "MyLib Application")
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries")
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ Headers")
set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION
"An extremely useful application that makes use of MyLib")
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION
"Static libraries used to build programs with MyLib")
set(CPACK_COMPONENT_HEADERS_DESCRIPTION
"C/C++ header files for use with MyLib")
set(CPACK_GENERATOR "TGZ")
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(CPACK_SET_DESTDIR ON)
set(CPACK_PACKAGE_CONTACT "jhf")
# This must always be last!
include(CPack)
I have a similar CMakeLists.txt and when I do make package, I end up getting all my binaries and libraries in the TGZ. What should the make package command be if I need just a TGZ with application component from the above CMakeLists.txt?
It is simple.
Just set the CMAKE variable CPACK_COMPONENTS_ALL to the list of components you want to appear in the installation:
SET(CPACK_COMPONENTS_ALL applications) #only pack "applications" component
Take a look at CPackComponent.
I have exactly the same question with you.
I'm a beginner to cmake, and today I've try a whole day on this, just now I noticed a cmake module named CPackComponent which begins appeared in cmake 2.8.5 standard modules.
For now, I haven't made sure whether it is the reason yet. But the variables in the documents listed by you can be found in this module.
cmake 2.8.5 is the earliest version contained CPackComponent in its standard modules.
Have a check at http://www.cmake.org/cmake/help/v2.8.5/cmake.html#module:CPackComponent
And cmake 2.8.8 is the earliest version listed the variables you want. e.g. CPACK_COMPONENTS_ALL
Over here http://www.cmake.org/cmake/help/v2.8.8/cmake.html#module:CPackComponent
I'm sorry I'm a newbie too, could not help you any more.