Skip to content

Commit

Permalink
Fix platform selection, let platforms override custom tools, and obey…
Browse files Browse the repository at this point in the history
… user overrides of use_mingw

Let the platforms optionally override the default build tools with a
`get_custom_tools` method, so the default SConstruct only needs to set the
defaults and not worry about each individual platform requirements.

Fix the order of initialization, so we can pick up the use_mingw option
from all the different places where it can be set, and use it during
environment initialization.

This also fixes a related issue where, if a platform sets a default target
in `get_flags`, if the platform doesn't support the `editor` target, and the user
doesn't pass in the target in the command line, the `editor` target would be
briefly selected during a portion of SConstruct execution, just long enough
for some wrong variables to be set, and cause the build to fail, or include
bad defines.

Fixes godotengine#60719
  • Loading branch information
shana committed Sep 15, 2023
1 parent 88269cf commit d83d113
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 53 deletions.
134 changes: 81 additions & 53 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ platform_apis = []

time_at_start = time.time()

custom_tools = []

for x in sorted(glob.glob("platform/*")):
if not os.path.isdir(x) or not os.path.exists(x + "/detect.py"):
continue
Expand Down Expand Up @@ -103,56 +105,11 @@ for x in sorted(glob.glob("platform/*")):
platform_list += [x]
platform_opts[x] = detect.get_opts()
platform_flags[x] = detect.get_flags()
if hasattr(detect, "get_custom_tools"):
custom_tools = detect.get_custom_tools()
sys.path.remove(tmppath)
sys.modules.pop("detect")

custom_tools = ["default"]

platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))

if platform_arg == "android":
custom_tools = ["clang", "clang++", "as", "ar", "link"]
elif platform_arg == "web":
# Use generic POSIX build toolchain for Emscripten.
custom_tools = ["cc", "c++", "ar", "link", "textfile", "zip"]
elif os.name == "nt" and methods.get_cmdline_bool("use_mingw", False):
custom_tools = ["mingw"]

# We let SCons build its default ENV as it includes OS-specific things which we don't
# want to have to pull in manually.
# Then we prepend PATH to make it take precedence, while preserving SCons' own entries.
env_base = Environment(tools=custom_tools)
env_base.PrependENVPath("PATH", os.getenv("PATH"))
env_base.PrependENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
if "TERM" in os.environ: # Used for colored output.
env_base["ENV"]["TERM"] = os.environ["TERM"]

env_base.disabled_modules = []
env_base.module_version_string = ""
env_base.msvc = False

env_base.__class__.disable_module = methods.disable_module

env_base.__class__.add_module_version_string = methods.add_module_version_string

env_base.__class__.add_source_files = methods.add_source_files
env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix

env_base.__class__.add_shared_library = methods.add_shared_library
env_base.__class__.add_library = methods.add_library
env_base.__class__.add_program = methods.add_program
env_base.__class__.CommandNoCache = methods.CommandNoCache
env_base.__class__.Run = methods.Run
env_base.__class__.disable_warnings = methods.disable_warnings
env_base.__class__.force_optimization_on_debug = methods.force_optimization_on_debug
env_base.__class__.module_add_dependencies = methods.module_add_dependencies
env_base.__class__.module_check_dependencies = methods.module_check_dependencies

env_base["x86_libtheora_opt_gcc"] = False
env_base["x86_libtheora_opt_vc"] = False

# avoid issues when building with different versions of python out of the same directory
env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))

# Build options

Expand Down Expand Up @@ -262,8 +219,25 @@ opts.Add("CFLAGS", "Custom flags for the C compiler")
opts.Add("CXXFLAGS", "Custom flags for the C++ compiler")
opts.Add("LINKFLAGS", "Custom flags for the linker")

# Update the environment to have all above options defined
# in following code (especially platform and custom_modules).

recheck_mingw = False;

# Set default tools, if the platform implementation didn't specify any
if not custom_tools:
custom_tools = ["default"]

if os.name == "nt":
if methods.get_cmdline_bool("use_mingw", False):
custom_tools = ["mingw"]
else:
# At this point we aren't able to check other possible user overrides,
# we'll need an environment for that, so defer the check
recheck_mingw = True

# We let SCons build its default ENV as it includes OS-specific things which we don't
# want to have to pull in manually.
# Then we prepend PATH to make it take precedence, while preserving SCons' own entries.
env_base = Environment(tools=custom_tools)
opts.Update(env_base)

# Platform selection: validate input, and add options.
Expand Down Expand Up @@ -318,9 +292,6 @@ if selected_platform in ["linux", "bsd", "x11"]:
# Alias for convenience.
selected_platform = "linuxbsd"

# Make sure to update this to the found, valid platform as it's used through the buildsystem as the reference.
# It should always be re-set after calling `opts.Update()` otherwise it uses the original input value.
env_base["platform"] = selected_platform

# Add platform-specific options.
if selected_platform in platform_opts:
Expand All @@ -329,7 +300,64 @@ if selected_platform in platform_opts:

# Update the environment to take platform-specific options into account.
opts.Update(env_base)
env_base["platform"] = selected_platform # Must always be re-set after calling opts.Update().

# Make sure to update this to the found, valid platform as it's used through the buildsystem as the reference.
# It should always be re-set after calling `opts.Update()` otherwise it uses the original input value.
env_base["platform"] = selected_platform


# MinGW is a special case, as it's a tool loaded as part of environment initialization
# but we need an environment in order to merge user option
# so we might have to recreate the environment
if recheck_mingw:
if env_base["use_mingw"] or ("use_mingw", False) in platform_flags[selected_platform]:
custom_tools = ["mingw"]
# rebuild the environment with the updated tools and reset everything
env_base = Environment(tools=custom_tools)

# Add platform-specific options.
if selected_platform in platform_opts:
for opt in platform_opts[selected_platform]:
opts.Add(opt)

# Update the environment to take platform-specific options into account.
opts.Update(env_base)
env_base["platform"] = selected_platform # Must always be re-set after calling opts.Update().


# Now we're ready to set our PATHs
env_base.PrependENVPath("PATH", os.getenv("PATH"))
env_base.PrependENVPath("PKG_CONFIG_PATH", os.getenv("PKG_CONFIG_PATH"))
if "TERM" in os.environ: # Used for colored output.
env_base["ENV"]["TERM"] = os.environ["TERM"]

env_base.disabled_modules = []
env_base.module_version_string = ""
env_base.msvc = False

env_base.__class__.disable_module = methods.disable_module

env_base.__class__.add_module_version_string = methods.add_module_version_string

env_base.__class__.add_source_files = methods.add_source_files
env_base.__class__.use_windows_spawn_fix = methods.use_windows_spawn_fix

env_base.__class__.add_shared_library = methods.add_shared_library
env_base.__class__.add_library = methods.add_library
env_base.__class__.add_program = methods.add_program
env_base.__class__.CommandNoCache = methods.CommandNoCache
env_base.__class__.Run = methods.Run
env_base.__class__.disable_warnings = methods.disable_warnings
env_base.__class__.force_optimization_on_debug = methods.force_optimization_on_debug
env_base.__class__.module_add_dependencies = methods.module_add_dependencies
env_base.__class__.module_check_dependencies = methods.module_check_dependencies

env_base["x86_libtheora_opt_gcc"] = False
env_base["x86_libtheora_opt_vc"] = False

# avoid issues when building with different versions of python out of the same directory
env_base.SConsignFile(".sconsign{0}.dblite".format(pickle.HIGHEST_PROTOCOL))


# Detect modules.
modules_detected = OrderedDict()
Expand Down
4 changes: 4 additions & 0 deletions platform/android/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ def get_flags():
]


def get_custom_tools():
return ["clang", "clang++", "as", "ar", "link"]


# Check if Android NDK version is installed
# If not, install it.
def install_ndk_if_needed(env):
Expand Down
5 changes: 5 additions & 0 deletions platform/web/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ def get_flags():
]


def get_custom_tools():
# Use generic POSIX build toolchain for Emscripten.
return ["cc", "c++", "ar", "link", "textfile", "zip"]


def configure(env: "Environment"):
# Validate arch.
supported_arches = ["wasm32"]
Expand Down

0 comments on commit d83d113

Please sign in to comment.