Difference between revisions of "CMake and FIND PACKAGE"

From Wiki for iCub and Friends
Jump to: navigation, search
(On CMake and FIND_PACKAGE)
 
(16 intermediate revisions by 2 users not shown)
Line 1: Line 1:
One of the most important features of CMake is that it allows to configure your project to include/link additional packages (libraries). To do this you have to tell CMake you want to use an additional package, you do this with the FIND_PACKAGE macro. I found FIND_PACKAGE a bit confusing so I try to explain here how it works and how we have been using it on YARP.
+
CMake allows you to configure your project to use additional packages by calling the FIND_PACKAGE macro. Since this macro can be confusing I try to explain here how it works and how we have been using it on YARP.
  
Note: I here explain the functionalities of FIND_PACKAGE that are used in YARP, go to http://www.cmake.org/HTML/Documentation.html for a more complete explanation.
+
Note: I here explain the functionalities of FIND_PACKAGE that are used in YARP, go to http://www.cmake.org for a more complete explanation.
  
FIND_PACKAGE(<name>) asks CMake to find and load settings from the external projects/packages called <name>. This works in a few steps:
 
  
- CMake searches the directories listed in CMAKE_MODULE_PATH for a file called Find<name>.cmake. If found, this macro is executed and it is responsible for finding the package (examples of similar macro are: FindACE.cmake, FindBoost.cmake, FindOpenCV.cmake that are located in your $YARP_ROOT/conf directories). "Find" macros define variables which allow you to check if the package has been found and use it in your project. Unfortunately different macros behave differently so you have to check the code to find out the exact names of those variables. A good idea would be to define:
+
FIND_PACKAGE(<name>) asks CMake to find and load settings from the external package <name>. This works as follows:
  
<name>_FOUND
+
* CMake searches the directories listed in CMAKE_MODULE_PATH for a file called Find<name>.cmake. If found, this macro is executed and it is responsible for finding the package (examples of similar macro are: FindACE.cmake, FindBoost.cmake, FindOpenCV.cmake that are located in your $YARP_ROOT/conf directory). "Find" macros define variables which allow you to check if the package has been found and use it in your project. Unfortunately different macros behave differently so you have to check the code to find out the exact names of those variables (usually this is explained in the comments at the beginning of the file). For example, a Find macro might define:
<name>_INCLUDE_DIR
 
<name>_LIBRARIES
 
<name>_LINK_DIRECTORIES
 
  
For example, suppose you want to include the ACE package in a new project:
+
  <name>_FOUND  // true iff the package was found
 +
  <name>_INCLUDE_DIR  // a list of directories containing the package's include files
 +
  <name>_LIBRARIES    // a list of directories containing the package's libraries
 +
  <name>_LINK_DIRECTORIES  // the list of the package's libraries
  
#find ACE
+
Now suppose you want to create a new project which uses OpenCV. A possible CMakeLists.txt is:
FIND_PACKAGE(OpenCV)
 
  
# searches for all .cpp and .h files in the current directory and add them  
+
  #### assume FindOpenCV.cmake is in one of the CMAKE_MODULE_PATH folders.
# to the current project
+
  FIND_PACKAGE(OpenCV)
FILE(GLOB folder_source *.cpp)
+
 
FILE(GLOB folder_header *.h)
+
  # searches for all .cpp and .h files in the current directory and add them  
SOURCE_GROUP("Source Files" FILES ${folder_source})
+
  # to the current project
SOURCE_GROUP("Header Files" FILES ${folder_header})
+
  FILE(GLOB folder_source *.cpp)
 +
  FILE(GLOB folder_header *.h)
 +
  SOURCE_GROUP("Source Files" FILES ${folder_source})
 +
  SOURCE_GROUP("Header Files" FILES ${folder_header})
 +
 
 +
  # create the project
 +
  ADD_EXECUTABLE(your_project ${folder_source} ${folder_header})
 +
   
 +
  # add include directories
 +
  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 +
  INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
 +
   
 +
  # link opencv libraries
 +
  TARGET_LINK_LIBRARIES(your_project ${OPENCV_LIBRARIES})
  
# create the project
+
* If CMake does not find any Find<name>.cmake file in the directories listed in MAKE_MODULE_PATH, it assumes the package was built with CMake and has a "<name>Config.cmake" file associated. CMake expects the user to specify the location of this file by filling a cache entry called <name>_DIR (this entry is created by CMake automatically). If the file is found, it is processed to load the settings of the package (an error or a warning is displayed otherwise).
ADD_EXECUTABLE(your_project ${folder_source} ${folder_header})
 
  
# add include directories
+
For example, when YARP is built CMake creates a file called YARPConfig.cmake in the "build" directory that is selected by the user. When users want to create a project which uses YARP they just have to call FIND_PACKAGE(YARP) and select the approprite YARP_DIR. For example:
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 
INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
 
  
# link opencv libraries
+
  SET(YARP_DIR "c:/yarp/build" CACHE LOCATION "where was yarp built?")
TARGET_LINK_LIBRARIES(your_project ${OPENCV_LIBRARIES})
+
 
 +
  or, if they YARP_ROOT is an environment variable pointing to your YARP build:
 +
 
 +
  SET(YARP_DIR "$ENV{YARP_ROOT}" CACHE LOCATION "where was yarp built?")
 +
 
 +
  FIND_PACKAGE(YARP)
  
- If CMake does not find any Find<name>.cmake file in the directories listed in CMAKE_MODULE_PATH, it assumes the package was built with CMake and has a
+
The macro FIND_PACKAGE automatically searches YARP_DIR for the file YARPConfig.CMake and executes it. YARPConfig.cmake creates the entries YARP_LIBRARIES, YARP_INCLUDE_DIRS and YARP_DEFINES. To use these in a project, do:
"<name>Config.cmake" file associated. CMake expects the user to specify the location
 
of this file by filling a cache entry called <name>_DIR (this entry is created by
 
CMake automatically). If the file is found it is processed to load the settings of the package.
 
  
For example, when YARP is built CMake creates a file called YARPConfig.cmake in the "build" directory selected by the user. When users want to create a project which uses YARP they have to do something like:
+
  INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
 +
  ADD_DEFINITIONS(${YARP_DEFINES}) # optional
 +
  ...
 +
  TARGET_LINK_LIBRARIES(your_target_name ${YARP_LIBRARIES})
  
SET(YARP_DIR "c:/yarp/build" CACHE LOCATION "where was yarp built?")
 
  
or, if they defined YARP_ROOT:
+
----
  
SET(YARP_DIR "$ENV{YARP_ROOT}" CACHE LOCATION "where was yarp built?")
 
  
FIND_PACKAGE(YARP)
+
To recap, as a final example here is a CMakeLists.txt which creates a new project "foo" which uses YARP and OpenCV.  You'll need to have the environment variable YARP_DIR set to where YARP was built:
  
The macro FIND_PACKAGE automatically searches YARP_DIR for the file YARPConfig.CMake and executes it. YARPConfig.cmake creates the entries YARP_LIBRARIES, YARP_INCLUDES and YARP_DEFINES which are already processed so that projects added later will use them:
+
  CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
 
+
 
LINK_LIBRARIES(${YARP_LIBRARIES})
+
  # execute YarpConfig.cmake
INCLUDE_DIRECTORIES(${YARP_INCLUDES})
+
  FIND_PACKAGE(YARP)
ADD_DEFINITIONS(${YARP_DEFINES})
+
 
 
+
  # pick up YARP find scripts
Note: LINK_LIBRARIES is an obsolete CMake command, in the future should be replaced by TARGET_LINK_LIBRARIES
+
  SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${YARP_MODULE_PATH})
 
+
 
YARPConfig.cmake also append ${YARP_DIR}/conf to CMAKE_MODULE_PATH so that later all Find*.cmake provided with YARP can be accessed by CMake by calling FIND_PACKAGE command.
+
  # now FindOpenCV.cmake is in CMAKE_MODULE_PATH
 +
  FIND_PACKAGE(OpenCV)
 +
 
 +
  # searches for all .cpp and .h files in the current directory and add them  
 +
  # to the current project
 +
  FILE(GLOB folder_source *.cpp)
 +
  FILE(GLOB folder_header *.h)
 +
  SOURCE_GROUP("Source Files" FILES ${folder_source})
 +
  SOURCE_GROUP("Header Files" FILES ${folder_header})
 +
 
 +
  # add the current directory in the include path
 +
  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
 +
  # add YARP include directories
 +
  INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
 +
  # add OpenCV include directories
 +
  INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
 +
   
 +
  # create the program "foo"
 +
  ADD_EXECUTABLE(foo ${folder_source} ${folder_header})
 +
   
 +
  # link opencv and YARP libraries
 +
  TARGET_LINK_LIBRARIES(foo ${OPENCV_LIBRARIES} ${YARP_LIBRARIES})

Latest revision as of 20:25, 25 May 2010

CMake allows you to configure your project to use additional packages by calling the FIND_PACKAGE macro. Since this macro can be confusing I try to explain here how it works and how we have been using it on YARP.

Note: I here explain the functionalities of FIND_PACKAGE that are used in YARP, go to http://www.cmake.org for a more complete explanation.


FIND_PACKAGE(<name>) asks CMake to find and load settings from the external package <name>. This works as follows:

  • CMake searches the directories listed in CMAKE_MODULE_PATH for a file called Find<name>.cmake. If found, this macro is executed and it is responsible for finding the package (examples of similar macro are: FindACE.cmake, FindBoost.cmake, FindOpenCV.cmake that are located in your $YARP_ROOT/conf directory). "Find" macros define variables which allow you to check if the package has been found and use it in your project. Unfortunately different macros behave differently so you have to check the code to find out the exact names of those variables (usually this is explained in the comments at the beginning of the file). For example, a Find macro might define:
  <name>_FOUND  // true iff the package was found
  <name>_INCLUDE_DIR   // a list of directories containing the package's include files
  <name>_LIBRARIES     // a list of directories containing the package's libraries
  <name>_LINK_DIRECTORIES  // the list of the package's libraries

Now suppose you want to create a new project which uses OpenCV. A possible CMakeLists.txt is:

  #### assume FindOpenCV.cmake is in one of the CMAKE_MODULE_PATH folders.
  FIND_PACKAGE(OpenCV)
  
  # searches for all .cpp and .h files in the current directory and add them 
  # to the current project
  FILE(GLOB folder_source *.cpp)
  FILE(GLOB folder_header *.h)
  SOURCE_GROUP("Source Files" FILES ${folder_source})
  SOURCE_GROUP("Header Files" FILES ${folder_header})
  
  # create the project
  ADD_EXECUTABLE(your_project ${folder_source} ${folder_header})
   
  # add include directories
  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
  INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
   
  # link opencv libraries 
  TARGET_LINK_LIBRARIES(your_project ${OPENCV_LIBRARIES})
  • If CMake does not find any Find<name>.cmake file in the directories listed in MAKE_MODULE_PATH, it assumes the package was built with CMake and has a "<name>Config.cmake" file associated. CMake expects the user to specify the location of this file by filling a cache entry called <name>_DIR (this entry is created by CMake automatically). If the file is found, it is processed to load the settings of the package (an error or a warning is displayed otherwise).

For example, when YARP is built CMake creates a file called YARPConfig.cmake in the "build" directory that is selected by the user. When users want to create a project which uses YARP they just have to call FIND_PACKAGE(YARP) and select the approprite YARP_DIR. For example:

  SET(YARP_DIR "c:/yarp/build" CACHE LOCATION "where was yarp built?")
  
  or, if they YARP_ROOT is an environment variable pointing to your YARP build:
  
  SET(YARP_DIR "$ENV{YARP_ROOT}" CACHE LOCATION "where was yarp built?")
  
  FIND_PACKAGE(YARP)

The macro FIND_PACKAGE automatically searches YARP_DIR for the file YARPConfig.CMake and executes it. YARPConfig.cmake creates the entries YARP_LIBRARIES, YARP_INCLUDE_DIRS and YARP_DEFINES. To use these in a project, do:

  INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
  ADD_DEFINITIONS(${YARP_DEFINES}) # optional
  ...
  TARGET_LINK_LIBRARIES(your_target_name ${YARP_LIBRARIES})




To recap, as a final example here is a CMakeLists.txt which creates a new project "foo" which uses YARP and OpenCV. You'll need to have the environment variable YARP_DIR set to where YARP was built:

  CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
  
  # execute YarpConfig.cmake
  FIND_PACKAGE(YARP)
  
  # pick up YARP find scripts
  SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${YARP_MODULE_PATH})
  
  # now FindOpenCV.cmake is in CMAKE_MODULE_PATH
  FIND_PACKAGE(OpenCV)
  
  # searches for all .cpp and .h files in the current directory and add them 
  # to the current project
  FILE(GLOB folder_source *.cpp)
  FILE(GLOB folder_header *.h)
  SOURCE_GROUP("Source Files" FILES ${folder_source})
  SOURCE_GROUP("Header Files" FILES ${folder_header})
  
  # add the current directory in the include path
  INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
  # add YARP include directories
  INCLUDE_DIRECTORIES(${YARP_INCLUDE_DIRS})
  # add OpenCV include directories
  INCLUDE_DIRECTORIES(${OPENCV_INCLUDE_DIR})
   
  # create the program "foo"
  ADD_EXECUTABLE(foo ${folder_source} ${folder_header})
   
  # link opencv and YARP libraries
  TARGET_LINK_LIBRARIES(foo ${OPENCV_LIBRARIES} ${YARP_LIBRARIES})