With this option turned on, if properly set up, SCons generates a
`build.ninja` file and quits. To actually build the engine, the user can
then call `ninja` with whatever options they might prefer (not
everything is yet transferred properly to this new generated file).
Ideally, the scons file should never be called again, as ninja
automatically detects any SCons build script change and invokes
the required commands to regenerate itself.
This approach speeds up incremental builds considerably, as it limits
SCons to code generation and uses ninja's extremely fast timestamp-based
file change detector.
SConscript("some SCsub path") calls create a new context where a relative path
to the .sconsign file is interpreted as being next to the currently executing
SCsub, and not the one at the root. This breaks incremental build detection
because scons can't find the build information of dependent files outside of the
SCsub directory and just rebuilds everything every time.
Custom Visual Studio project generation logic that supports any platform that has a msvs.py
script, so Visual Studio can be used to run scons for any platform, with the right defines per target.
Invoked with `scons vsproj=yes`
To generate build configuration files for all platforms+targets+arch combinations, users should call
```
scons vsproj=yes platform=XXX target=YYY [other build flags]
```
for each combination of platform+target[+arch]. This will generate the relevant vs project files but
skip the build process, so that project files can be quickly generated without waiting for a command line
build. This lets project files be quickly generated even if there are build errors.
All possible combinations of platform+target are created in the solution file by default, but they
won't do anything until each one is set up with a scons vsproj=yes command for the respective platform
in the appropriate command line. This lets users only generate the combinations they need, and VS
won't have to parse settings for other combos.
Only platforms that opt in to vs proj generation by having a msvs.py file in the platform folder are included.
Platforms with a msvs.py file will be added to the solution, but only the current active platform+target+arch
will have a build configuration generated, because we only know what the right defines/includes/flags/etc are
on the active build target currently being processed by scons.
Platforms that don't support an editor target will have a dummy editor target that won't do anything on build,
but will have the files and configuration for the windows editor target.
To generate AND build from the command line, run
```
scons vsproj=yes vsproj_gen_only=no
```
This allows custom environment variables to be used during the build,
which is useful when using alternative compilation tools such as caches
and distributed build systems.
This is useful to speed up iteration when working on the engine
(or editor).
This can be combined with a script that calls `adb` to deploy the APK
on a device (coupled with Godot's `--export-*` for projects)
to further speed up iteration.
Verbose output is meant for debugging the SCU mode itself and can be
triggered by changing the `_verbose` bool manually.
Prefix all prints with "SCU:" for context, and print the processed
folders all at once instead of when adding the sources.
Add `object_prefix` as an scons option to add a custom prefix to
all generated object files, via the `OBJPREFIX` and `SHOBJPREFIX`
environment variables.
This is useful for instance to hide object files on unix-like
systems and make the source directories less cluttered by
setting `object_prefix = '.'` in `custom.py`.
Upon investigating the extremely slow MSVC build times in #80513, I noticed
that while Godot policy is to never use exceptions, we weren't enforcing it
with compiler flags, and thus still included exception handling code and
stack unwinding.
This is wasteful on multiple aspects:
- Binary size: Around 20% binary size reduction with exceptions disabled
for both MSVC and GCC binaries.
- Compile time:
* More than 50% build time reduction with MSVC.
* 10% to 25% build time reduction with GCC + LTO.
- Performance: Possibly, needs to be benchmarked.
Since users may want to re-enable exceptions in their own thirdparty code
or the libraries they compile with Godot, this behavior can be toggled with
the `disable_exceptions` SCons option, which defaults to true.
"scu_limit" allows specifying the maximum number of includes in a single SCU file (translation unit). A lower limit (e.g. 8) uses less RAM during compilation, but may be slower to compile.
Follow-up to #75932.
Since these icons are only used by the export plugin, it makes sense to
move them and generate the headers there.
The whole `detect.is_active()` logic seems to be a leftover from before
times, as far back as 1.0-stable it already wasn't used for anything.
So I'm removing it and moving the export icon generation to
`platform_methods`, where it makes more sense.
Adds a new OS::get_system_ca_certs method which can be implemented by
platforms to retrieve the list of trusted CA certificates using OS
specific APIs.
The function should return the certificates in PEM format, and is
currently implemented for Windows/macOS/LinuxBSD(*)/Android.
mbedTLS will fall back to bundled certificates when the OS returns no
certificates.
(*) LinuxBSD does not have a standardized certificates store location.
The current implementation will test for common locations and may
return an empty string on some distributions (falling back to the
bundled certificates).
- Use -gdwarf-4 to support both LLVM and GCC when calling addr2line
- Subtract position-independant execuable relocation when passing the
address to addr2line
This is equivalent to calling `strip` on the resulting binary, which is what
we do for official builds.
This applies for GCC/Clang.
For MSVC `/DEBUG:NONE` should already be the default.
Replace all TODO uses of `#warning` by proper TODO comments, and will open
matching bug reports to keep track of them.
We don't have a great track record fixing TODOs, but I'd wager we're even
worse for fixing these "TODO #warning" so we should prohibit this usage.
- Outright disable spammy warnings due to past or present GCC bugs:
* `-Wno-strict-overflow` for GCC 7.
* `-Wno-type-limits` for GCC before 11 (regressed in 9/10, might work in
earlier releases but at this stage we don't care).
* `-Wno-return-type` for GCC 12/13 (regression, still not fixed).
- Enable extra warnings conditionally when broken on earlier GCC:
* `-Wnoexcept` was removed due to an upstream regression in GCC 9, could
be re-enabled (but commented out for now as we actually have `-Wnoexcept`
warnings to fix.
* `-Wlogical-op` was broken on our variadic templates before GCC 11, now
seems fine.
Mainly:
- Make `max_descriptors_per_pool` project setting Vulkan-specific.
- Use a common, render driver agnostic magic FourCC for shader binary data.
- Downgrade spirv_reflect to Vulkan-only dependency.
- Add a `RENDER_DRIVER_*` macro to GLSL shader code for per-driver customizations.
Implements https://github.com/godotengine/godot-proposals/issues/3371.
New `target` presets
====================
The `tools` option is removed and `target` changes to use three new presets,
which match the builds users are familiar with. These targets control the
default optimization level and enable editor-specific and debugging code:
- `editor`: Replaces `tools=yes target=release_debug`.
* Defines: `TOOLS_ENABLED`, `DEBUG_ENABLED`, `-O2`/`/O2`
- `template_debug`: Replaces `tools=no target=release_debug`.
* Defines: `DEBUG_ENABLED`, `-O2`/`/O2`
- `template_release`: Replaces `tools=no target=release`.
* Defines: `-O3`/`/O2`
New `dev_build` option
======================
The previous `target=debug` is now replaced by a separate `dev_build=yes`
option, which can be used in combination with either of the three targets,
and changes the following:
- `dev_build`: Defines `DEV_ENABLED`, disables optimization (`-O0`/`/0d`),
enables generating debug symbols, does not define `NDEBUG` so `assert()`
works in thirdparty libraries, adds a `.dev` suffix to the binary name.
Note: Unlike previously, `dev_build` defaults to off so that users who
compile Godot from source get an optimized and small build by default.
Engine contributors should now set `dev_build=yes` in their build scripts or
IDE configuration manually.
Changed binary names
====================
The name of generated binaries and object files are changed too, to follow
this format:
`godot.<platform>.<target>[.dev][.double].<arch>[.<extra_suffix>][.<ext>]`
For example:
- `godot.linuxbsd.editor.dev.arm64`
- `godot.windows.template_release.double.x86_64.mono.exe`
Be sure to update your links/scripts/IDE config accordingly.
More flexible `optimize` and `debug_symbols` options
====================================================
The optimization level and whether to generate debug symbols can be further
specified with the `optimize` and `debug_symbols` options. So the default
values listed above for the various `target` and `dev_build` combinations
are indicative and can be replaced when compiling, e.g.:
`scons p=linuxbsd target=template_debug dev_build=yes optimize=debug`
will make a "debug" export template with dev-only code enabled, `-Og`
optimization level for GCC/Clang, and debug symbols. Perfect for debugging
complex crashes at runtime in an exported project.
- `_DEBUG` is MSVC specific so it didn't make much sense to define for
Android and iOS builds.
- iOS was the only platform to define `DEBUG`. We don't use it anywhere
outside thirdparty code, which we usually don't intend to debug, so it
seems better to be consistent with other platforms.
- Consistently define `NDEBUG` to disable assert behavior in both `release`
and `release_debug` targets. This used to be set for `release` for all
platforms, and `release_debug` for Android and iOS only.
- Due to the above, I removed the only use we made of `assert()` in Godot
code, which was only implemented for Unix anyway, should have been
`DEV_ENABLED`, and is in PoolAllocator which we don't actually use.
- The denoise and recast modules keep defining `NDEBUG` even for the `debug`
target as we don't want OIDN and Embree asserting all over the place.
This makes it possible to retrieve all relevant versioning info used to
generate `core/version_generated.gen.h` in the buildsystem.
Notably it makes the custom logic parsing the `GODOT_VERSION_STATUS`
environment variable to override status easy to reuse.
Adds support for LTO on macOS and Android. We don't have much experience
with LTO on these platforms so for now we keep it disabled by default
even when `production=yes` is set.
Similarly for iOS where we ship object files for the user to link in
Xcode so LTO makes builds extremely slow to link.
`production=yes` defaults to full LTO.
ThinLTO is much faster for LLVM-based compilers but seems to produce
bigger binaries (at least for the Web platform).
Modules can now call:
env.module_add_dependencies(name: str, deps: list, optional: bool)
To add required or optional dependencies during the "can_build" step.
Required dependencies will be checked and the module will be not be
enabled when they are missing, printing a warning to notify the user.
Adds SCons options to disable Brotli and Graphite.
Adds option categories to the build profiles editor.
Adds options default state to the build profiles editor.
Adds Text Server related options to the build profiles editor.
Fix misplaced OpenGL/Vulkan SCons options.
This PR is a continuation of #50381 (which was implemented exactly a year ago!)
* Add a visual interface to select which classes should not be built into Godot (well, they are built if something else uses them, but if not used the optimizer will remove them out).
* Add a detection system to scan the project and figure out the actual classes used.
* Added the ability for SCons to load build profiles.
Obligatory Screen:
A simple test with a couple of nodes in the scene resulted in a 25% reduction for the final binary size
TODO:
* Script languages need to implement used class detection (left for another PR).
* Options to disable servers or server functionalities (like 2D or 3D physics, navigation, etc). Are missing, that should also greatly aid in reducing binary size.
* Options to disable some modules would be desired.
* More options to disable drivers (OpenGL, Vulkan, etc) would be desired.
In general this PR is a starting point for more contributors to improve and enhance this functionality.
This doesn't change the behavior when `--jobs`/`-j` is specified as a
command-line argument or in `SCONSFLAGS`.
The SCons hack used to know if `num_jobs` was set by the user is derived
from the MongoDB setup.
We use `os.cpu_count()` for portability (available since Python 3.4).
With 4 CPUs or less, we use the max. With more than 4 we use max - 1 to
preserve some bandwidth for the user's other programs.
We shouldn't presume that future compilers will not have false positives or
find new occurrences of this warning, which would break compiling old versions
of the engine without passing custom `CXXFLAGS`.
Follow-up to #60652.
SConstruct change also makes it possible to outright delete the `editor`
folder in a `tools=no` build, which we use in CI to ensure no invalid
cross-dependencies are added.