SCons: Properly handle overriding default values to bool options

The `dev=yes` and `production=yes` options work as aliases to set a number of
options, while still aiming to allow overriding specific options if the user
wishes so. (E.g. `production=yes use_lto=no` should work to enable production
defaults *but* disable LTO.)

That wasn't working as `ARGUMENTS.get()` returns a string and not a boolean as
expected by `BoolVariable`, and this wasn't flagged as a bug... So added a
helper method using SCons' `BoolVariable._text2bool` to do the conversion
manually.
This commit is contained in:
Rémi Verschelde 2021-02-24 10:05:30 +01:00
parent e254715e79
commit b97ef35585
2 changed files with 23 additions and 10 deletions

View file

@ -55,7 +55,7 @@ custom_tools = ["default"]
platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False)) platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
if os.name == "nt" and (platform_arg == "android" or ARGUMENTS.get("use_mingw", False)): if os.name == "nt" and (platform_arg == "android" or methods.get_cmdline_bool("use_mingw", False)):
custom_tools = ["mingw"] custom_tools = ["mingw"]
elif platform_arg == "javascript": elif platform_arg == "javascript":
# Use generic POSIX build toolchain for Emscripten. # Use generic POSIX build toolchain for Emscripten.
@ -95,7 +95,7 @@ env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))
customs = ["custom.py"] customs = ["custom.py"]
profile = ARGUMENTS.get("profile", False) profile = methods.get_cmdline_bool("profile", False)
if profile: if profile:
if os.path.isfile(profile): if os.path.isfile(profile):
customs.append(profile) customs.append(profile)
@ -325,17 +325,17 @@ if selected_platform in platform_list:
env.Alias("compiledb", env.CompilationDatabase()) env.Alias("compiledb", env.CompilationDatabase())
# 'dev' and 'production' are aliases to set default options if they haven't been set # 'dev' and 'production' are aliases to set default options if they haven't been set
# manually by the user. We use `ARGUMENTS.get()` to check if they were manually set. # manually by the user.
if env["dev"]: if env["dev"]:
env["verbose"] = ARGUMENTS.get("verbose", True) env["verbose"] = methods.get_cmdline_bool("verbose", True)
env["warnings"] = ARGUMENTS.get("warnings", "extra") env["warnings"] = ARGUMENTS.get("warnings", "extra")
env["werror"] = ARGUMENTS.get("werror", True) env["werror"] = methods.get_cmdline_bool("werror", True)
if env["tools"]: if env["tools"]:
env["tests"] = ARGUMENTS.get("tests", True) env["tests"] = methods.get_cmdline_bool("tests", True)
if env["production"]: if env["production"]:
env["use_static_cpp"] = ARGUMENTS.get("use_static_cpp", True) env["use_static_cpp"] = methods.get_cmdline_bool("use_static_cpp", True)
env["use_lto"] = ARGUMENTS.get("use_lto", True) env["use_lto"] = methods.get_cmdline_bool("use_lto", True)
env["debug_symbols"] = ARGUMENTS.get("debug_symbols", False) env["debug_symbols"] = methods.get_cmdline_bool("debug_symbols", False)
if not env["tools"] and env["target"] == "debug": if not env["tools"] and env["target"] == "debug":
print( print(
"WARNING: Requested `production` build with `tools=no target=debug`, " "WARNING: Requested `production` build with `tools=no target=debug`, "

View file

@ -6,9 +6,11 @@ from collections import OrderedDict
# We need to define our own `Action` method to control the verbosity of output # We need to define our own `Action` method to control the verbosity of output
# and whenever we need to run those commands in a subprocess on some platforms. # and whenever we need to run those commands in a subprocess on some platforms.
from SCons.Script import Action
from SCons import Node from SCons import Node
from SCons.Script import Action
from SCons.Script import ARGUMENTS
from SCons.Script import Glob from SCons.Script import Glob
from SCons.Variables.BoolVariable import _text2bool
from platform_methods import run_in_subprocess from platform_methods import run_in_subprocess
@ -145,6 +147,17 @@ def parse_cg_file(fname, uniforms, sizes, conditionals):
fs.close() fs.close()
def get_cmdline_bool(option, default):
"""We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
"""
cmdline_val = ARGUMENTS.get(option)
if cmdline_val is not None:
return _text2bool(cmdline_val)
else:
return default
def detect_modules(search_path, recursive=False): def detect_modules(search_path, recursive=False):
"""Detects and collects a list of C++ modules at specified path """Detects and collects a list of C++ modules at specified path