#[[ # 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}")