cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
156 lines
6.4 KiB
CMake
156 lines
6.4 KiB
CMake
# SPDX-FileCopyrightText: 2020 Andreas Cord-Landwehr <cordlandwehr@kde.org>
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
#[=======================================================================[.rst:
|
|
ECMCheckOutboundLicense
|
|
-----------------------
|
|
|
|
Assert that source file licenses are compatible with a desired outbound license
|
|
of a compiled binary artifact (e.g., library, plugin or application).
|
|
|
|
This module provides the ``ecm_check_outbound_license`` function that
|
|
generates unit tests for checking the compatibility of license statements.
|
|
The license statements in all tested files are required to be added by using
|
|
the SPDX marker ``SPDX-License-Identifier``.
|
|
|
|
During the CMake configuration of the project, a temporary license bill of
|
|
materials (BOM) in SPDX format is generated by calling the REUSE tool
|
|
(see <https://reuse.software>). That BOM is parsed and license computations
|
|
based on an internal compatibility matrix are performed.
|
|
|
|
Preconditions for using this module:
|
|
* All tested input source files must contain the SPDX-License-Identifier tag.
|
|
* Python3 must be available.
|
|
* The REUSE tool must be available, which generates the bill-of-materials
|
|
by running ``reuse spdx`` on the tested directory.
|
|
|
|
When this module is included, a ``SKIP_LICENSE_TESTS`` option is added (default
|
|
``OFF``). Turning this option on skips the generation of license tests, which might
|
|
be convenient if licenses shall not be tested in all build configurations.
|
|
|
|
::
|
|
|
|
ecm_check_outbound_license(LICENSES <outbound-licenses>
|
|
FILES <source-files>
|
|
[TEST_NAME <name>]
|
|
[WILL_FAIL])
|
|
|
|
This method adds a custom unit test to ensure the specified outbound license to be
|
|
compatible with the specified license headers. Note that a convenient way is to use
|
|
the CMake ``GLOB`` argument of the ``FILE`` function.
|
|
|
|
``LICENSES`` : List of one or multiple outbound license regarding which the compatibility of the source code files shall be tested.
|
|
Currently, the following values are supported (values are SPDX registry identifiers):
|
|
* MIT
|
|
* BSD-2-Clause
|
|
* BSD-3-Clause
|
|
* LGPL-2.0-only
|
|
* LGPL-2.1-only
|
|
* LGPL-3.0-only
|
|
* GPL-2.0-only
|
|
* GPL-3.0-only
|
|
|
|
``FILES:`` : List of source files that contain valid SPDX-License-Identifier markers.
|
|
The paths can be relative to the CMake file that generates the test case
|
|
or be absolute paths.
|
|
|
|
``TEST_NAME`` : Optional parameter that defines the name of the generated test case.
|
|
If no name is defined, the relative path to the test directory with appended
|
|
license name is used. Every test has ``licensecheck_`` as prefix.
|
|
|
|
``WILL_FAIL`` : Optional parameter that inverts the test result. This parameter is usually only
|
|
used for tests of the module.
|
|
|
|
Since 5.75.0
|
|
#]=======================================================================]
|
|
|
|
include(FeatureSummary)
|
|
|
|
option(SKIP_LICENSE_TESTS "Skip outbound license tests" OFF)
|
|
|
|
find_package(Python3)
|
|
set_package_properties(Python3 PROPERTIES
|
|
PURPOSE "Required to run tests of module ECMCheckOutboundLicense"
|
|
TYPE OPTIONAL
|
|
)
|
|
|
|
find_package(ReuseTool)
|
|
set_package_properties(ReuseTool PROPERTIES
|
|
PURPOSE "Required to run tests of module ECMCheckOutboundLicense"
|
|
TYPE OPTIONAL
|
|
)
|
|
|
|
if (NOT SKIP_LICENSE_TESTS AND NOT REUSETOOL_FOUND)
|
|
add_feature_info(SPDX_LICENSE_TESTING FALSE "Automatic license testing based on SPDX definitions (requires reuse tool)")
|
|
message(WARNING "Reuse tool not found, skipping test generation")
|
|
else()
|
|
add_feature_info(SPDX_LICENSE_TESTING TRUE "Automatic license testing based on SPDX definitions (requires reuse tool)")
|
|
endif()
|
|
|
|
set(SPDX_BOM_OUTPUT "${CMAKE_BINARY_DIR}/spdx.txt")
|
|
|
|
# test fixture for generating SPDX bill of materials
|
|
if(SKIP_LICENSE_TESTS OR NOT REUSETOOL_FOUND)
|
|
message(STATUS "Skipping execution of outbound license tests.")
|
|
else()
|
|
add_test(
|
|
NAME generate_spdx_bom
|
|
COMMAND reuse spdx -o ${SPDX_BOM_OUTPUT}
|
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
)
|
|
set_tests_properties(generate_spdx_bom PROPERTIES FIXTURES_SETUP SPDX_BOM)
|
|
endif()
|
|
|
|
function(ecm_check_outbound_license)
|
|
if(SKIP_LICENSE_TESTS OR NOT REUSETOOL_FOUND)
|
|
return()
|
|
endif()
|
|
|
|
set(_options WILL_FAIL)
|
|
set(_oneValueArgs TEST_NAME)
|
|
set(_multiValueArgs LICENSES FILES)
|
|
cmake_parse_arguments(ARG "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN} )
|
|
|
|
if(NOT ARG_LICENSES)
|
|
message(FATAL_ERROR "No LICENSES argument given to ecm_check_outbound_license")
|
|
endif()
|
|
|
|
if(NOT ARG_FILES)
|
|
message(WARNING "No FILES argument given to ecm_check_outbound_license")
|
|
return()
|
|
endif()
|
|
|
|
if(NOT ARG_TEST_NAME)
|
|
# compute test name based on licensecheck_<relative-path>_<licence> if not name given
|
|
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" TEMP_TEST_NAME "${CMAKE_CURRENT_SOURCE_DIR}_${ARG_LICENSE}")
|
|
string(MAKE_C_IDENTIFIER ${TEMP_TEST_NAME} ARG_TEST_NAME)
|
|
endif()
|
|
|
|
# generate file with list of relative file paths
|
|
string(REPLACE "${CMAKE_BINARY_DIR}/" "" RELATIVE_PREFIX_PATH ${CMAKE_CURRENT_BINARY_DIR})
|
|
set(OUTPUT_FILE ${CMAKE_BINARY_DIR}/licensecheck_${ARG_TEST_NAME}.txt)
|
|
file(REMOVE ${OUTPUT_FILE})
|
|
foreach(_file ${ARG_FILES})
|
|
# check script expects files to start with "./", which must be relative to CMAKE_SOURCE_DIR
|
|
if (IS_ABSOLUTE ${_file})
|
|
string(REPLACE ${CMAKE_SOURCE_DIR} "." TEMPORARY_PATH ${_file})
|
|
file(APPEND ${OUTPUT_FILE} "${TEMPORARY_PATH}\n")
|
|
else()
|
|
file(APPEND ${OUTPUT_FILE} "./${RELATIVE_PREFIX_PATH}/${_file}\n")
|
|
endif()
|
|
endforeach()
|
|
|
|
file(COPY ${ECM_MODULE_DIR}/check-outbound-license.py DESTINATION ${CMAKE_BINARY_DIR})
|
|
|
|
foreach(_license ${ARG_LICENSES})
|
|
string(MAKE_C_IDENTIFIER ${_license} LICENSE_ID)
|
|
add_test(
|
|
NAME licensecheck_${ARG_TEST_NAME}_${LICENSE_ID}
|
|
COMMAND python3 ${CMAKE_BINARY_DIR}/check-outbound-license.py -l ${_license} -s ${SPDX_BOM_OUTPUT} -i ${OUTPUT_FILE}
|
|
)
|
|
set_tests_properties(licensecheck_${ARG_TEST_NAME}_${LICENSE_ID} PROPERTIES FIXTURES_REQUIRED SPDX_BOM)
|
|
set_tests_properties(licensecheck_${ARG_TEST_NAME}_${LICENSE_ID} PROPERTIES WILL_FAIL ${ARG_WILL_FAIL})
|
|
endforeach()
|
|
endfunction()
|