Skip to content

Commit

Permalink
Allow components in Config.cmake. (#396)
Browse files Browse the repository at this point in the history
* Allow components in Config.cmake.

* Add macro PROJECT_INSTALL_COMPONENT

* Update doc.

* Add missing include

* Add optional argument NAMESPACE to PROJECT_INSTALL_COMPONENT
  • Loading branch information
jmirabel authored Jun 18, 2020
1 parent be594b8 commit 272d644
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 16 deletions.
28 changes: 26 additions & 2 deletions .docs/pages/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ To document a macro or a variable in a ``.cmake`` file, use
# Variable details details (Mind the empty line before).
# Related to :cmake:command:`HOW_TO_DOCUMENT_A_COMMAND`.
#
# A code block::
#
# notice the double : and the indention
#
# or the more verbose, but supports other language
#
# .. code-block:: bash
#
# make html
# # Open build/html/index.html to see the doc
# firefox build/html/index.html
#
# .. command:: HOW_TO_DOCUMENT_A_COMMAND(argname)
#
# Macro details (Mind the empty line before).
Expand All @@ -58,8 +70,20 @@ gives

.. variable:: HOW_TO_DOCUMENT_A_VARIABLE

Variable details (Mind the empty line before).
Related to :cmake:command:`HOW_TO_DOCUMENT_A_COMMAND`.
Variable details (Mind the empty line before).
Related to :cmake:command:`HOW_TO_DOCUMENT_A_COMMAND`.

A cmake code block::
set(foo "notice the double : and the indention")

or the more verbose, but supports other language

.. code-block:: bash
make html
# Open build/html/index.html to see the doc
firefox build/html/index.html
.. command:: HOW_TO_DOCUMENT_A_COMMAND(argname)

Expand Down
31 changes: 28 additions & 3 deletions Config.cmake.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
@PACKAGE_INIT@

if(@PROJECT_NAME@_FOUND)
set(skip_this_file TRUE)
if(NOT @PROJECT_NAME@_FOUND)
set(skip_this_file FALSE)
endif()
if(skip_this_file)
foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS})
if(NOT "@PROJECT_NAME@_${component}_FOUND")
set(skip_this_file FALSE)
endif()
endforeach()
endif()
if(skip_this_file)
return()
endif()

Expand Down Expand Up @@ -82,9 +93,9 @@ set("@PROJECT_NAME_UPPER@_LIBRARIES" ${_PACKAGE_CONFIG_LIBRARIES})

include(CMakeFindDependencyMacro)
if(${CMAKE_VERSION} VERSION_LESS "3.15.0")
@PACKAGE_DEPENDENCIES_FIND_PACKAGE@
@PACKAGE_DEPENDENCIES_FIND_PACKAGE@
else()
@PACKAGE_DEPENDENCIES_FIND_DEPENDENCY@
@PACKAGE_DEPENDENCIES_FIND_DEPENDENCY@
endif()

IF(COMMAND ADD_REQUIRED_DEPENDENCY)
Expand All @@ -98,6 +109,20 @@ IF(COMMAND ADD_REQUIRED_DEPENDENCY)
ENDIF(COMMAND ADD_REQUIRED_DEPENDENCY)

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

foreach(component ${@PROJECT_NAME@_FIND_COMPONENTS})
set(comp_file "${CMAKE_CURRENT_LIST_DIR}/${component}Config.cmake")
if(EXISTS ${comp_file})
include(${comp_file})
else()
set("@PROJECT_NAME@_${component}_FOUND" FALSE)
endif()
if("@PROJECT_NAME@_${component}_FOUND")
message(STATUS "@PROJECT_NAME@: ${component} found.")
else()
message(STATUS "@PROJECT_NAME@: ${component} not found.")
endif()
endforeach()
check_required_components("@PROJECT_NAME@")

@PACKAGE_EXTRA_MACROS@
23 changes: 23 additions & 0 deletions componentConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@PACKAGE_INIT@

if(NOT @PROJECT_NAME@_FOUND)
set(@PROJECT_NAME@_@COMPONENT@_FOUND FALSE)
return()
endif()

# At the moment, components only support targets
#set("@PROJECT_NAME@_@COMPONENT@_INCLUDE_DIRS" "@CMAKE_INSTALL_FULL_INCLUDEDIR@")
#set("@PROJECT_NAME@_@COMPONENT@_LIBRARIES" ${_PACKAGE_CONFIG_LIBRARIES})
set(@PROJECT_NAME@_@COMPONENT@_DEPENDENCIES "@_PACKAGE_CONFIG_COMPONENT_DEPENDENCIES_PROJECTS@")

include(CMakeFindDependencyMacro)
if(${CMAKE_VERSION} VERSION_LESS "3.15.0")
@COMPONENT_FIND_PACKAGE@
else()
@COMPONENT_FIND_DEPENDENCY@
endif()

include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")
set(@PROJECT_NAME@_@COMPONENT@_FOUND TRUE)

@COMPONENT_EXTRA_MACRO@
66 changes: 55 additions & 11 deletions package-config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ set(PACKAGE_EXTRA_MACROS "" CACHE INTERNAL "")
ENDMACRO(_SETUP_PROJECT_PACKAGE_INIT)

#.rst:
# .. command:: ADD_PROJECT_DEPENDENCY(ARGS [PKG_CONFIG_REQUIRES pkg])
# .. command:: ADD_PROJECT_DEPENDENCY(ARGS [PKG_CONFIG_REQUIRES pkg] [FOR_COMPONENT component])
#
# This is a wrapper around find_package to add correct find_dependency calls in
# the generated config script. All arguments are passed to find_package.
Expand All @@ -66,25 +66,27 @@ ENDMACRO(_SETUP_PROJECT_PACKAGE_INIT)
# section of the generated .pc file
#
MACRO(ADD_PROJECT_DEPENDENCY)
list(APPEND _PACKAGE_CONFIG_DEPENDENCIES_PROJECTS "${ARGV0}")

# add dependency to the generated .pc
# ref https://github.com/jrl-umi3218/jrl-cmakemodules/pull/335
cmake_parse_arguments(PARSED_ARGN "" "PKG_CONFIG_REQUIRES" "" ${ARGN})
cmake_parse_arguments(PARSED_ARGN "" "PKG_CONFIG_REQUIRES;FOR_COMPONENT" "" ${ARGN})
IF(PARSED_ARGN_PKG_CONFIG_REQUIRES)
_ADD_TO_LIST_IF_NOT_PRESENT(_PKG_CONFIG_REQUIRES "${PARSED_ARGN_PKG_CONFIG_REQUIRES}")
_ADD_TO_LIST_IF_NOT_PRESENT(_PKG_CONFIG_DEP_NOT_FOR_CONFIG_CMAKE "${PARSED_ARGN_PKG_CONFIG_REQUIRES}")
ENDIF()
if(PARSED_ARGN_FOR_COMPONENT)
set(component "_${PARSED_ARGN_FOR_COMPONENT}")
endif(PARSED_ARGN_FOR_COMPONENT)
_ADD_TO_LIST_IF_NOT_PRESENT(APPEND "_PACKAGE_CONFIG${component}_DEPENDENCIES_PROJECTS" "${ARGV0}")

string(REPLACE ";" " " PACKAGE_ARGS "${PARSED_ARGN_UNPARSED_ARGUMENTS}")
list(APPEND _PACKAGE_CONFIG_DEPENDENCIES_FIND_PACKAGE " find_package(${PACKAGE_ARGS})")
list(APPEND _PACKAGE_CONFIG_DEPENDENCIES_FIND_DEPENDENCY " find_dependency(${PACKAGE_ARGS})")
_ADD_TO_LIST_IF_NOT_PRESENT("_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_PACKAGE" "find_package(${PACKAGE_ARGS})")
_ADD_TO_LIST_IF_NOT_PRESENT("_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_DEPENDENCY" "find_dependency(${PACKAGE_ARGS})")
find_package(${PARSED_ARGN_UNPARSED_ARGUMENTS})

# Propagate variables changes to the cached values
set(_PACKAGE_CONFIG_DEPENDENCIES_PROJECTS "${_PACKAGE_CONFIG_DEPENDENCIES_PROJECTS}" CACHE INTERNAL "")
set(_PACKAGE_CONFIG_DEPENDENCIES_FIND_PACKAGE "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_PACKAGE}" CACHE INTERNAL "")
set(_PACKAGE_CONFIG_DEPENDENCIES_FIND_DEPENDENCY "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_DEPENDENCY}" CACHE INTERNAL "")
set(_PACKAGE_CONFIG${component}_DEPENDENCIES_PROJECTS "${_PACKAGE_CONFIG${component}_DEPENDENCIES_PROJECTS}" CACHE INTERNAL "")
set(_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_PACKAGE "${_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_PACKAGE}" CACHE INTERNAL "")
set(_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_DEPENDENCY "${_PACKAGE_CONFIG${component}_DEPENDENCIES_FIND_DEPENDENCY}" CACHE INTERNAL "")
ENDMACRO()


Expand Down Expand Up @@ -130,8 +132,8 @@ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" PROJECT_NAME_UPPER "${PROJECT_NAME_UPPER
# Include module with fuction 'write_basic_package_version_file'
include(CMakePackageConfigHelpers)

string(REPLACE ";" "\n" PACKAGE_DEPENDENCIES_FIND_PACKAGE "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_PACKAGE}")
string(REPLACE ";" "\n" PACKAGE_DEPENDENCIES_FIND_DEPENDENCY "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_DEPENDENCY}")
string(REPLACE ";" "\n " PACKAGE_DEPENDENCIES_FIND_PACKAGE "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_PACKAGE}")
string(REPLACE ";" "\n " PACKAGE_DEPENDENCIES_FIND_DEPENDENCY "${_PACKAGE_CONFIG_DEPENDENCIES_FIND_DEPENDENCY}")

# Configure '<PROJECT-NAME>ConfigVersion.cmake'
# Note: PROJECT_VERSION is used as a VERSION
Expand Down Expand Up @@ -174,3 +176,45 @@ install(
DESTINATION "${CONFIG_INSTALL_DIR}"
)
ENDMACRO(SETUP_PROJECT_PACKAGE_FINALIZE)

#.rst:
# .. command:: PROJECT_INSTALL_COMPONENT(COMPONENT [EXTRA_MACRO cmake_code] [NAMESPACE namespace])
#
# Generates CMake componentConfig.cmake and Targets files so users can call::
#
# find_package(MyPackage COMPONENT component)
#
# :param EXTRA_MACRO: optional argument. `cmake_code` will be appended to
# the generated *Config.cmake*.
# :param NAMESPACE: optional argument. Defaults to `${PROJECT_NAME}::`.
#
macro(PROJECT_INSTALL_COMPONENT COMPONENT)
cmake_parse_arguments(PARSED_ARGN "" "NAMESPACE;EXTRA_MACRO" "" ${ARGN})
if(PARSED_ARGN_NAMESPACE)
set(namespace "${PARSED_ARGN_NAMESPACE}")
else()
set(namespace "${PROJECT_NAME}::")
endif()

install(EXPORT ${COMPONENT}Targets
NAMESPACE "${namespace}"
DESTINATION "${CONFIG_INSTALL_DIR}")

set(COMPONENT ${COMPONENT})
set(_PACKAGE_CONFIG_COMPONENT_DEPENDENCIES_PROJECTS "${_PACKAGE_CONFIG_${COMPONENT}_DEPENDENCIES_PROJECTS}")
string(REPLACE ";" "\n " COMPONENT_FIND_PACKAGE
"${_PACKAGE_CONFIG_${COMPONENT}_DEPENDENCIES_FIND_PACKAGE}")
string(REPLACE ";" "\n " COMPONENT_FIND_DEPENDENCY
"${_PACKAGE_CONFIG_${COMPONENT}_DEPENDENCIES_FIND_DEPENDENCY}")
set(COMPONENT_CONFIG "${CMAKE_BINARY_DIR}/generated/${COMPONENT}Config.cmake")
set(COMPONENT_EXTRA_MACRO "${PARSED_ARGN_EXTRA_MACRO}")
include(CMakePackageConfigHelpers)
configure_package_config_file(
"${CMAKE_SOURCE_DIR}/cmake/componentConfig.cmake.in"
"${COMPONENT_CONFIG}"
INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
NO_CHECK_REQUIRED_COMPONENTS_MACRO
NO_SET_AND_CHECK_MACRO)
install(FILES "${COMPONENT_CONFIG}"
DESTINATION "${CONFIG_INSTALL_DIR}")
endmacro()

0 comments on commit 272d644

Please sign in to comment.