-
Notifications
You must be signed in to change notification settings - Fork 37.7k
[build] Make --enable-debug pick better options #12695
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
Conversation
Good catch! Concept ACK Just wanted to add that I've noticed a lot of high quality contributions from you recently. Really nice to have you on board! Thanks for your contributions! |
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.
Concept ACK, but let's do a bit of cleanup while we're at it.
I assume these were added before we started properly checking flags. The "GCC" thing probably just dumps "cc --version | grep Free Software Foundation" like lots of other tools.
I'm not sure how portable "-g3" is, and we actually want to be using "-Og" these days instead of "-O0" if possible. We should be checking flags explicitly.
Also, while we're at it, this is one of the handful of remaining checks that taints the global CPPFLAGS/CXXFLAGS.
AX_CHECK_COMPILE_FLAG([-Og],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -Og"]],,[[$CXXFLAG_WERROR]])
AX_CHECK_COMPILE_FLAG([-g3],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -g3"]],,[[$CXXFLAG_WERROR]])
AX_CHECK_PREPROC_FLAG([-DDEBUG],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG"]],,[[$CXXFLAG_WERROR]])
AX_CHECK_PREPROC_FLAG([-DDEBUG_LOCKORDER],[[DEBUG_CPPFLAGS="$DEBUG_CPPFLAGS -DDEBUG_LOCKORDER"]],,[[$CXXFLAG_WERROR]])
The CFLAGS line can simply be dropped.
(The above doesn't attempt any fallback in case of failed -Og/-g3, but ideally they would fall back to -O0/-g respectively.)
Then at the end of configure.ac, AC_SUBST(DEBUG_CPPFLAGS) and AC_SUBST(DEBUG_CXXFLAGS), and finally add the respective flags to AM_CXXFLAGS/AM_CPPFLAGS in src/Makefile.am.
Question: do we want to have conditional logic based on GCC vs. Clang, or just do what's best for GCC (as long as it doesn't break Clang)? It seems like if we want to have the best symbols for both we need some additional logic here. GCC:
Clang:
So it seems like "-g -Og" works on both compilers, but for Clang "-g -O0" is actually better. The |
Also FYI later I plan to submit another PR for you to review to clean up the logic we have to start using more of the newer AX_* macros, most notably AX_APPEND_COMPILE_FLAGS which will clean up a lot of copy/paste logic we have when we check a flag and then append it.[1] I'm going to do that as another PR because I want to separate changes that affect logic (like this PR) with changes that are just cleanups. |
Summary of recent commits:
|
configure.ac
Outdated
AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ | ||
AX_CHECK_PREPROC_FLAG([-U_FORTIFY_SOURCE],[ | ||
HARDENED_CPPFLAGS="$HARDENED_CPPFLAGS -U_FORTIFY_SOURCE" | ||
dnl -D_FORTIFY_SOURCE=1 and 2 incompatible with -O0 |
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 should be automatically detected where necessary (where it would otherwise be warning) if we turn warnings into errors by passing $CXXFLAG_WERROR as the last argument to AX_CHECK_PREPROC_FLAG.
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.
Clever, good idea.
Nice investigative work above! Generally we don't want to make any assumptions about what compiler will be used, unless an option is known to directly conflict between common ones. I don't think that's the case here. The code also builds fine with msvc, and I'd hope that icc works as well. So checks like this really don't make much sense because they're basically just hard-coded: if test $CLANG -eq 1; then
AX_CHECK_COMPILE_FLAG([-O0],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]])
... Let's try instead to come up with some universal checks that can be applied. A few more little things gleaned from glancing at the gcc/clang code:
For the most part, debugging with -O0 is huge overkill due to all of the inlining, so it makes sense to me that gcc/clang chose -O1 as the starting point for debugging. I think we should use the flags that declare intent, as opposed to trying to guess about optimization levels. That way we benefit more from future compiler versions. So my preference would be:
We could either nest the fallbacks in the original check's failure condition, or just set a variable if the original check fails, and try the fallback if it's false. My slight preference would be for the latter, just because it's more readable. |
Changes here:
There's one other change here that I would like @luke-jr to review. In 9b4e03b he added logic to first try to undefined the flag before setting it. Since we now pass in the debug/error flags, if the -D_FORTIFY_SOURCE=2 check fails I retry with the undefine change. This should mean that if you use --enable-werror the right thing will happen if just setting -D_FORTIFY_SOURCE=2 warns unless it's first undefined. I don't have a compiler that warns in this case, and I'd like Luke to check if he thinks this makes sense. Also note that the _FORTIFY_SOURCE change is a lot less necessary in the first place now since the original error was related to -O0, and we're now preferring -Og (and the warning was a GCC thing in the first place). We could just drop the _FORTIFY_SOURCE change altogether since the logic is a bit confusing; that said, the new logic I added seems a little bit better. |
configure.ac
Outdated
@@ -592,12 +601,16 @@ if test x$use_hardening != xno; then | |||
AX_CHECK_COMPILE_FLAG([-Wstack-protector],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) | |||
AX_CHECK_COMPILE_FLAG([-fstack-protector-all],[HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) | |||
|
|||
AX_CHECK_PREPROC_FLAG([-D_FORTIFY_SOURCE=2],[ |
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.
I'd rather not reverse this logic as it now completely depends on -Werror working as intended. If some compiler fails to warn about the redefine, we'd get the wrong behavior here.
With the current logic, we always undefine and redefine as long as the options work individually.
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.
OK, will undo this.
Thanks, looks good to me now other than the FORTIFY reversal.
Being pedantic: The warning comes from glibc, it could potentially occur with any compiler. |
Reverted the change to _FORTIFY_SOURCE, now the only difference in that part of the file compared to master is that we pass in debug and error flags when making the check. If this looks OK I can squash the branch down. |
Hmm it appears the extra flags are supposed to be CPPFLAGS not CFLAGS/CXXFLAGS according to the m4 macro. So maybe there's no point in passing in the flags at all there. Kind of a bummer since that means it doesn't catch the interaction with |
Removed the _FORTIFY_SOURCE changes altogether since the new check isn't effective. The only reason I wanted to change it in the first place was because it interacted poorly with -O0, and on the platforms that generates warnings on we no longer expect to see warnings. |
One more thing I might as well ask while we're making this change, since I touched this line of code anyway. At the top of
We don't set The current code works but we might want to fix this (perhaps in another PR). |
Not sure what you mean by that. The flags passed in are appended to CPPFLAGS for the test, it doesn't matter how they're stored otherwise. I agree with just leaving it alone, though. |
Yes, it looks like LIBTOOL_LDFLAGS wasn't removed from AM_LDFLAGS in e0077de as it should've been. But the manual additions of LIBTOOL_APP_LDFLAG are intentional; They're appended for all application links, but not for libraries (libbitcoinconsensus). |
I think that last test failure was Travis being flaky, b0860d8e82041786b3424851b42a8b8c5bc143e8 squashes all of these changes down. |
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.
utACK b0860d8e82041786b3424851b42a8b8c5bc143e8
configure.ac
Outdated
echo " CXX = $CXX" | ||
echo " CXXFLAGS = $CXXFLAGS" | ||
echo " LDFLAGS = $LDFLAGS" | ||
echo " CXXFLAGS = $CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS" |
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.
Should this line include configure.ac
should include comments to stay in sync with the AM_CXXFLAGS and AM_LDFLAGS lines from Makefile.am
.
Could also consider combining the flags into a variable that is used both places.
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.
Agreed. I haven't complained about this becoming stale because it seemed inevitable that it would be non-exact due to the per-object and per-library flags. But keeping it in sync with AM_*FLAGS makes sense.
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.
Updated. What about something like:
DEFAULT_AM_CXXFLAGS="$CXXFLAGS $DEBUG_CXXFLAGS etc..."
AC_SUBST(DEFAULT_AM_CXXFLAGS)
# and likewise for the other vars
Then the configure script could print that variable, and it could be re-used in src/Makefile.am. Seems like it would be less likely to get out of sync that wya.
if test "x$GXX" = xyes; then | ||
CXXFLAGS="$CXXFLAGS -g3 -O0" | ||
fi | ||
# Prefer -Og, fall back to -O0 if that is unavailable. |
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.
Maybe move this enable_debug
section up two lines up, above the CXXFLAG_WERROR line. I realise you didn't add this section here, but it is rewritten now, and seems out of place in the middle of the checks for compiler warning flags.
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.
enable_debug uses CXXFLAG_WERROR, so it needs to be below the definition.
AX_CHECK_COMPILE_FLAG( | ||
[-Og], | ||
[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -Og"]], | ||
[AX_CHECK_COMPILE_FLAG([-O0],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]])], |
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.
Maybe add a comment here if passing if $CXXFLAG_WERROR
is intentional, or consider dropping it. It seem like it makes these checks unnecessarily verbose and also fragile.
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.
It's passed on purpose to turn -D_FORTIFY re-definition warnings into errors.
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.
Why would we want an error in that case?
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.
@luke-jr Sorry, that was the explanation for a different change.
-D_FORTIFY has incompatibilities with -O0, and many toolchains forcibly set _FORTIFY. Newer glibc versions spew a warning in that case, which we want to catch here because it means that -O0 is unusable without unsetting _FORTIFY.
Of course, there's the case to be made that --enable-debug and --enable-harden should be mutually exclusive, but as long as this is the only snag, I don't see the need to go that far.
configure.ac
Outdated
@@ -1370,9 +1380,9 @@ echo " build os = $BUILD_OS" | |||
echo | |||
echo " CC = $CC" | |||
echo " CFLAGS = $CFLAGS" | |||
echo " CPPFLAGS = $CPPFLAGS" | |||
echo " CPPFLAGS = $CPPFLAGS $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS" |
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.
CPPFLAGS and CXXFLAGS should probably be printed after the other flags instead of before, since they will override them.
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.
updated
PR description #12695 (comment) should be updated to match commit description, since it seems out of date now. |
Updated the configure summary at the end, and changed PR description. |
Note the summary list gets formatted kind of weird with extra/leading spaces when options aren't enabled, e.g.
The reason is that some flags we set will be missing or have whitespace themselves. Here is a reasonable way to fix that problem in a way that is /bin/sh compatible and doesn't use any non-Posix features: eklitzke@fd35edc . It technically doesn't handle whitespace within parameters correctly, but I don't think autoconf/automake does anyway. Unfortunately variable indirection in /bin/sh requires eval so you need to specify the flag name and its value separately. With that change the output looks like this:
|
Various changes: * Don't check $GCC and $GXX * Prefer -Og instead of -O0 * If -g3 isn't available, use -g This also incidentally fixes compiler warnings with GCC and glibc when using --enable-debug, as the old default values mixed poorly with the hardening flags.
I think switching to AX_APPEND_FLAG / AX_APPEND_COMPILE_FLAGS takes care of the whitespace problem more elegantly? |
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.
utACK
That's a good point, AX_APPEND_FLAG does in fact do the right thing wrt whitespace and feels a lot less hacky. We can let the output be a little untidy for now, I've got a 12 hour flight coming up in a few days and I might try to see if I can get AX_APPEND_FLAG and AX_APPEND_COMPILE_FLAGS working then. Thanks for your patience reviewing this! |
No problem, thanks for sticking with it! The flags change sounds like the perfect thing to fill some idle flight time :) Though, I think AX_APPEND_FLAG alone is probably enough. configure.ac is already so cryptic, it's helpful for self-documentation to explicitly use CXXFLAGS rather than having it implied. |
[AX_CHECK_COMPILE_FLAG([-O0],[[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -O0"]],,[[$CXXFLAG_WERROR]])], | ||
[[$CXXFLAG_WERROR]]) | ||
|
||
# Prefer -g3, fall back to -g if that is unavailable. |
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.
I wonder if it should prefer -ggdb
first...
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.
Why not -glldb ? :)
Since we can't anticipate, I think generic makes the most sense.
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.
Right, that kind of option makes more sense to pass in manually if you need it.
utACK - needs rebase though (probably due to your own commit, 6feb46c :). |
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.
utACK 9418964. Only change since last review is correcting CXXFLAGS/LDFLAG echo lines
Rebased in #13005. |
9e49db2 Make --enable-debug to pick better options (Evan Klitzke) Pull request description: Cherry-picked (and rebased) 9418964 from the "up for grabs" PR: "[build] Make --enable-debug pick better options" (#12695). See previous review in #12695. Tree-SHA512: a93cdadcf13e2ef8519acb1ce4f41ce95057a388347bb0a86a5c164dc7d0b0d14d4bb2a466082d5a100b8d50de65c605c40abaed555e8ea77c99e28800a34439
9e49db2 Make --enable-debug to pick better options (Evan Klitzke) Pull request description: Cherry-picked (and rebased) 9418964 from the "up for grabs" PR: "[build] Make --enable-debug pick better options" (bitcoin#12695). See previous review in bitcoin#12695. Tree-SHA512: a93cdadcf13e2ef8519acb1ce4f41ce95057a388347bb0a86a5c164dc7d0b0d14d4bb2a466082d5a100b8d50de65c605c40abaed555e8ea77c99e28800a34439
9e49db2 Make --enable-debug to pick better options (Evan Klitzke) Pull request description: Cherry-picked (and rebased) 9418964 from the "up for grabs" PR: "[build] Make --enable-debug pick better options" (bitcoin#12695). See previous review in bitcoin#12695. Tree-SHA512: a93cdadcf13e2ef8519acb1ce4f41ce95057a388347bb0a86a5c164dc7d0b0d14d4bb2a466082d5a100b8d50de65c605c40abaed555e8ea77c99e28800a34439
This changes
--enable-debug
to choose better options:-Og
rather than-O0
if it is available-g3
over-g
if it is available$DEBUG_CPPFLAGS
rather than updating$CPPFLAGS
directlyThis also updates the flags summaries at the end of the configure script to more accurately reflect what flags will be used for most of the code in src.