Fixes: #33859
Previously one had to read the Makefile (and various *.mk configuration files) to see how to correctly override CC and CXX when building native depends packages.
Detail this in README.md to make it clearer.
Fixes: #33859
Previously one had to read the Makefile (and various *.mk configuration files) to see how to correctly override CC and CXX when building native depends packages.
Detail this in README.md to make it clearer.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33902.
See the guideline for information on the review process.
If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
155+```
156+
157+To ensure both native and target use Clang:
158+
159+```
160+make build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++
make build_CC=clang build_CXX=clang++ CC=clang CXX=clang++?
They should be exactly equivalent.
I used my version as I had just described build_CC and host_CC and it would seem a little odd (to me) to exemplify with build_CC and CC, although as I re-read it now this example appears in the CC, CXX section.
I think therefore I should set make build_CC=clang build_CXX=clang++ CC=clang CXX=clang++ as the primary example for this section, and perhaps use make build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++ as an “ultimately explicit” final variation?
In most situations where the compiler needs to be specified, users simply run:
0make CC=clang CXX=clang++
Only in rare cases (https://github.com/bitcoin/bitcoin/pull/33902#discussion_r2541427389, #33902 (review), #33902 (review)) does this need to be extended to:
0make CC=clang CXX=clang++ build_CC=clang build_CXX=clang++
They should be exactly equivalent.
Unfortunately this isn’t the case. make build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++ doesn’t work properly on a machine with no g++, because Boosts CMake will still try and find g++, and fail. Arguably this is also a CMake issue that we should fix/workaround in some way, because there’s no reason for Boost to try and find a compiler, when we aren’t compiling anything, and only need to copy headers. In this case, you do need to use make build_CC=clang build_CXX=clang++ CC=clang CXX=clang++.
For example, on a Chimera Linux machine:
0gmake build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++ -C depends/ -j12 build_TAR=gtar
1gmake: Entering directory '/bitcoin/depends'
2Extracting native_capnp...
3/bitcoin/depends/sources/capnproto-cxx-1.2.0.tar.gz: OK
4Preprocessing native_capnp...
5Configuring native_capnp...
6-- The CXX compiler identification is Clang 21.1.4
7-- Detecting CXX compiler ABI info
8<snip>
9done
10Configuring boost...
11CMake Error at /usr/share/cmake-4.1/Modules/CMakeDetermineCXXCompiler.cmake:47 (message):
12 Could not find compiler set in environment variable CXX:
13
14 g++.
15
16Call Stack (most recent call first):
17 CMakeLists.txt:13 (project)
18
19
20CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
21-- Configuring incomplete, errors occurred!
22gmake: *** [funcs.mk:344: /bitcoin/depends/aarch64-unknown-linux-musl/.boost_stamp_configured] Error 1
Using CC=clang CXX=clang++:
0build_CC=clang build_CXX=clang++ CC=clang CXX=clang++ -C depends/ -j12 build_TAR=gtar
1gmake: Entering directory '/bitcoin/depends'
2Extracting native_capnp...
3/bitcoin/depends/sources/capnproto-cxx-1.2.0.tar.gz: OK
4Preprocessing native_capnp...
5Configuring native_capnp...
6-- The CXX compiler identification is Clang 21.1.4
7<snip>
8done
9Configuring boost...
10-- The CXX compiler identification is Clang 21.1.4
11-- Detecting CXX compiler ABI info
12-- Detecting CXX compiler ABI info - done
13-- Check for working CXX compiler: /usr/sbin/clang++ - skipped
14-- Detecting CXX compile features
15-- Detecting CXX compile features - done
16-- Boost: using system layout: include, bin, lib/, lib//cmake
OK so having thought about this a bit more, my preference would be to not actually change the docs (as I have them in this PR), but to amend depends/host/default.mk to better respect when host_CC= host_CXX= have been set. I also posit that a setting of host_CC should override CC.
For depends, if I run make build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++ I expect to be able to build all host and native packages.
I also believe that if I run make build_CC=clang build_CXX=clang++ host_CC=clang host_CXX=clang++ CC=notacompiler CXX=notacompiler++, as host/build_CC/CXX have been defined and are more granular, they should be used over CC/CXX.
I think this commit here implements this, but makefile is really not my strongest suit and I could have easily not implemented what I wanted.
What are your thoughts on this approach?
I don’t think that the host_$(tool) variables were ever meant to be set by users, and the same applies to build_$(tool).
(this is my understanding of the code as it was originally introduced; however, @theuni knows better)
More recently, it became clear that native packages also need a way to define their toolchains.
As #23571 didn’t gain enough support, I ended up using the “internal” build_$(tool) variables in https://github.com/bitcoin/bitcoin/commit/551e13abf82522bad7fdde4ff4bd15d2c8f88b23.
lgtm
review ACK 17577646f77e20783ffdd9f322f85e96da2265 🌴
Signature:
0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
2trusted comment: review ACK 17577646f77e20783ffdd9f322f85e96da2265 🌴
3b6tuB1ff+N8xGzUilBsW1CSxIOpk4gK7SE473C8JMS+vg4aU5H4YbP04c0HL3NEDxTZkxKFJBRcJ9RVAQ9t7DQ==
181+Setting `CC` and `CXX` environment variables will override target compilers but **NOT** native tool compilers. Native tools will still use the default GCC unless explicitly overridden with `build_*` variables.
182+
183+Example that may not work as expected (native tools still use GCC):
184+
185+```
186+make CC=clang CXX=clang++
7f17cf6d6164460086afebbb0f921a7af4475bf9:
This example uses Makefile variable CC and CXX, but the section title refers to “Environment Variables”. Both approaches work, of course, but the section could be made clearer.
178+
179+### Environment Variables (CC, CXX)
180+
181+Setting `CC` and `CXX` environment variables will override target compilers but **NOT** native tool compilers. Native tools will still use the default GCC unless explicitly overridden with `build_*` variables.
182+
183+Example that may not work as expected (native tools still use GCC):
7f17cf6d6164460086afebbb0f921a7af4475bf9
This comes across as a bit discouraging and confusing. When I say “I build depends with Clang”, I’m referring to the host-specific packages. I’m not concerned about which compiler is used for the native tools, as long as they build without issues.
I’m not concerned about which compiler is used for the native tools, as long as they build without issues.
at least for me the issue was that they did not build at all, because the gcc version was ancient on OpenSuse Leap (or Alma Linux 8, ….)
I’m not concerned about which compiler is used for the native tools, as long as they build without issues.
at least for me the issue was that they did not build at all, because the gcc version was ancient on OpenSuse Leap (or Alma Linux 8, ….)
The same issue occurs on NetBSD.
176+make HOST=x86_64-pc-linux-gnu host_CC=clang host_CXX=clang++
177+```
178+
179+### Environment Variables (CC, CXX)
180+
181+Setting `CC` and `CXX` environment variables will override target compilers but **NOT** native tool compilers. Native tools will still use the default GCC unless explicitly overridden with `build_*` variables.
I’m not entirely convinced by the phrasing “Native tools will still use the default GCC…”. They may instead use whatever the system’s default cc and c++, but I haven’t tested this.
UPDATE: nm, it is hardcoded in depends/builders/default.mk.
UPDATE 2: However, the default compiler is Clang on some systems, such as macOS, FreeBSD and OpenBSD.
15
16 Skip the following packages if you don't intend to use the GUI and will build with [`NO_QT=1`](#dependency-options):
17
18- apt install bison g++ ninja-build pkgconf python3 xz-utils
19+```
20+apt install bison g++ ninja-build pkgconf python3 xz-utils
native_qt, require g++.
147+### Native Tools (build\_\* variables)
148+
149+These control compilers used to compile tools that run natively on the build machine during compilation:
150+
151+- `build_CC`: C compiler for native tools (default: `gcc` on Linux, `clang` on macOS/BSD)
152+- `build_CXX`: C++ compiler for native tools (default: `g++` on Linux, `clang++` on macOS/BSD)
0- `build_CC`: C compiler for native tools (default: `gcc` on Linux, `clang` on macOS/FreeBSD/OpenBSD)
1- `build_CXX`: C++ compiler for native tools (default: `g++` on Linux, `clang++` on macOS/FreeBSD/OpenBSD)
152+- `build_CXX`: C++ compiler for native tools (default: `g++` on Linux, `clang++` on macOS/BSD)
153+- `build_AR`, `build_RANLIB`, etc.: Other native build tools
154+
155+This separation allows cross-compilation where build and target architecture differ. These include Cap'n Proto code generators (`native_capnp`), Qt build tools (`native_qt`), and multiprocess utilities (`native_libmultiprocess`).
156+
157+You might want to override native tool compilers when your default build compiler (set in ./depends/builders/*.mk) is not available. For example when using a linux host without gcc/g++.
0You might want to override native tool compilers when your default build compiler (set in `./depends/builders/*.mk`) is not available. For example, when using a Linux host without gcc/g++.
154+
155+This separation allows cross-compilation where build and target architecture differ. These include Cap'n Proto code generators (`native_capnp`), Qt build tools (`native_qt`), and multiprocess utilities (`native_libmultiprocess`).
156+
157+You might want to override native tool compilers when your default build compiler (set in ./depends/builders/*.mk) is not available. For example when using a linux host without gcc/g++.
158+
159+Example using Clang for native build tools on linux:
0Example using Clang for native build tools on Linux:
Previously one had to read the Makefile (and various *.mk configuration
files) to see how to correctly override CC and CXX when building native
depends packages.
Detail this in README.md to make it clearer.
As we are touching the file use modern codeblock syntax throughout.
re-ACK 7dd714ae71fd18eda82ab4b43d4cecc047b87a2d 🔔
Signature:
0untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
1RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
2trusted comment: re-ACK 7dd714ae71fd18eda82ab4b43d4cecc047b87a2d 🔔
3GdGC0CV1oagJPrWcSYTtdbnzJVbACdpgtwV3w0kHQgMB3ZEIhZNTp9Mr5d0DHvusR7eUHFQEauWPXPwpa0cUDw==
doc: or build: prefix in title?
See #33902 (comment).
As I describe here I have a commit which if host_CC is set, and** CC is unset, will set CC to host_CC (and similarly for CXX and friends).
In my opinion this would result in the expected behaviour:
{var} is set, use thathost_{var} is set, and use thatI don’t see a use-case where someone purposefully setting host_{var} would ever expect {var} to take precedence for host buildilng, so don’t think having both set would work “unexpectedly”?
@hebasto notes that these variables are apparently not supposed to be set by users though.
If that is the case, perhaps then instead of introducing more opinionated fallback heirarchies we should look at re-working how toolchains are defined more holistically? I don’t see an obvious/clean approach not involving two sets of env vars though…
If that is the case, perhaps then instead of introducing more opinionated fallback heirarchies we should look at re-working how toolchains are defined more holistically? I don’t see an obvious/clean approach not involving two sets of env vars though…
I agree that the depends build subsystem should accept two sets of variables: one for host/target-specific tools and another for native tools.
The naming for the former is well established (CC, CXX, etc) and it makes no senses to use anything else, as this is what developers, integration workflows and testing frameworks (such as OSS-Fuzz) expect.
For the latter, many projects use the $(tool)_FOR_BUILD pattern, which we might also adopt.
Previously one had to read the Makefile (and various *.mk configuration files) to see how to correctly override CC and CXX when building native depends packages.
I also wanted to highlight the distinction between environment variables and Makefile variables. There should be no difference in behaviour between the two when supplied by the user, provided they are recognised by the build system. But that is not currently the case. See: #29963.