-
-
Notifications
You must be signed in to change notification settings - Fork 21.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SCons: Disable C++ exception handling #80612
SCons: Disable C++ exception handling #80612
Conversation
d0893e1
to
7b12c55
Compare
7b12c55
to
3487c54
Compare
3487c54
to
bff7893
Compare
This comment was marked as resolved.
This comment was marked as resolved.
bff7893
to
be36f1c
Compare
be36f1c
to
6d269a8
Compare
We were already defining Also removed the |
# Increase number of addressable sections in object files | ||
# due to doctest's heavy use of templates and macros. | ||
if env_tests.msvc: | ||
env_tests.Append(CCFLAGS=["/bigobj"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was redundant with platform/windows/detect.py
, hence the removal.
I see that too, but I'm surprised, as I thought
I was wondering whether it's needed. I'm not so familiar with MSVC, but it seems like exception handling is enabled by default (and can only be overridden with
Edit: Well both issues seem to come from compiling OIDN, so it shows OIDN does want |
Upon investigating the extremely slow MSVC build times in godotengine#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.
6d269a8
to
3907e53
Compare
Re-added |
Tested this: Editor:
Release template:
So these options seem to have a significant impact to further decrease the binary size, at the cost of (somewhat surprisingly?) increasing build times. Might be an interesting tradeoff to explore for official production builds, though I'll leave that for a separate issue/PR. Edit: Doing some more tests, I'm seeing wild variations in build times on the build server where I did those tests, so the above time comparisons might not be accurate. So it may well be that |
I'm seeing mentions of these "unwind tables" potentially affecting stacktrace generation as well, so might be worth checking to see that any such things in Godot are still working as expected, if applicable. |
Indeed, I would enable this only when using Currently we build everything with Either way, we're not there yet and this is for future work. |
Note to self, or Yuri: Worth cherrypicking IMO, but we might want to make |
Cherry-picked for 4.1.2. Disabled by default, as suggested. |
Counterpart to godotengine/godot#80612. (cherry picked from commit bf1c03a)
Counterpart to godotengine/godot#80612. (cherry picked from commit bf1c03a)
Counterpart to godotengine/godot#80612. (cherry picked from commit bf1c03a)
We made a mistake when cherry-picking godotengine#80612 with 269b115, where the global flag was defaulted to false to preserve the 4.1-stable behavior for desktop platforms, but we forgot that the refactoring removed the force disabling of exceptions for Android, iOS, and Web. This reintroduces this behavior so it should be back to the same as in 4.1/4.1.1, and the export templates should get back to their original size. Only difference, the old code used to keep exceptions for the Web editor, but I see no reason for it, so I disable them like with the templates.
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:
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.Alternative to #80516.
Fixes #80513.
Could be considered for a
4.1
cherry-pick, but this will require significant testing to make sure it behaves as expected, and it may be a welcome but surprising change for existing 4.1.x users, so we might opt for not including it.Test builds
Edit: New test builds for all platforms made with the official buildsystem: https://downloads.tuxfamily.org/godotengine/testing/4.2-dev-pr80612/
To help validate this PR, I've done some builds of the before and after states (from this PR, so on top of 0308422), for Linux (GCC on our official buildsystem) and Windows (VS 2022 on my laptop, unsigned).
You'll find zips here:
https://downloads.tuxfamily.org/godotengine/testing/4.2.dev.no-exceptions/
Linux builds
exceptions
are the same as we currently use for official builds, andno-exceptions
use the new option to disable exception handling.OIDN is special cased as I couldn't disable exception handling for it yet, so the
with-oidn
builds actually still have exceptions enabled for OIDN's build environment only.without-oidn
builds were made withmodule_denoise_enabled=no
. It's an editor-only dependency so it doesn't affect the template build.I didn't include the
without-oidn
builds in the above ZIPs to save your bandwidth, I mostly build them to see the impact on size and build time.These builds were made on the official buildsystem with the same options as official releases, so with full optimizations and LTO enabled (
scons p=linuxbsd target=editor warnings=no production=yes
)Windows builds
Impact on size
As seen above, for Linux builds with GCC 10, we get a 16% size reduction for the editor build (or said otherwise, enabling exceptions added 20% size), and a similar ratio for the release template.
With LTO disabled, both build types are around 3M bigger, so the ratio doesn't change much.
Dev build: 758M to 736M on Linux, so 3% size reduction. Less than I expected.
On Windows, there's a similar 15% size reduction for the editor build, and only 5% size reduction for the release template (but it was already significantly smaller than the Linux one, now they have a comparable size).
Impact on compile time
Linux with GCC 10
Production builds with LTO enabled.
scons p=linuxbsd target=editor warnings=no production=yes
The differences aren't huge, because LTO still takes a while, and it seems like having to compile OIDN with exceptions enabled adds a whole minute to the build time.
If we compare the builds without OIDN, there's a 13% build time reduction for the editor, and a 26% build time reduction for the release template.
Builds without LTO enabled.
no-lto
isscons p=linuxbsd target=editor warnings=no
, whiledev-build
isscons p=linuxbsd target=editor dev_build=yes
.For an optimized build without LTO (so not paying a disproportionate amount of time for linking), there's a significant 25% build time speedup.
For the dev builds, I actually got a 2% build time increase, though I don't know if it's representative, I ran the test only once.
Sizes for these builds for those interested:
Windows with MSVC from VS 2022
I used
scu_build
to speed things up, so this exacerbates issues like #80513 since the parallel build goes faster, but we'll still get stuck a long time ongdscript_vm.cpp
for theexceptions
build.The results are pretty impressive though, with the build time divided by 3 for the editor (34m to 12m) and divided by 2 for the template (19m to 9m).
Impact on performance
Help welcome to run some benchmarks! You can use the builds linked above.
Impact on tests
I had to disable exceptions in doctest, which downgrades our
REQUIRE
/FAIL
macros to theCHECK
level (which marks the test as failed but doesn't rage quit). We need to see if that impacts our test suites negatively, and if we should clarify this behavior by changing our existingREQUIRE
/FAIL
uses toCHECK
.This is work for a follow-up PR where I'd welcome a volunteer - for this PR we should just ensure that the tests still work properly.
Further work
godot-cpp
could likely reuse the same logic to build without extensions by default, with a command line option to override that behavior for users who want to compile with a library that needs exceptions (or their own code).3.x
backport: #80622