diff --git a/ament_cmake_vendor_package/cmake/ament_vendor.cmake b/ament_cmake_vendor_package/cmake/ament_vendor.cmake index c9b963cd..92696dd1 100644 --- a/ament_cmake_vendor_package/cmake/ament_vendor.cmake +++ b/ament_cmake_vendor_package/cmake/ament_vendor.cmake @@ -48,6 +48,31 @@ # project, expose the external project globally to any downstream CMake # projects. # :type GLOBAL_HOOK: option +# :param IS_VENDORED_OUTPUT_VARIABLE_NAME: the name of the variable that +# will be set to ``TRUE`` if the package has been vendored, or ``FALSE`` +# otherwise. +# :type IS_VENDORED_OUTPUT_VARIABLE_NAME: string +# +# Beside proper CMake macro arguments, the macro also is influenced by the +# following CMake advanced options, that can be set from the CMake command +# line when the project that contains the 'ament_vendor' call is configured. +# +# AMENT_VENDOR_POLICY: String option that specifies how ament_vendor behaves, +# the allowed values are listed in the following. +# DEFAULT: Vendor if ``SATISFIED`` argument is not supplied or false, +# do not vendor otherwise. +# FORCE_BUILD_VENDOR: Always vendor, independently of the value of the +# ``SATISFIED`` argument. +# NEVER_VENDOR: Never vendor, and raise an error if ``SATISFIED`` argument +# is not supplied or false. +# NEVER_VENDOR_IGNORE_SATISFIED_CHECK: Never vendor, and do not raise +# an error even if ``SATISFIED`` argument is not supplied +# or false. This option is in unsupported by most packages, +# so use at your own risk, as it could break the buid. +# +# To check if a package has been actually vendored, downstream users of +# ``ament_vendor` can pass a variable name to IS_VENDORED_OUTPUT_VARIABLE_NAME +# argument, and check its value. # # @public # @@ -60,7 +85,7 @@ macro(ament_vendor TARGET_NAME) message(FATAL_ERROR "ament_vendor() must be called before ament_package()") endif() - cmake_parse_arguments(_ARG "GLOBAL_HOOK;SKIP_INSTALL" "SOURCE_SUBDIR;VCS_TYPE;VCS_URL;VCS_VERSION;SATISFIED" "CMAKE_ARGS;PATCHES" ${ARGN}) + cmake_parse_arguments(_ARG "GLOBAL_HOOK;SKIP_INSTALL" "SOURCE_SUBDIR;VCS_TYPE;VCS_URL;VCS_VERSION;SATISFIED;IS_VENDORED_OUTPUT_VARIABLE_NAME" "CMAKE_ARGS;PATCHES" ${ARGN}) if(_ARG_UNPARSED_ARGUMENTS) message(FATAL_ERROR "ament_vendor() called with unused arguments: " "${_ARG_UNPARSED_ARGUMENTS}") @@ -93,15 +118,57 @@ macro(ament_vendor TARGET_NAME) set(_ARG_SATISFIED FALSE) endif() + # If defined, let's set ${_ARG_IS_VENDORED_OUTPUT_VARIABLE_NAME} to FALSE, it will be set + # to TRUE if the package is actually vendored + if(DEFINED _ARG_IS_VENDORED_OUTPUT_VARIABLE_NAME) + # There is no PARENT_SCOPE as this is a cmake macro, + # if it is converted to a function PARENT_SCOPE will need to be added + set(${_ARG_IS_VENDORED_OUTPUT_VARIABLE_NAME} FALSE) + endif() + option(FORCE_BUILD_VENDOR_PKG "Build vendor packages from source, even if system-installed packages are available" OFF) + mark_as_advanced(FORCE_BUILD_VENDOR_PKG) + + set(_AMENT_VENDOR_POLICY_DOCS "Specify how ament_vendor behaves, allowed values are DEFAULT, FORCE_BUILD_VENDOR, NEVER_VENDOR and NEVER_VENDOR_IGNORE_SATISFIED_CHECK.") + set(AMENT_VENDOR_POLICY "DEFAULT" CACHE STRING ${_AMENT_VENDOR_POLICY_DOCS}) + set_property(CACHE AMENT_VENDOR_POLICY PROPERTY STRINGS "DEFAULT" "FORCE_BUILD_VENDOR" "NEVER_VENDOR" "NEVER_VENDOR_IGNORE_SATISFIED_CHECK") + mark_as_advanced(AMENT_VENDOR_POLICY) + + if(FORCE_BUILD_VENDOR_PKG AND NOT AMENT_VENDOR_POLICY STREQUAL "FORCE_BUILD_VENDOR") + message(DEPRECATION "FORCE_BUILD_VENDOR_PKG set to ON detected, FORCE_BUILD_VENDOR_PKG variable is deprecated, please set AMENT_VENDOR_POLICY to FORCE_BUILD_VENDOR instead.") + set(CMAKE_BUILD_TYPE "FORCE_BUILD_VENDOR" CACHE STRING ${_AMENT_VENDOR_POLICY_DOCS} FORCE) + endif() + + # AMENT_VENDOR_POLICY - if(NOT _ARG_SATISFIED OR FORCE_BUILD_VENDOR_PKG) + if(AMENT_VENDOR_POLICY STREQUAL "FORCE_BUILD_VENDOR") + set(_call_ament_vendor TRUE) if(_ARG_SATISFIED) - message(STATUS "Forcing vendor package build for '${TARGET_NAME}', which is already satisfied") + message(STATUS "Forcing vendor package build for '${TARGET_NAME}', which is already satisfied as AMENT_VENDOR_POLICY is set to FORCE_BUILD_VENDOR") endif() + elseif(AMENT_VENDOR_POLICY STREQUAL "NEVER_VENDOR") + if(NOT _ARG_SATISFIED) + message(FATAL_ERROR "Error as SATISFIED argument is not TRUE, but AMENT_VENDOR_POLICY is set to NEVER_VENDOR") + endif() + set(_call_ament_vendor FALSE) + elseif(AMENT_VENDOR_POLICY STREQUAL "NEVER_VENDOR_IGNORE_SATISFIED_CHECK") + if(NOT _ARG_SATISFIED) + message(STATUS "Not vendoring even if SATISFIED is not TRUE as AMENT_VENDOR_POLICY is set to NEVER_VENDOR_IGNORE_SATISFIED_CHECK") + endif() + set(_call_ament_vendor FALSE) + else() + # This is the default case + if(_ARG_SATISFIED) + message(STATUS "Skipping vendor package build for '${TARGET_NAME}', as SATISFIED is TRUE and AMENT_VENDOR_POLICY is set to DEFAULT") + set(_call_ament_vendor FALSE) + else() + set(_call_ament_vendor TRUE) + endif() + endif() + if(_call_ament_vendor) list_append_unique(_AMENT_CMAKE_VENDOR_PACKAGE_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}-prefix/install") _ament_vendor( @@ -115,6 +182,12 @@ macro(ament_vendor TARGET_NAME) "${_ARG_SKIP_INSTALL}" ) + if(DEFINED _ARG_IS_VENDORED_OUTPUT_VARIABLE_NAME) + # There is no PARENT_SCOPE as this is a cmake macro, + # if it is converted to a function PARENT_SCOPE will need to be added + set(${_ARG_IS_VENDORED_OUTPUT_VARIABLE_NAME} TRUE) + endif() + if(NOT _ament_vendor_called AND NOT _ARG_SKIP_INSTALL) # Hooks for CMAKE_PREFIX_PATH if(_ARG_GLOBAL_HOOK) @@ -142,8 +215,6 @@ macro(ament_vendor TARGET_NAME) set(_ament_vendor_called TRUE) endif() - else() - message(STATUS "Skipping vendor package build for '${TARGET_NAME}', which is already satisfied") endif() endmacro()