diff options
| -rw-r--r-- | cmake/script/feature_verification.cmake | 90 |
1 files changed, 90 insertions, 0 deletions
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 <alexey.gavrilov@mail.com> + # + # 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 <https://www.gnu.org/licenses/>. + ]] + +#[[ + # 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}") |
