SCons: Remove transitive includes in libc++#111767
SCons: Remove transitive includes in libc++#111767Repiteo merged 1 commit intogodotengine:masterfrom
libc++#111767Conversation
12b1a1b to
97562b1
Compare
There was a problem hiding this comment.
When preparing #111557, I initially wanted to go for a SConstruct based approach as well.
However, I got caught up on 2 problems:
- I don't know an easy way to query the build system whether
libc++is in use. - Editing
SConstructalso affects thirdparty libraries, some of which break.
It seems like you've run into both as well, and decided to tackle them instead.
Your approach should work everywhere, but ends up a bit more complicated than #111557, and has to make some 'educated guesses' about when libc++ is used.
My approach (changing typedefs.h) is stupid simple. But it doesn't help in all compile units (depending on include order), and comes with a small risk of unexpected missing includes in headers, depending on include order of the compile unit.
I'd be fine with choosing either. Maybe time for more people to weigh in?
Ivorforce
left a comment
There was a problem hiding this comment.
Overall, after thinking about it some more, I think i prefer your approach.
But maybe we can simplify it some more?
Instead of patching 3rd party libraries, can we just selectively disable _LIBCPP_REMOVE_TRANSITIVE_INCLUDES on those that don't support it? That seems easier to maintain.
SConstruct
Outdated
| env.AppendUnique(CCFLAGS=["-fansi-escape-codes"]) | ||
|
|
||
| # Reduce transitive includes. | ||
| if (methods.using_clang(env) and not env.msvc) or methods.using_emcc(env) or "-stdlib=libc++" in env["CXXFLAGS"]: |
There was a problem hiding this comment.
How sure are we that this works and won't break?
I suppose the worst that happens if it's wrong is that we don't save on compile time, or define a useless macro. But still, it feels a little weird to hardcode this.
There was a problem hiding this comment.
Yeah, I suppose it isn't an absolute guarantee. The only certainty is msvc will NOT support this.
I'll just add the define universally then
There was a problem hiding this comment.
Makes sense to me. Unless long compile commands are a problem, I don't see an actual downside to this.
methods.py
Outdated
| if "_LIBCPP_REMOVE_TRANSITIVE_INCLUDES" in self["CPPDEFINES"]: | ||
| self["CPPDEFINES"] = [x for x in self["CPPDEFINES"] if x != "_LIBCPP_REMOVE_TRANSITIVE_INCLUDES"] |
There was a problem hiding this comment.
Why remove the flag when warnings are disabled?
There was a problem hiding this comment.
disable_warnings is a bit of a misnomer; it's more "prepare thirdparty libraries". That is: this would disable the define for compiled thirdparty code
97562b1 to
5f6082c
Compare
|
Got this simplified, albeit in the other direction. That is: instead of directly excluding |
Ivorforce
left a comment
There was a problem hiding this comment.
Would it be possible to disable / remove the macro from the libraries that error instead of adding patches?
|
Only partially. That's what the |
Makes sense. // "thirdparty/jolt/wrapper.h
// _LIBCPP_REMOVE_TRANSITIVE_INCLUDES fixes
#include <type_traits>
#include "thirdparty/jolt_physics/Jolt/Core/Core.h"
We'd include this file instead of Sorry about being so picky about this. But I'm thinking, this is 'just' a build performance PR after all. I'd feel a lot more comfortable if we could find a way to introduce the macro without increasing our maintenance cost / risk of future build failures with these libraries. |
5f6082c to
83f1008
Compare
|
If Jolt in particular is a hangup, we could always hold out for an upstream sync where the change is already in place. Otherwise it'd mean editing a lot of files for a wrapper that'd be redundant not too long after More likely you're just wanting to cover your bases about not causing potential breakage. To that end, I just added a new SCons flag: |
Yes, I mainly wouldn't want this optimization to cause problems or maintenance effort down the line. The Jolt example above was just serving as an example to explain a possible alternative to the patches. |
821b5e8 to
aa7ffce
Compare
There was a problem hiding this comment.
Turns out 0005-msvc-include-ctype.patch was excluded from the thirdparty README, likely from sharing the 0005 prefix and being erroneously excluded in a rebase. Given it's already just adding a header, I consolidated it into this new patch file
aa7ffce to
ad02128
Compare
There was a problem hiding this comment.
I tested this change and it compiled successfully, ~10% faster than master.
Code looks good to me now. I appreciate simplifying the implementation to this level!
I really hope that this won't cause too many issues down the line (I can imagine there will be a few), but the 10% compile time boost is worth it in my opinion.
If it ends up being too frail in practice, we could switch to transitive libc++ by default, and support non-transitive on a best-effort basis.
(I'm actually surprised at how few patches are required to get this working. I would have fully expected we'd need to disable this optimization for 3rd party libs.)
akien-mga
left a comment
There was a problem hiding this comment.
Seems fine.
Could you propose these changes upstream to the various libraries patched here? So hopefully they get merged and we can drop our patches eventually.
libc++by defining_LIBCPP_REMOVE_TRANSITIVE_INCLUDESintypedefs.h. #111557I really like the idea of the above PR, but the implementation via
typedefs.hwould be inconsistent. It relies on all stdlib headers being defined after this header, which is unlikely when it's usually sorted so late in header chains & isn't a universal include for our repo. In order to guarantee this is applied for ALL scripts equally, the define is setup via SCons instead.While this does the trick of catching overlooked cases early, that's proving to be a bit of a double-edged sword. Most notably: some thirdparty headers are caught in the crossfire, which I'll be gradually cleaning up over the next few days. This implementation currently excludes thirdparty compilation files, but could be expanded to include them as well, given we're already having to touch thirdparty code to some extent.