From 74a1901f8a7b136b06158ac8c18276279b3130e0 Mon Sep 17 00:00:00 2001 From: Alexey Gavrilov Date: Fri, 7 Aug 2026 20:36:28 +0700 Subject: Feature verification script Current script includes a batch of verification routines. One routine allows now - it is dependency verification. It validates dependencies chain start from initial feature to the last sequence dependencies element. That script has helpful in CI pipeline, when cmake generation succeeded. Then needs more checks around the features. Committers might to incorrect convey the features list. CI must identifies these cases. Signed-off-by: Alexey Gavrilov --- cmake/script/feature_verification.cmake | 90 +++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 cmake/script/feature_verification.cmake (limited to 'cmake/script') diff --git a/cmake/script/feature_verification.cmake b/cmake/script/feature_verification.cmake new file mode 100644 index 0000000..2ec1eab --- /dev/null +++ b/cmake/script/feature_verification.cmake @@ -0,0 +1,90 @@ +#[[ + # Copyright (c) 2026 Alexey Gavrilov + # + # This file is part of ObjectiveOS. + # + # ObjectiveOS 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. + # + # ObjectiveOS 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 + # ObjectiveOS. If not, see . + ]] + +#[[ + # This cmake script works like passed feature definitions handling. + # Parameters specify via command line -D option. FEATURE_OUT_FILEPATH is + # necessary, and means path to the features description file generated by + # correspondent module. + ]] + +#[[ + # Read the out file created by the feature module, and instance populated + # variables in current cmake environment. Receive only one argument - path to the + # feature module file to read variables from + ]] +function(readCacheFile filepath) + if(NOT EXISTS ${filepath} OR NOT IS_READABLE ${filepath}) + message(FATAL_ERROR "${filepath} not exists") + endif() + + file(STRINGS ${filepath} vardefines REGEX "^[^#|//][^:]*(:.*)?=(\".+\")") + foreach(line IN LISTS vardefines) + if(line MATCHES "^([^:]+)(:[A-Z]+)?=\"(.+)\"") + set(${CMAKE_MATCH_1} ${CMAKE_MATCH_3} PARENT_SCOPE) + endif() + endforeach() + +endfunction() + +#[[ + # The feature dependency chain checks. Dependency chain is the sequence of + # features interconnected between themself by dependency property. Every this + # check means proper feature definition existence passed through command line. + # Checks are success when last feature has not features dependencies, and all + # options are set. +# Loop dependencies are inappropriate this way. + ]] +function(verify_feature_dependencies feature dependency) + # Through out the non-target dependency + if(NOT FEATURE_${dependency}_ID STREQUAL "${dependency}") + return() + elseif(dependency IN_LIST FEATURE_${feature}_DEPENDENCIES + AND NOT DEFINED FEATURE_${dependency} + ) + message(FATAL_ERROR "${feature} has ${dependency} dependency, " + "but FEATURE_${dependency} is not set") + endif() + + # Dive deep into subsequent recursive iteration + foreach(next_lvl_dep IN LISTS FEATURE_${dependency}_DEPENDENCIES) + verify_feature_dependencies(${dependency} ${next_lvl_dep}) + endforeach() +endfunction() + +#[[ +# Verification start point. Parse available features. +# Forward features to further verifications. + ]] +function(verify_features feature_metadata_filepath) + readCacheFile("${feature_metadata_filepath}") + get_directory_property(_cache_vars CACHE_VARIABLES) + list(FILTER _cache_vars INCLUDE REGEX "FEATURE_[A-Za-z0-9\.]+$") + foreach(enable_feature_def IN LISTS _cache_vars) + # Fetch feature name/id + string(REGEX MATCH "[^_][A-Za-z0-9\.]+$" enable_feature + "${enable_feature_def}" + ) + # Dependencies checks + foreach(dependency IN LISTS FEATURE_${enable_feature}_DEPENDENCIES) + verify_feature_dependencies("${enable_feature}" "${dependency}") + endforeach() + # Put further verifications below + endforeach() +endfunction() + +verify_features("${FEATURE_OUT_FILEPATH}") -- cgit v1.2.3