From 453007f0ec8e9f3cb582ff05fc8d178584b786f5 Mon Sep 17 00:00:00 2001 From: sammiller Date: Fri, 18 Sep 2026 16:23:35 -0700 Subject: [PATCH] Limit licence exemptions to CTest-generated targets Signed-off-by: sammiller --- CMakeLists.txt | 10 +++++++--- docs/licence-boundary.md | 6 ++++-- eng/test_licence_boundary.py | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a84ef57..25e7846 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,13 +20,17 @@ project(DesktopPlatform VERSION 0.1.0 LANGUAGES C CXX) option(ARCFORGES_BUILD_TESTS "Build native ABI smoke tests" ON) option(ARCFORGES_BUILD_FUZZERS "Build Clang libFuzzer ABI boundary targets" OFF) if(ARCFORGES_BUILD_TESTS) + get_property(_arcforges_targets_before_ctest DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) include(CTest) + get_property(_arcforges_ctest_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) + # Exempt only targets created by CTest, including when owned targets precede it. + if(_arcforges_targets_before_ctest) + list(REMOVE_ITEM _arcforges_ctest_targets ${_arcforges_targets_before_ctest}) + endif() + set_property(DIRECTORY PROPERTY ARCFORGES_EXTERNAL_TARGETS "${_arcforges_ctest_targets}") enable_testing() endif() -# CTest creates dashboard utility targets; record those before adding owned targets. -get_property(_arcforges_ctest_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) -set_property(DIRECTORY PROPERTY ARCFORGES_EXTERNAL_TARGETS "${_arcforges_ctest_targets}") include(eng/cmake/LicenceBoundary.cmake) add_subdirectory(native) cmake_language(DEFER CALL arcforges_verify_native_licences) diff --git a/docs/licence-boundary.md b/docs/licence-boundary.md index 51631c0..53948a5 100644 --- a/docs/licence-boundary.md +++ b/docs/licence-boundary.md @@ -31,10 +31,12 @@ dirty state, targets and configure-time link expressions in `artifacts/cmake///licence-boundary.json`. Imported dependencies keep their own licences; CTest's generated utility targets are identified separately. The existing native-stage audit still verifies the actual third-party binary, -notice and source closure. Declaration checks do not replace it. +notice and source closure. Declaration checks do not replace it. Only targets created +by the CTest module are exempt; owned targets added before it still require declarations, +with both native-test settings covered by a regression using the actual root CMake file. CI requires both operating systems' source/managed checks and the Windows native -IDE/CMake reports before packaging. Ten negative/positive test groups include real +IDE/CMake reports before packaging. Eleven negative/positive test groups include real MSBuild global overrides, real CMake target changes and malformed reference graphs. The current Design exports are refreshed to the same accepted baseline; glossary content and forbidden-alias digests are unchanged. diff --git a/eng/test_licence_boundary.py b/eng/test_licence_boundary.py index b7cbf40..abf54a1 100644 --- a/eng/test_licence_boundary.py +++ b/eng/test_licence_boundary.py @@ -126,6 +126,24 @@ def test_actual_cmake_rejects_missing_or_overridden_target(self): self.write('CMakeLists.txt', source + addition + '\n') self.assertIn('AFL001', self.run_tool('cmake', '-S', '.', '-B', directory, success=False)) + def test_real_root_does_not_exempt_owned_targets_before_ctest(self): + source = (policy.ROOT / 'CMakeLists.txt').read_text(encoding='utf-8') + source = source.replace('LANGUAGES C CXX', 'LANGUAGES NONE') + source = source.replace('include(eng/cmake/LicenceBoundary.cmake)', + f'include("{(policy.ROOT / "eng/cmake/LicenceBoundary.cmake").as_posix()}")') + source = source.replace('add_subdirectory(native)', + 'add_custom_target(registered)\narcforges_declare_target_licence(registered)') + source = source.replace('option(ARCFORGES_BUILD_TESTS', + 'add_custom_target(early_unregistered)\noption(ARCFORGES_BUILD_TESTS') + self.write('CMakeLists.txt', source) + self.write('toolchain.cmake', '# Empty toolchain for a LANGUAGES NONE policy fixture.\n') + for enabled in ('ON', 'OFF'): + output = self.run_tool('cmake', '-S', '.', '-B', 'ctest-' + enabled, + '-DARCFORGES_NATIVE_PROFILE=runtime-shared', '-DVCPKG_TARGET_TRIPLET=fixture', + '-DCMAKE_TOOLCHAIN_FILE=' + str(self.root / 'toolchain.cmake'), + '-DARCFORGES_BUILD_TESTS=' + enabled, success=False) + self.assertIn('AFL001: missing or incorrect native target licence: early_unregistered', output) + if __name__ == '__main__': unittest.main()