cmvr-es/dependency/arm/third_party/jrl-cmakemodules/v1.1.2/share/jrl-cmakemodules/header.cmake

329 lines
10 KiB
CMake

#.rst:
# C++ Headers
# -----------
#
# .. command:: _SETUP_PROJECT_HEADER
#
# This setup CMake to handle headers properly.
#
# 1. The `include` directory in the build and source trees is added to the
# include search path (see INCLUDE_DIRECTORIES). As always, the build
# directory has the priority over the source directory in case of conflict.
#
# However you *should not* have conflicting names for files which are both in
# the build and source trees. Conflicting names are filenames which differ only
# by a prefix:
#
# include/a.h vs _build/include/a.h src/a.h vs src/foo/a.h
#
# ...this files makes a project very fragile as the -I ordering will have a lot
# of importance and may break easily when using tools which may reorder the
# pre-processor flags such as pkg-config.
#
# 1. The headers are installed in the prefix in a way which preserves the
# directory structure.
#
# The directory name for header follows the rule: each non alpha-numeric
# character is replaced by a slash (`/`). In practice, it means that hpp-util
# will put its header in: ${CMAKE_INSTALL_PREFIX}/include/hpp/util
#
# This rule has been decided to homogenize headers location, however some
# packages do not follow this rule (dg-middleware for instance).
#
# In that case, CUSTOM_HEADER_DIR can be set to override this policy.
#
# Reminder: breaking the JRL/LAAS policies shoud be done after discussing the
# issue. You should at least open a ticket or send an e-mail to notify this
# behavior.
#
# Copyright (C) 2008-2024 LAAS-CNRS, JRL AIST-CNRS, INRIA.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
# .rst: .. ifmode:: user
#
# .. variable:: ${PROJECT_NAME}_HEADERS
#
# List of C++ header filenames. They will be installed automatically using
# :command:`HEADER_INSTALL`
#
macro(_SETUP_PROJECT_HEADER)
# Install project headers.
if(DEFINED PROJECT_CUSTOM_HEADER_DIR)
set(HEADER_DIR "${PROJECT_CUSTOM_HEADER_DIR}")
elseif(DEFINED CUSTOM_HEADER_DIR)
set(HEADER_DIR "${CUSTOM_HEADER_DIR}")
else()
string(REGEX REPLACE "[^a-zA-Z0-9]" "/" HEADER_DIR "${PROJECT_NAME}")
endif()
if(NOT DEFINED PROJECT_CUSTOM_HEADER_EXTENSION)
set(PROJECT_CUSTOM_HEADER_EXTENSION "hh")
endif(NOT DEFINED PROJECT_CUSTOM_HEADER_EXTENSION)
if(NOT DEFINED PROJECT_GENERATED_HEADERS_SKIP_CONFIG)
set(PROJECT_GENERATED_HEADERS_SKIP_CONFIG OFF)
endif()
if(NOT DEFINED PROJECT_GENERATED_HEADERS_SKIP_DEPRECATED)
set(PROJECT_GENERATED_HEADERS_SKIP_DEPRECATED OFF)
endif()
if(NOT DEFINED PROJECT_GENERATED_HEADERS_SKIP_WARNING)
set(PROJECT_GENERATED_HEADERS_SKIP_WARNING OFF)
endif()
string(TOLOWER "${HEADER_DIR}" "HEADER_DIR")
string(REGEX REPLACE "[^a-zA-Z0-9]" "_" PACKAGE_CPPNAME "${PROJECT_NAME}")
string(TOLOWER "${PACKAGE_CPPNAME}" "PACKAGE_CPPNAME_LOWER")
string(TOUPPER "${PACKAGE_CPPNAME}" "PACKAGE_CPPNAME")
if(NOT PROJECT_GENERATED_HEADERS_SKIP_CONFIG)
# Generate config.hh header.
GENERATE_CONFIGURATION_HEADER(
${HEADER_DIR}
config.${PROJECT_CUSTOM_HEADER_EXTENSION}
${PACKAGE_CPPNAME}
${PACKAGE_CPPNAME_LOWER}_EXPORTS
)
endif()
if(NOT PROJECT_GENERATED_HEADERS_SKIP_DEPRECATED)
# Generate deprecated.hh header.
configure_file(
${PROJECT_JRL_CMAKE_MODULE_DIR}/deprecated.hh.cmake
${CMAKE_CURRENT_BINARY_DIR}/include/${HEADER_DIR}/deprecated.${PROJECT_CUSTOM_HEADER_EXTENSION}
@ONLY
)
if(INSTALL_GENERATED_HEADERS)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/include/${HEADER_DIR}/deprecated.${PROJECT_CUSTOM_HEADER_EXTENSION}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${HEADER_DIR}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
)
endif(INSTALL_GENERATED_HEADERS)
endif()
if(NOT PROJECT_GENERATED_HEADERS_SKIP_WARNING)
# Generate warning.hh header.
configure_file(
${PROJECT_JRL_CMAKE_MODULE_DIR}/warning.hh.cmake
${CMAKE_CURRENT_BINARY_DIR}/include/${HEADER_DIR}/warning.${PROJECT_CUSTOM_HEADER_EXTENSION}
@ONLY
)
if(INSTALL_GENERATED_HEADERS)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/include/${HEADER_DIR}/warning.${PROJECT_CUSTOM_HEADER_EXTENSION}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${HEADER_DIR}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
)
endif(INSTALL_GENERATED_HEADERS)
endif()
# Generate config.h header. This header, unlike the previous one is *not*
# installed and is generated in the top-level directory of the build tree.
# Therefore it must not be included by any distributed header.
configure_file(
${PROJECT_JRL_CMAKE_MODULE_DIR}/config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config.h
)
# Default include directories: - top-level build directory (for generated
# non-distributed headers). - include directory in the build tree (for
# generated, distributed headers). - include directory in the source tree
# (non-generated, distributed headers).
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/include
${PROJECT_SOURCE_DIR}/include
)
endmacro(_SETUP_PROJECT_HEADER)
# GENERATE_CONFIGURATION_HEADER
# -----------------------------
#
# This macro generates a configuration header. Macro parameters may be used to
# customize it.
#
# * HEADER_DIR : where to generate the header
# * FILENAME : how the file should be named
# * LIBRARY_NAME : CPP symbol prefix, should match the compiled library name
# * EXPORT_SYMBOL : controls the switch between symbol import/export
function(
GENERATE_CONFIGURATION_HEADER
HEADER_DIR
FILENAME
LIBRARY_NAME
EXPORT_SYMBOL
)
GENERATE_CONFIGURATION_HEADER_V2(
INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include
HEADER_DIR ${HEADER_DIR}
FILENAME ${FILENAME}
LIBRARY_NAME ${LIBRARY_NAME}
EXPORT_SYMBOL ${EXPORT_SYMBOL}
)
endfunction(GENERATE_CONFIGURATION_HEADER)
# ~~~
# .rst: .. command:: GENERATE_CONFIGURATION_HEADER_V2 (
# INCLUDE_DIR <include_dir>
# HEADER_DIR <header_dir>
# FILENAME <filename>
# LIBRARY_NAME <library_name>
# EXPORT_SYBMOL <export_symbol>)
# ~~~
#
# This function generates a configuration header at
# ``<include_dir>/<header_dir>/<filename>``.
#
# If INSTALL_GENERATED_HEADERS is ON, the configuration header will be installed
# in
# ``${CMAKE_INSTALL_INCLUDEDIR}/<header_dir>``.
#
# :param INCLUDE_DIR: Include root directory (absolute).
#
# :param HEADER_DIR: Include sub directory.
#
# :param FILENAME: Configuration header name.
#
# :param LIBRARY_NAME: CPP symbol prefix, should match the compiled library
# name.
#
# :param EXPORT_SYMBOL: Controls the switch between symbol import/export.
function(GENERATE_CONFIGURATION_HEADER_V2)
set(options)
set(
oneValueArgs
INCLUDE_DIR
HEADER_DIR
FILENAME
LIBRARY_NAME
EXPORT_SYMBOL
)
set(multiValueArgs)
cmake_parse_arguments(
ARGS
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
if(${PROJECT_VERSION_MAJOR} MATCHES UNKNOWN)
set(PROJECT_VERSION_MAJOR_CONFIG ${ARGS_LIBRARY_NAME}_VERSION_UNKNOWN_TAG)
else()
set(PROJECT_VERSION_MAJOR_CONFIG ${PROJECT_VERSION_MAJOR})
endif()
if(${PROJECT_VERSION_MINOR} MATCHES UNKNOWN)
set(PROJECT_VERSION_MINOR_CONFIG ${ARGS_LIBRARY_NAME}_VERSION_UNKNOWN_TAG)
else()
set(PROJECT_VERSION_MINOR_CONFIG ${PROJECT_VERSION_MINOR})
endif()
if(${PROJECT_VERSION_PATCH} MATCHES UNKNOWN)
set(PROJECT_VERSION_PATCH_CONFIG ${ARGS_LIBRARY_NAME}_VERSION_UNKNOWN_TAG)
else()
set(PROJECT_VERSION_PATCH_CONFIG ${PROJECT_VERSION_PATCH})
endif()
# Set variables for configure_file command
set(EXPORT_SYMBOL ${ARGS_EXPORT_SYMBOL})
set(LIBRARY_NAME ${ARGS_LIBRARY_NAME})
# Generate the header.
configure_file(
${PROJECT_JRL_CMAKE_MODULE_DIR}/config.hh.cmake
${ARGS_INCLUDE_DIR}/${ARGS_HEADER_DIR}/${ARGS_FILENAME}
@ONLY
)
# Install it if requested.
if(INSTALL_GENERATED_HEADERS)
install(
FILES ${ARGS_INCLUDE_DIR}/${ARGS_HEADER_DIR}/${ARGS_FILENAME}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${ARGS_HEADER_DIR}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
)
endif()
endfunction(GENERATE_CONFIGURATION_HEADER_V2)
# _SETUP_PROJECT_HEADER_FINALIZE
# ------------------------------
#
# Post-processing of the header management step. Install public headers if
# required.
#
macro(_SETUP_PROJECT_HEADER_FINALIZE)
# If the header list is set, install it.
if(DEFINED ${PROJECT_NAME}_HEADERS AND NOT BUILD_STANDALONE_PYTHON_INTERFACE)
HEADER_INSTALL(${${PROJECT_NAME}_HEADERS})
endif()
endmacro(_SETUP_PROJECT_HEADER_FINALIZE)
# .rst: .. ifmode:: internal
#
# ~~~
# .. command:: HEADER_INSTALL (COMPONENT <component> <files>...)
# ~~~
#
# Install a list of headers.
#
# :param component: Component to forward to install command.
#
# :param files: Files to install.
macro(HEADER_INSTALL)
set(options)
set(oneValueArgs COMPONENT)
set(multiValueArgs)
cmake_parse_arguments(
ARGS
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
if(ARGS_COMPONENT)
set(_COMPONENT_NAME ${ARGS_COMPONENT})
else()
set(_COMPONENT_NAME ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME})
endif()
set(FILES ${ARGS_UNPARSED_ARGUMENTS})
foreach(FILE ${FILES})
get_filename_component(DIR "${FILE}" PATH)
string(REPLACE "${PROJECT_BINARY_DIR}" "" DIR "${DIR}")
string(REPLACE "${PROJECT_SOURCE_DIR}" "" DIR "${DIR}")
string(REPLACE "include" "" DIR "${DIR}")
# workaround CMP0177
cmake_path(SET INSTALL_PATH NORMALIZE "${CMAKE_INSTALL_INCLUDEDIR}/${DIR}")
install(
FILES ${FILE}
DESTINATION ${INSTALL_PATH}
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ OWNER_WRITE
COMPONENT ${_COMPONENT_NAME}
)
endforeach()
endmacro()