1#!/bin/awk -f 2 3function get_values(var, arr) { 4 return split(ENVIRON[var], arr, " ") 5} 6 7# Add a line of data to config.mk. 8function add_line_to_config_mk(line) { 9 print(line) >> config_mk 10} 11 12function add_to_config_h_if_yes(value, define) { 13 if (value == "yes") 14 print(define) >> config_h 15 else 16 print("/* " define " */") >> config_h 17} 18 19# 20# Feature handling functions 21# 22 23# Get the name of the feature 24function get_feature_name(feature) { 25 return ENVIRON["_feature_" feature "_name"] 26} 27 28# Check whether the feature is enabled 29function get_feature_state(feature) { 30 get_values("_feature_" feature "_settings", settings) 31 for (i in settings) { 32 if (ENVIRON[settings[i]] == "yes") 33 return "yes" 34 } 35 return "no" 36} 37 38 39# 40# Engine handling functions 41# 42 43# Get the name of the engine 44function get_engine_name(engine) { 45 return ENVIRON["_engine_" engine "_name"] 46} 47 48# Will this engine be built? 49function get_engine_build(engine) { 50 return ENVIRON["_engine_" engine "_build"] 51} 52 53# Was this engine set to be built by default? 54function get_engine_build_default(engine) { 55 return ENVIRON["_engine_" engine "_build_default"] 56} 57 58# Get the subengines 59function get_engine_subengines(engine, subengines) { 60 return get_values("_engine_" engine "_subengines", subengines) 61} 62 63# Get the dependencies 64function get_engine_dependencies(engine, deps) { 65 return get_values("_engine_" engine "_deps", deps) 66} 67 68# Get the base engine game support description 69function get_engine_base(engine) { 70 return ENVIRON["_engine_" engine "_base"] 71} 72 73# Ask if this is a subengine 74function get_engine_sub(engine) { 75 subeng = ENVIRON["_engine_" engine "_sub"] 76 if (subeng == "") 77 subeng = "no" 78 return subeng 79} 80 81# Get a subengine's parent (undefined for non-subengines) 82function get_subengine_parent(engine) { 83 return ENVIRON["_engine_" engine "_parent"] 84} 85 86function disable_engine(engine) { 87 ENVIRON["_engine_" engine "_build"] = "no" 88} 89 90function check_engine_deps(engine) { 91 unmet_deps = "" 92 93 # Check whether the engine is enabled 94 if (get_engine_build(engine) != "no") { 95 # Collect unmet dependencies 96 depcount = get_engine_dependencies(engine, deps) 97 for (d = 1; d <= depcount; d++) { 98 if (get_feature_state(deps[d]) == "no") 99 unmet_deps = unmet_deps get_feature_name(deps[d]) " " 100 } 101 102 # Check whether there is any unmet dependency 103 if (unmet_deps) { 104 print("WARNING: Disabling engine " get_engine_name(engine) " because the following dependencies are unmet: " unmet_deps) 105 disable_engine(engine) 106 } 107 } 108} 109 110# Prepare the strings about the engines to build 111function prepare_engine_build_strings(engine) { 112 if (string = get_engine_build_string(engine, "static")) 113 _engines_built_static[++_static] = string 114 115 if (string = get_engine_build_string(engine, "dynamic")) 116 _engines_built_dynamic[++_dynamic] = string 117 118 if (string = get_engine_build_string(engine, "no")) 119 _engines_skipped[++_skipped] = string 120 121 if (string = get_engine_build_string(engine, "wip")) 122 _engines_built_wip[++_wip] = string 123} 124 125# Get the string about building an engine 126function get_engine_build_string(engine, request_status) { 127 engine_build = get_engine_build(engine) 128 engine_build_default = get_engine_build_default(engine) 129 show = 0 130 131 # Convert static/dynamic to yes to ease the check of subengines 132 if (engine_build == "no") 133 subengine_filter = "no" 134 else 135 subengine_filter = "yes" 136 137 # Check if the current engine should be shown for the current status 138 if (engine_build == request_status) { 139 show = 1 140 } else { 141 # Test for disabled sub-engines 142 if (request_status == "no") { 143 get_engine_subengines(engine, subengines) 144 for (subeng in subengines) { 145 if (get_engine_build(subengines[subeng]) == "no") { 146 # In this case we to display _disabled_ subengines 147 subengine_filter = "no" 148 show = 1 149 break 150 } 151 } 152 } 153 # Test for enabled wip sub-engines 154 if (request_status == "wip") { 155 get_engine_subengines(engine, subengines) 156 for (subeng in subengines) { 157 if (get_engine_build(subengines[subeng]) != "no" && get_engine_build_default(subengines[subeng]) == "no") { 158 show = 1 159 break 160 } 161 } 162 } 163 } 164 165 166 # Check if it is a wip engine 167 if (request_status == "wip" && engine_build != "no" && engine_build_default == "no") 168 show = 1 169 170 # The engine should be shown, build the string 171 if (show) 172 return get_engine_name(engine) " " get_subengines_build_string(engine, subengine_filter, request_status) 173} 174 175# Get the string about building subengines 176function get_subengines_build_string(parent_engine, subengine_filter, request_status) { 177 parent_engine_build_default = get_engine_build_default(parent_engine) 178 subengine_string = "" 179 180 # If the base engine isn't built at all, no need to list subengines 181 # in any of the possible categories. 182 if (get_engine_build(parent_engine) == "no") 183 return 184 185 all = 1 186 subeng_count = get_engine_subengines(parent_engine, subengines) 187 # If there are no subengines, never display "[all games]" (for brevity). 188 if (!subeng_count) 189 all = 0 190 # If the base engine does not fit the category we're displaying here 191 # (WIP or Skipped), we should never show "[all games]" 192 if (request_status == "wip" && parent_engine_build_default == "yes") 193 all = 0 194 if (request_status == "no") { 195 # If we're here, the parent engine is built, so no need to check that. 196 all = 0 197 } 198 199 200 # In the static/dynamic categories, also display the engine's base games. 201 if (subeng_count && request_status != "no" && request_status != "wip") 202 subengine_string = "[" get_engine_base(parent_engine) "]" 203 204 for (s = 1; s <= subeng_count; s++) { 205 subeng = subengines[s] 206 subengine_build = get_engine_build(subeng) 207 subengine_build_default = get_engine_build_default(subeng) 208 209 # Display this subengine if it matches the filter, unless it is 210 # a stable subengine in the WIP request. 211 if ((subengine_build == subengine_filter) && !(request_status == "wip" && subengine_build_default == "yes")) { 212 name = "[" get_engine_name(subeng) "]" 213 if (subengine_string) 214 subengine_string = subengine_string " " name 215 else 216 subengine_string = name 217 } else { 218 all = 0 219 } 220 } 221 222 # Summarize the full list, where applicable 223 if (all) 224 subengine_string = "[all games]" 225 226 return subengine_string 227} 228 229function print_engines(headline, engines, count) { 230 if (!count) 231 return 232 print("\n" headline) 233 for (e = 1; e <= count; e++) 234 print(" " engines[e]) 235} 236 237BEGIN { 238 config_mk = "config.mk.engines" 239 config_h = "config.h.engines" 240 # Clear previous contents if any 241 printf("") > config_h 242 printf("") > config_mk 243} 244 245END { 246 engine_count = get_values("_engines", engines) 247 for (e = 1; e <= engine_count; e++) { 248 engine = engines[e] 249 check_engine_deps(engine) 250 if (get_engine_sub(engine) == "no") { 251 # It's a main engine 252 if (get_engine_build(engine) == "no") { 253 isbuilt = "no" 254 } else { 255 # If dynamic plugins aren't supported, mark 256 # all the engines as static 257 if (ENVIRON["_dynamic_modules"] == "no") { 258 ENVIRON["_engine_" engine "_build"] = "static" 259 } else { 260 # If it wasn't explicitly marked as static or 261 # dynamic, use the configured default 262 if (get_engine_build(engine) == "yes") 263 ENVIRON["_engine_" engine "_build"] = ENVIRON["_plugins_default"] 264 } 265 266 # Prepare the defines 267 if (get_engine_build(engine) == "dynamic") { 268 isbuilt = "DYNAMIC_PLUGIN" 269 } else { 270 ENVIRON["_engine_" engine "_build"] = "static" 271 isbuilt = "STATIC_PLUGIN" 272 } 273 } 274 } else { 275 # It's a subengine, just say yes or no 276 if (get_engine_build(engine) == "no") 277 isbuilt = "no" 278 else 279 isbuilt = "1" 280 } 281 282 # Save the settings 283 defname = "ENABLE_" toupper(engine) 284 if (isbuilt == "no") 285 add_line_to_config_mk("# " defname) 286 else 287 add_line_to_config_mk(defname " = " isbuilt) 288 } 289 290 # Sort engines to place our headline engine at start... 291 # No technical reason, just historical convention 292 headline_engine = "scumm" 293 sorted_engines[++sorted] = headline_engine 294 for (e = 1; e <= engine_count; e++) { 295 if (engines[e] != headline_engine) 296 sorted_engines[++sorted] = engines[e] 297 } 298 299 # Prepare the information to be shown 300 for (e = 1; e <= engine_count; e++) { 301 engine = sorted_engines[e] 302 if (get_engine_sub(engine) == "no") { 303 # It's a main engine 304 prepare_engine_build_strings(engine) 305 } 306 } 307 308 # 309 # Detection of WIP/unstable engines 310 # 311 for (e in engines) { 312 engine = engines[e] 313 if (get_engine_build(engine) != "no" && get_engine_build_default(engine) == "no") { 314 _tainted_build = "yes" 315 break 316 } 317 } 318 319 add_to_config_h_if_yes(_tainted_build, "#define TAINTED_BUILD") 320 print_engines("Engines (builtin):", _engines_built_static, _static) 321 print_engines("Engines (plugins):", _engines_built_dynamic, _dynamic) 322 print_engines("Engines Skipped:", _engines_skipped, _skipped) 323 print_engines("WARNING: This ScummVM build contains the following UNSTABLE engines:", _engines_built_wip, _wip) 324 325 # Ensure engines folder exists prior to trying to generate 326 # files into it (used for out-of-tree-builds) 327 system("mkdir -p engines") 328 329 print("") 330 print("Creating engines/engines.mk") 331 engines_mk = "engines/engines.mk.new" 332 print("# This file is automatically generated by configure\n" \ 333 "# DO NOT EDIT MANUALLY\n" \ 334 "# This file is being included by \"Makefile.common\"") > engines_mk 335 336 for (e = 1; e <= engine_count; e++) { 337 engine = sorted_engines[e] 338 j = toupper(engine) 339 if (get_engine_sub(engine) == "no") { 340 # main engine 341 print("\n" \ 342 "ifdef ENABLE_" j "\n" \ 343 "DEFINES += -DENABLE_" j "=$(ENABLE_" j ")\n" \ 344 "MODULES += engines/" engine) >> engines_mk 345 346 subeng_count = get_engine_subengines(engine, subengines) 347 for (s = 1; s <= subeng_count; s++) { 348 k = toupper(subengines[s]) 349 print("\n" \ 350 "ifdef ENABLE_" k "\n" \ 351 "DEFINES += -DENABLE_" k "\n" \ 352 "endif") >> engines_mk 353 } 354 355 print("endif") >> engines_mk 356 } 357 } 358 359 # Name which is suffixed to each detection plugin 360 detectId = "_DETECTION" 361 det_table = "engines/detection_table.h.new" 362 363 print("Creating engines/detection_table.h") 364 print("/* This file is automatically generated by configure */\n" \ 365 "/* DO NOT EDIT MANUALLY */\n" \ 366 "// This file is being included by \"base/plugins.cpp\"") > det_table 367 368 for (e = 1; e <= engine_count; e++) { 369 engine = sorted_engines[e] 370 if (get_engine_sub(engine) == "no") { 371 j = toupper(engine) 372 detectEngine = j detectId 373 print("#if defined(ENABLE_" j ") || defined(DETECTION_FULL)\n" \ 374 "LINK_PLUGIN(" j detectId ")\n" \ 375 "#endif") >> det_table 376 } 377 } 378 379 plugins_table = "engines/plugins_table.h.new" 380 print("Creating engines/plugins_table.h") 381 print("/* This file is automatically generated by configure */\n" \ 382 "/* DO NOT EDIT MANUALLY */\n" \ 383 "// This file is being included by \"base/plugins.cpp\"") > plugins_table 384 385 for (e = 1; e <= engine_count; e++) { 386 engine = sorted_engines[e] 387 if (get_engine_sub(engine) == "no") { 388 j = toupper(engine) 389 print("#if PLUGIN_ENABLED_STATIC(" j ")\n" \ 390 "LINK_PLUGIN(" j ")\n" \ 391 "#endif") >> plugins_table 392 } 393 } 394} 395