Skip to content

Commit

Permalink
Add Engine.get_build_system_info() to get information about the bui…
Browse files Browse the repository at this point in the history
…ld environment

This returns a Dictionary with the following keys:

- `os_name`
- `compiler_name`
- `compiler_version`
- `optimization_level`
- `optimization_lto`
  • Loading branch information
Calinou committed Dec 4, 2024
1 parent 1f47e4c commit eaf10dc
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 31 deletions.
37 changes: 21 additions & 16 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,17 @@ if env["scu_build"]:

methods.set_scu_folders(scu_builders.generate_scu_files(max_includes_per_scu))

env.using_clang = methods.using_clang(env)
env.is_apple_clang = methods.is_apple_clang(env)
env.using_gcc = methods.using_gcc(env)
env.using_emcc = methods.using_emcc(env)

# Enforce our minimal compiler version requirements
env.compiler_version = methods.get_compiler_version(env)
cc_version_major = env.compiler_version["major"]
cc_version_minor = env.compiler_version["minor"]
cc_version_metadata1 = env.compiler_version["metadata1"]

# Must happen after the flags' definition, as configure is when most flags
# are actually handled to change compile options, etc.
detect.configure(env)
Expand All @@ -632,18 +643,12 @@ print(f'Building for platform "{env["platform"]}", architecture "{env["arch"]}",
if env.dev_build:
print("NOTE: Developer build, with debug optimization level and debug symbols (unless overridden).")

# Enforce our minimal compiler version requirements
cc_version = methods.get_compiler_version(env)
cc_version_major = cc_version["major"]
cc_version_minor = cc_version["minor"]
cc_version_metadata1 = cc_version["metadata1"]

if cc_version_major == -1:
print_warning(
"Couldn't detect compiler version, skipping version checks. "
"Build may fail if the compiler doesn't support C++17 fully."
)
elif methods.using_gcc(env):
elif env.using_gcc:
if cc_version_major < 9:
print_error(
"Detected GCC version older than 9, which does not fully support "
Expand All @@ -660,10 +665,10 @@ elif methods.using_gcc(env):
"to switch to posix threads."
)
Exit(255)
elif methods.using_clang(env):
elif env.using_clang:
# Apple LLVM versions differ from upstream LLVM version \o/, compare
# in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
if methods.is_apple_clang(env):
if env.is_apple_clang:
if cc_version_major < 10:
print_error(
"Detected Apple Clang version older than 10, which does not fully "
Expand Down Expand Up @@ -734,7 +739,7 @@ else:
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
# otherwise addr2line doesn't understand them
env.Append(CCFLAGS=["-gdwarf-4"])
if methods.using_emcc(env):
if env.using_emcc:
# Emscripten only produces dwarf symbols when using "-g3".
env.Append(CCFLAGS=["-g3"])
# Emscripten linker needs debug symbols options too.
Expand All @@ -749,7 +754,7 @@ else:
project_path = Dir("#").abspath
env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
else:
if methods.is_apple_clang(env):
if env.is_apple_clang:
# Apple Clang, its linker doesn't like -s.
env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
else:
Expand Down Expand Up @@ -814,7 +819,7 @@ elif env.msvc:
env.Append(CXXFLAGS=["/EHsc"])

# Configure compiler warnings
if env.msvc and not methods.using_clang(env): # MSVC
if env.msvc and not env.using_clang: # MSVC
if env["warnings"] == "no":
env.Append(CCFLAGS=["/w"])
else:
Expand Down Expand Up @@ -849,15 +854,15 @@ if env.msvc and not methods.using_clang(env): # MSVC
else: # GCC, Clang
common_warnings = []

if methods.using_gcc(env):
if env.using_gcc:
common_warnings += ["-Wshadow", "-Wno-misleading-indentation"]
if cc_version_major < 11:
# Regression in GCC 9/10, spams so much in our variadic templates
# that we need to outright disable it.
common_warnings += ["-Wno-type-limits"]
if cc_version_major >= 12: # False positives in our error macros, see GH-58747.
common_warnings += ["-Wno-return-type"]
elif methods.using_clang(env) or methods.using_emcc(env):
elif env.using_clang or env.using_emcc:
common_warnings += ["-Wshadow-field-in-constructor", "-Wshadow-uncaptured-local"]
# We often implement `operator<` for structs of pointers as a requirement
# for putting them in `Set` or `Map`. We don't mind about unreliable ordering.
Expand All @@ -869,7 +874,7 @@ else: # GCC, Clang
if env["warnings"] == "extra":
env.Append(CCFLAGS=[W_ALL, "-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings)
env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
if methods.using_gcc(env):
if env.using_gcc:
env.Append(
CCFLAGS=[
"-Walloc-zero",
Expand All @@ -886,7 +891,7 @@ else: # GCC, Clang
env.Append(CCFLAGS=["-Wattribute-alias=2"])
if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11.
env.Append(CCFLAGS=["-Wlogical-op"])
elif methods.using_clang(env) or methods.using_emcc(env):
elif env.using_clang or env.using_emcc:
env.Append(CCFLAGS=["-Wimplicit-fallthrough"])
elif env["warnings"] == "all":
env.Append(CCFLAGS=[W_ALL] + common_warnings)
Expand Down
44 changes: 44 additions & 0 deletions core/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,50 @@ gen_hash = env.CommandNoCache(
)
env.add_source_files(env.core_sources, gen_hash)

# Generate buildsystem info
def buildsystem_info_builder(target, source, env):
with methods.generated_wrapper(target) as file:
import platform
os_name = platform.system()
if os_name == "Darwin":
os_name = "macOS"

compiler_name = "unknown"
compiler_version = f"{env.compiler_version['major']}.{env.compiler_version['minor']}.{env.compiler_version['patch']}"
if env.using_gcc:
compiler_name = "gcc"
elif env.using_clang:
if env.is_apple_clang:
compiler_name = "apple-clang"
compiler_version = f"{env.compiler_version['apple_major']}.{env.compiler_version['apple_minor']}.{env.compiler_version['apple_patch1']}.{env.compiler_version['apple_patch2']}.{env.compiler_version['apple_patch3']}"
else:
compiler_name = "clang"
elif env.msvc:
compiler_name = "msvc"
elif env.using_emcc:
compiler_name = "emcc"

file.write(
f"""\
#define BUILDSYSTEM_OS_NAME "{os_name}"
#define BUILDSYSTEM_COMPILER_NAME "{compiler_name}"
#define BUILDSYSTEM_COMPILER_VERSION "{compiler_version}"
#define BUILDSYSTEM_OPTIMIZATION_TYPE "{env["optimize"]}"
#define BUILDSYSTEM_OPTIMIZATION_LTO "{env["lto"]}"
"""
)

env.CommandNoCache("buildsystem.gen.h", env.Value([
os.name,
env.using_gcc,
env.using_clang,
env.is_apple_clang,
env.msvc,
env.using_emcc,
env.compiler_version,
env["optimize"],
env["lto"],
]), env.Run(buildsystem_info_builder))

# Generate AES256 script encryption key
def encryption_key_builder(target, source, env):
Expand Down
12 changes: 12 additions & 0 deletions core/config/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "engine.h"

#include "core/authors.gen.h"
#include "core/buildsystem.gen.h"
#include "core/config/project_settings.h"
#include "core/donors.gen.h"
#include "core/license.gen.h"
Expand Down Expand Up @@ -147,6 +148,17 @@ Dictionary Engine::get_version_info() const {
return dict;
}

Dictionary Engine::get_build_system_info() const {
Dictionary dict;
dict["os_name"] = BUILDSYSTEM_OS_NAME;
dict["compiler_name"] = BUILDSYSTEM_COMPILER_NAME;
dict["compiler_version"] = BUILDSYSTEM_COMPILER_VERSION;
dict["optimization_type"] = BUILDSYSTEM_OPTIMIZATION_TYPE;
dict["optimization_lto"] = BUILDSYSTEM_OPTIMIZATION_LTO;

return dict;
}

static Array array_from_info(const char *const *info_list) {
Array arr;
for (int i = 0; info_list[i] != nullptr; i++) {
Expand Down
1 change: 1 addition & 0 deletions core/config/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class Engine {
#endif

Dictionary get_version_info() const;
Dictionary get_build_system_info() const;
Dictionary get_author_info() const;
TypedArray<Dictionary> get_copyright_info() const;
Dictionary get_donor_info() const;
Expand Down
5 changes: 5 additions & 0 deletions core/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,10 @@ Dictionary Engine::get_version_info() const {
return ::Engine::get_singleton()->get_version_info();
}

Dictionary Engine::get_build_system_info() const {
return ::Engine::get_singleton()->get_build_system_info();
}

Dictionary Engine::get_author_info() const {
return ::Engine::get_singleton()->get_author_info();
}
Expand Down Expand Up @@ -1957,6 +1961,7 @@ void Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_main_loop"), &Engine::get_main_loop);

ClassDB::bind_method(D_METHOD("get_version_info"), &Engine::get_version_info);
ClassDB::bind_method(D_METHOD("get_build_system_info"), &Engine::get_build_system_info);
ClassDB::bind_method(D_METHOD("get_author_info"), &Engine::get_author_info);
ClassDB::bind_method(D_METHOD("get_copyright_info"), &Engine::get_copyright_info);
ClassDB::bind_method(D_METHOD("get_donor_info"), &Engine::get_donor_info);
Expand Down
1 change: 1 addition & 0 deletions core/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ class Engine : public Object {
MainLoop *get_main_loop() const;

Dictionary get_version_info() const;
Dictionary get_build_system_info() const;
Dictionary get_author_info() const;
TypedArray<Dictionary> get_copyright_info() const;
Dictionary get_donor_info() const;
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/Engine.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@
Returns the engine author information as a [Dictionary], where each entry is an [Array] of strings with the names of notable contributors to the Godot Engine: [code]lead_developers[/code], [code]founders[/code], [code]project_managers[/code], and [code]developers[/code].
</description>
</method>
<method name="get_build_system_info" qualifiers="const">
<return type="Dictionary" />
<description>
Returns the build system environment that was used to compile this Godot binary, as a [Dictionary] containing the following entries:
- [code]os_name[/code] - Name of the operating system used to compile Godot, as a string (can differ from the binary's target platform)
- [code]compiler_name[/code] - Compiler name (can be [code]"gcc"[/code], [code]"clang"[/code], [code]"apple-clang"[/code], [code]"msvc"[/code], [code]"emcc"[/code] or [code]"unknown"[/code])
- [code]compiler_version[/code] - Compiler version number, as a string
- [code]optimization_type[/code] - Compiler optimization type (can be [code]"none"[/code], [code]"debug"[/code], [code]"speed_trace"[/code], [code]"speed"[/code], [code]"size"[/code], [code]"custom"[/code])
- [code]optimization_lto[/code] - Link-time optimization level (can be [code]"none"[/code], [code]"thin"[/code], [code]"full"[/code])
See also [method get_version_info].
</description>
</method>
<method name="get_copyright_info" qualifiers="const">
<return type="Dictionary[]" />
<description>
Expand Down Expand Up @@ -188,6 +200,7 @@
}
[/csharp]
[/codeblocks]
See also [method get_build_system_info].
</description>
</method>
<method name="get_write_movie_path" qualifiers="const">
Expand Down
2 changes: 1 addition & 1 deletion drivers/d3d12/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ else:
extra_defines += [
"HAVE_STRUCT_TIMESPEC",
]
if methods.using_gcc(env) and methods.get_compiler_version(env)["major"] < 13:
if env.using_gcc and env.compiler_version["major"] < 13:
# `region` & `endregion` not recognized as valid pragmas.
env_d3d12_rdd.Append(CCFLAGS=["-Wno-unknown-pragmas"])
env.Append(CCFLAGS=["-Wno-unknown-pragmas"])
Expand Down
14 changes: 14 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5034,6 +5034,18 @@ String EditorNode::_get_system_info() const {
driver_name = "Metal";
}

const Dictionary build_system_info = Engine::get_singleton()->get_build_system_info();
String compiler_name = String(build_system_info["compiler_name"]).capitalize();
if (compiler_name == "Gcc") {
compiler_name = "GCC";
} else if (compiler_name == "Msvc") {
compiler_name = "MSVC";
}
String build_system_string = ("Compiled on " + String(build_system_info["os_name"]) +
" with " + compiler_name + " " + String(build_system_info["compiler_version"]) +
", optimization: " + String(build_system_info["optimization_type"]) +
", LTO: " + String(build_system_info["optimization_lto"]));

// Join info.
Vector<String> info;
info.push_back(godot_version);
Expand Down Expand Up @@ -5084,6 +5096,8 @@ String EditorNode::_get_system_info() const {

info.push_back(vformat("%s (%d threads)", processor_name, processor_count));

info.push_back(build_system_string);

return String(" - ").join(info);
}

Expand Down
6 changes: 3 additions & 3 deletions methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def add_source_files(self, sources, files, allow_gen=False):

def disable_warnings(self):
# 'self' is the environment
if self.msvc and not using_clang(self):
if self.msvc and not self.using_clang:
# We have to remove existing warning level defines before appending /w,
# otherwise we get: "warning D9025 : overriding '/W3' with '/w'"
self["CCFLAGS"] = [x for x in self["CCFLAGS"] if not (x.startswith("/W") or x.startswith("/w"))]
Expand Down Expand Up @@ -658,7 +658,7 @@ def detect_darwin_sdk_path(platform, env):
def is_apple_clang(env):
if env["platform"] not in ["macos", "ios"]:
return False
if not using_clang(env):
if not env.using_clang:
return False
try:
version = subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip().decode("utf-8")
Expand Down Expand Up @@ -690,7 +690,7 @@ def get_compiler_version(env):
"apple_patch3": -1,
}

if env.msvc and not using_clang(env):
if env.msvc and not env.using_clang:
try:
# FIXME: `-latest` works for most cases, but there are edge-cases where this would
# benefit from a more nuanced search.
Expand Down
5 changes: 2 additions & 3 deletions platform/linuxbsd/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from typing import TYPE_CHECKING

from methods import get_compiler_version, print_error, print_warning, using_gcc
from methods import print_error, print_warning, using_gcc
from platform_methods import detect_arch, validate_arch

if TYPE_CHECKING:
Expand Down Expand Up @@ -113,8 +113,7 @@ def configure(env: "SConsEnvironment"):
if env["linker"] != "default":
print("Using linker program: " + env["linker"])
if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold.
cc_version = get_compiler_version(env)
cc_semver = (cc_version["major"], cc_version["minor"])
cc_semver = (env.compiler_version["major"], env.compiler_version["minor"])
if cc_semver < (12, 1):
found_wrapper = False
for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]:
Expand Down
9 changes: 4 additions & 5 deletions platform/macos/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import sys
from typing import TYPE_CHECKING

from methods import detect_darwin_sdk_path, get_compiler_version, is_apple_clang, print_error, print_warning
from methods import detect_darwin_sdk_path, print_error, print_warning
from platform_methods import detect_arch, detect_mvk, validate_arch

if TYPE_CHECKING:
Expand Down Expand Up @@ -98,12 +98,11 @@ def configure(env: "SConsEnvironment"):

env.Append(CCFLAGS=["-ffp-contract=off"])

cc_version = get_compiler_version(env)
cc_version_major = cc_version["apple_major"]
cc_version_minor = cc_version["apple_minor"]
cc_version_major = env.compiler_version["apple_major"]
cc_version_minor = env.compiler_version["apple_minor"]

# Workaround for Xcode 15 linker bug.
if is_apple_clang(env) and cc_version_major == 1500 and cc_version_minor == 0:
if env.is_apple_clang and cc_version_major == 1500 and cc_version_minor == 0:
env.Prepend(LINKFLAGS=["-ld_classic"])

env.Append(CCFLAGS=["-fobjc-arc"])
Expand Down
5 changes: 2 additions & 3 deletions platform/web/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)
from SCons.Util import WhereIs

from methods import get_compiler_version, print_error, print_warning
from methods import print_error, print_warning
from platform_methods import validate_arch

if TYPE_CHECKING:
Expand Down Expand Up @@ -192,8 +192,7 @@ def configure(env: "SConsEnvironment"):
env["LIBSUFFIXES"] = ["$LIBSUFFIX"]

# Get version info for checks below.
cc_version = get_compiler_version(env)
cc_semver = (cc_version["major"], cc_version["minor"], cc_version["patch"])
cc_semver = (env.compiler_version["major"], env.compiler_version["minor"], env.compiler_version["patch"])

# Minimum emscripten requirements.
if cc_semver < (3, 1, 62):
Expand Down

0 comments on commit eaf10dc

Please sign in to comment.