-
Notifications
You must be signed in to change notification settings - Fork 5
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
cmake: Add user-defined APPEND_{CPP,C,CXX,LD}FLAGS
#157
Conversation
2d5e9d3
to
ad4fe4a
Compare
The recent push to bitcoin#29790 (the |
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 tested these and they work as expected: use -DEXTRA_CPPFLAGS:STRING="-I/extracppflags" -DEXTRA_CFLAGS:STRING="-I/extracflags" -DEXTRA_CXXFLAGS:STRING="-I/extracxxflags" -DEXTRA_LDFLAGS:STRING="-L/extraldflags"
and then observe the output when compiling with --verbose
. Except that -fPIE -pie
and -pthread
are present after my extra LDFLAGS:
/usr/local/bin/clang++-devel -O0 -ftrapv -g3 -fstack-protector-all -fcf-protection=full -fstack-clash-protection -Wl,-z,relro -Wl,-z,now -Wl,-z,separate-code -L/extracldflags -fPIE -pie src/CMakeFiles/bitcoin-cli.dir/bitcoin-cli.cpp.o -o src/bitcoin-cli -Wl,-rpath,/usr/local/lib: src/libbitcoin_cli.a src/libbitcoin_common.a src/util/libbitcoin_util.a -pthread /usr/local/lib/libevent.so src/univalue/libunivalue.a src/libbitcoin_consensus.a src/crypto/libbitcoin_crypto.a libsecp256k1.a
These extra flags are not printed in the summary. An adapted #93 must make it.
cmake_parse_arguments(PARSE_ARGV 1 FWD "" "" "") | ||
add_library("${name}" ${FWD_UNPARSED_ARGUMENTS}) |
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 is it necessary to parse the command line arguments manually/explicitly? Aren't the variables readily available in e.g. ${EXTRA_CXXFLAGS}
? I was (naively?) hoping that this would be as simple as:
CXXFLAGS += ${EXTRA_CXXFLAGS}
or
set(CXXFLAGS "${CXXFLAGS} ${EXTRA_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.
From the CMake docs, it follows:
- The
CXXFLAGS
environment variable theCMAKE_CXX_FLAGS
CMake variable. CMake can combine its own builtin toolchain-specific default flags (the exact flags are not documented) into theCMAKE_CXX_FLAGS
variable. - During compiler invocation, the resulted flags are combined as follows:
(`CMAKE_CXX_FLAGS`) + (`CMAKE_CXX_FLAGS_<CONFIG>`) + (`COMPILE_OPTIONS` target properties)
To be able to override any flag, the EXTRA_CXXFLAGS
/APPEND_CXXFLAGS
must be a COMPILE_OPTIONS
property of a target that is considered the last.
cmake/module/AddTargetMacros.cmake
Outdated
# Functions in this module are drop-in replacements for CMake's add_library | ||
# and add_executable functions. They are mandatory for use in the Bitcoin | ||
# Core project, except for imported and interface libraries. |
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 think it is good to explain "Why?" (ie why are they mandatory). Something like:
They are mandatory for use in Bitcoin Core because they handle EXTRA_CPPFLAGS, EXTRA_CFLAGS, EXTRA_CXXFLAGS and EXTRA_LDFLAGS.
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.
Yea, it's not ectually clear why we need all this extra machinery to do this, and it's more non-standard stuff we'll have to maintain. I would also assume we can have a better interface/encapsulation, than a function that is always called with the same arguments, otherwise it can just be missued.
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.
My understanding is that this is needed if we want to append to the CXXFLAGS when invoking CMake, in order to override only some options, but not all. E.g. if it would use internally "-Wfoo -Wbar" we don't want to drop/override this completely but we want to append "-Wno-foo" so that it becomes "-Wfoo -Wbar -Wno-foo". Am I right?
This implementation looks quite complicated to me but I couldn't come up with a simpler one. First I tried to use the global add_compile_options(), but that is already out-lawed via cmake/module/WarnAboutGlobalProperties.cmake
. Then I tried to append the extra flags to core_interface
by something like:
cmake_language(EVAL CODE "
cmake_language(DEFER
DIRECTORY ${PROJECT_SOURCE_DIR}
CALL target_compile_options core_interface INTERFACE ${EXTRA_CPPFLAGS} $<$<COMPILE_LANGUAGE:CXX>:${EXTRA_CXXFLAGS}>
)
")
but to my annoyance the extra flags appear before all the -Werror -W...
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.
E.g. if it would use internally "-Wfoo -Wbar" we don't want to drop/override this completely but we want to append "-Wno-foo" so that it becomes "-Wfoo -Wbar -Wno-foo". Am I right?
Correct.
This implementation looks quite complicated to me but I couldn't come up with a simpler one. First I tried to use the global add_compile_options(), but that is already out-lawed via
cmake/module/WarnAboutGlobalProperties.cmake
.
It is out-lawed for a reason :)
Directory-level properties are quite error-prone and hard to reason about in large project like Bitcoin Core.
Then I tried to append the extra flags to
core_interface
by something like...
It is still possible to combine extra flags into the core_interface
library, and use it in these invocations. But, again, this approach is a bit error-prone as it it requires an extra care about the order of appending all other flags to the core_interface
library.
CMakeLists.txt
Outdated
@@ -94,6 +94,11 @@ cmake_dependent_option(FUZZ "Build for fuzzing. Enabling this will disable all o | |||
|
|||
option(INSTALL_MAN "Install man pages." ON) | |||
|
|||
set(EXTRA_CPPFLAGS "" CACHE STRING "Extra (Objective) C/C++ preprocessor 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.
If CMake does not have a notion of CPPFLAGS
can we avoid it as well? Looks like sneaking an autotool-ism into CMake based build system. I peeked at the CI changes that engage EXTRA_CPPFLAGS
and I think using EXTRA_CXXFLAGS
instead should work, no?
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.
We have discussed this earlier and during today's call. The rough consensus is to keep EXTRA_CPPFLAGS
for convenience.
ad4fe4a
to
f77ab70
Compare
Rebased to resolve conflicts. |
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.
Approach ACK f77ab70
Would be nice to have:
- Deduplicate the code from
subtree_add_library
andbitcoincore_add_library
- Elaborate the comment at cmake: Add user-defined
APPEND_{CPP,C,CXX,LD}FLAGS
#157 (comment) - Rename to
APPEND_
orLATE_
f77ab70
to
555798a
Compare
EXTRA_{CPP,C,CXX,LD}FLAGS
APPEND_{CPP,C,CXX,LD}FLAGS
Thank you for your review!
Your feedback has been addressed. |
FWIW, the Qt 6 uses a quite similar approach. From Professional CMake: A Practical Guide 18th Edition:
|
Also add a sanity check for non-encapsulated (directory-wide) build properties.
Co-authored-by: Cory Fields <[email protected]> Co-authored-by: Vasil Dimov <[email protected]>
Co-authored-by: Cory Fields <[email protected]>
Avoid using source-specific compile options. They hard to reason about and error-prone when combining with target-specific compile options. The resulted build logic effectively mirrors the master branch's one.
67f5198 fixup! cmake: Build `bitcoin_consensus` library (Hennadii Stepanov) Pull request description: Separated sources have not been needed since libbitcoinconsencus was removed. Required for #157. Top commit has no ACKs. Tree-SHA512: c4f391f439a7401771152ce5efee54c4b85b2ae879af95a66bc06e902a86a254defcf83526b1d778a3f523886076906382020f9a0f024d666f13195ea52b8547
d88e03c cmake: Add `docs` build target (Hennadii Stepanov) Pull request description: Same as `make docs` in the master branch. ACKs for top commit: vasild: ACK d88e03c Tree-SHA512: 6c8871658cd686576b41e73c0adcdedf97ef2d1ce9a25c9f0625ec94183e6cda7eb642e25e761c1bdfed45fb26fa20af39565a61e7087143636452086a416b7c
5ca0799 fixup! cmake: Build `bitcoin_crypto` library (Hennadii Stepanov) Pull request description: Avoid using source-specific compile options. They hard to reason about and error-prone when combining with target-specific compile options. The resulted build logic effectively mirrors the master branch's one. Required for #157. Similar to #171. ACKs for top commit: TheCharlatan: ACK 5ca0799 Tree-SHA512: 8f55c86a3ad900c8de1789a97c936e39362d9995d75d2f9ca2d0f65f5863816795623d8ec1f2cc5f4468e27d934ce99150574cf766a7d6dd1da68546f13216fb
43fbeac fixup! cmake: Build `crc32c` static library (Hennadii Stepanov) Pull request description: Avoid using source-specific compile options. They are hard to reason about and error-prone when combining with target-specific compile options. The resulted build logic effectively mirrors the master branch's one. Required for #157. ACKs for top commit: TheCharlatan: ACK 43fbeac Tree-SHA512: 51eac99f9c7327afc9edf812575b2c0a76c899d788cac547e22ed573c7d28694ae5615fa6686d0033bc9cc85e0c350dd8f5aeaacbfde864c8a9718a18efae6f8
The content of those variables is appended to the each target flags added by the build system.
Rebased. |
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.
ACK 1fc6d39
The append flags are not printed in the configure summary, #93
Works as expected, except then linking -pthread
and -fPIE -pie
appear after the append flags: /usr/local/bin/clang++-devel -O0 -ftrapv -g3 -fstack-protector-all -fcf-protection=full -fstack-clash-protection -Wl,-z,relro -Wl,-z,now -Wl,-z,separate-code -L/appendldflags -fPIE -pie src/CMakeFiles/bitcoind.dir/bitcoind.cpp.o src/CMakeFiles/bitcoind.dir/init/bitcoind.cpp.o -o src/bitcoind -Wl,-rpath,/usr/local/lib: src/libbitcoin_node.a src/wallet/libbitcoin_wallet.a libleveldb.a libcrc32c.a libcrc32c_sse42.a libminisketch.a /usr/local/lib/libevent_pthreads.so src/libbitcoin_common.a src/util/libbitcoin_util.a -pthread /usr/local/lib/libevent.so src/libbitcoin_consensus.a src/crypto/libbitcoin_crypto.a src/crypto/libbitcoin_crypto_sse41.a src/crypto/libbitcoin_crypto_avx2.a src/crypto/libbitcoin_crypto_x86_shani.a libsecp256k1.a src/univalue/libunivalue.a /usr/local/lib/libsqlite3.so && :
. Why is that? It makes it impossible to append -fno-PIE
.
This is expected as bitcoin/src/util/CMakeLists.txt Lines 45 to 50 in 2dc63ca
|
I think you'll need to explain this further. The point of these options is to always have the last say, so it's not at all expected that some options would still be added after these flags. |
Well, that's annoying.
This is because CMake treats Position Independent Code /Executable as abstractions with internal implementation of the logic for applying the related compile and linker flags.
I have no solution for that at the moment. |
When However,
|
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.
ACK 2dc63ca
I think there is no way to negate -pthread
(e.g. -no-pthread
), so its late appearance seems ok.
The -fPIE
is indeed annoying, but IMO not a blocker for this PR.
I checked that cmake -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=OFF
has no effect and still adds -fPIE
, maybe because the top level CMakeLists.txt
sets it like set(CMAKE_POSITION_INDEPENDENT_CODE ON)
after a check. Maybe this can be made conditional - only set it to ON
if it is not already set to OFF
on the command line?
This approach will work. |
This doesn't explain why it's appearing after our options on the link line? Wether or not overriding it may or may not have use is mostly irrelevant. The fact it's appearing on the line after our options points to this not completely working like we intend. |
"... which makes CMake treat it as any other -l option" The Again, this can be fixed, if there are reasons for that. |
Please consider an alternative implementation in #184. |
Closing in favour of #184. |
…e 2) a9dc2c1 cmake: Dispaly `APPEND_{CPP,C,CXX,LD}FLAGS` in summary (Hennadii Stepanov) bfadb6e cmake: Add `APPEND_{CPP,C,CXX,LD}FLAGS` cache variables (Hennadii Stepanov) Pull request description: An alternative implementation of #157. ACKs for top commit: vasild: ACK a9dc2c1 Tree-SHA512: 77fff64817c59153e4022390bed3a5db1eeb247ea916c99c582fcf18fe9e1f638aa2dd38121ebb5734339bf15d935a8b817083918020b944f2a0d72c76375e86
…oin Core's approach 4706be2 cmake: Reimplement `SECP256K1_APPEND_CFLAGS` using Bitcoin Core approach (Hennadii Stepanov) c2764db cmake: Rename `SECP256K1_LATE_CFLAGS` to `SECP256K1_APPEND_CFLAGS` (Hennadii Stepanov) Pull request description: This PR address this hebasto/bitcoin#239 (comment): > For consistency with libsecp256k1: > > > > Is this code block supposed to achieve the same as our `SECP256K1_LATE_CFLAGS` (implemented by a user-defined function `all_targets_add_compile_options`) in libsecp256k1? > > > > > > It is. But this approach guaranties to override even options that are abstracted by CMake, for instance [#157 (comment)](hebasto/bitcoin#157 (comment)). > > * If we agree that appending to rule variables is superior, should we also do this in libsecp256k1? > > * And/or should we rename the `SECP256K1_LATE_CFLAGS` variable to `APPEND_CFLAGS`? ACKs for top commit: real-or-random: utACK 4706be2 Tree-SHA512: 24603886c4d6ab4e31836a67d5759f9855a60c6c9d34cfc6fc4023bd309cd51c15d986ac0b77a434f9fdc6d5e97dcd3b8484d8f5ef5d8f840f47dc141de18084
This PR implements the CMake WG design decision made during the call on 2024-04-18.
To test this PR, I suggest to observe raw build logs using the
--verbose
command-line option.The related #93 is to be reworked on top of this PR.