blob: 2ec1eabd5b293147f4fda3d67f0c4cefa6e9310c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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}")
|