-
Notifications
You must be signed in to change notification settings - Fork 37.7k
[POC] build: static musl libc based bitcoind #23203
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
Cocnept ACK, this is great!
Qt is going to be a big challenge for full-static linking (due to system dependencies for X, FreeType etc). It's ok to skip that for now, IMO, would be nice to be able to ship a statically linked |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, 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. |
|
That excerpt is for the native b2 build, where using the system compiler is expected. |
I might have not properly cleaned my tree. Will retry a full build. Edit: whoops, that did it. |
Great, the functional tests pass and so does
They do exist, but it's unable to run them somehow;
I think this is the problem: "interpreter /lib/ld-musl-x86_64.so.1" |
The build works as-is on RISC-V! Except I had to add Edit: also the tests segfault on RISC-V, no idea why yet. Ok, built with debug information, this is the traceback:
I'm not sure what this is. But I strongly suspect it's not a bug in our code. It could be some kind of C++ ABI conflict (does it matter what C++ libarary version is on the system?), but also simply a RISC-V specific compilation / library /thread handling bug. We'll know more once we try on for other platforms. |
Concept ACK, always great to see people doing static builds. |
Concept ACK |
FWIW I checked and there's another copy of the C++ library headers under |
I've reworked this PR a bit. It's been rebased, and now builds on #20744 (using Given that, I've updated the config here so that the toolchain we're now using is GCC 11.2 + binutils 2.37 + musl 1.2.2. Currently the link invocation for a minimal # compiler
<path to>/x86_64-linux-musl-g++
# compile options
-m64
-std=c++17
-fdebug-prefix-map=/home/ubuntu/bitcoin=.
-fstack-reuse=none
-Wstack-protector
-fstack-protector-all
-fcf-protection=full
-fstack-clash-protection
-flto
-flto-odr-type-merging
-fPIE
-pipe
-O2
-fno-extended-identifiers
-fvisibility=hidden
# link options
-Wl,--exclude-libs -Wl,ALL
-Wl,-z -Wl,relro
-Wl,-z -Wl,now
-Wl,-z -Wl,separate-code
-pie
-static
-Wl,-O2
-o bitcoind bitcoind-bitcoind.o init/bitcoind-bitcoind.o
# depends lib search path
-L/home/ubuntu/bitcoin/depends/x86_64-pc-linux-gnu/lib
# internal libs
libbitcoin_common.a
libbitcoin_consensus.a
libbitcoin_server.a
libbitcoin_util.a
crypto/libbitcoin_crypto_base.a
crypto/libbitcoin_crypto_sse41.a
crypto/libbitcoin_crypto_avx2.a
crypto/libbitcoin_crypto_shani.a
leveldb/libleveldb.a
leveldb/libmemenv.a
crc32c/libcrc32c.a
crc32c/libcrc32c_sse42.a
secp256k1/.libs/libsecp256k1.a
univalue/.libs/libunivalue.a
# libstdc++
path/to/libstdc++/in/depends/libstdc++.a
# external libs
-levent_pthreads
-levent
-pthread |
4a1bea2
to
9a89a44
Compare
Nice work! It would be interesting to see the output of |
It's: $ ldd src/bitcoind
statically linked |
It seems like musl-cross-make automagically downloads a bunch of repositories (gcc, etc)... Any way we can "pre-seed" that? |
Nice! Playing around with this. Got it to build, great work. First observation (could be a red herring, take with a grain of salt) is the link line:
That static libstdc++.a seems weird and out of place, I assume libtool is throwing it in there. If omitted, g++ will add I'm mostly mentioning this because the two resulting binaries do differ. Though I haven't looked into how or whether the difference is at all significant. |
9a89a44
to
168d8f1
Compare
168d8f1
to
efcf935
Compare
Rebased this on master now that we are no-longer linking Boost libs, and changed to using GCC 10.3.0, so it, and binutils 2.37 match what we use for Guix builds. Also changed the depends variable to Building with |
Awesome, concept ACK! Will test soon. |
Hah, amazing. src/bitcoin2 (efcf935) % du -hs ./src/bitcoind
30M ./src/bitcoind
src/bitcoin2 (efcf935) % ldd ./src/bitcoind
statically linked
src/bitcoin2 (efcf935) % podman run --rm -it -v ./src/bitcoind:/bitcoind docker.io/library/alpine /bitcoind -version
Bitcoin Core version v22.99.0-efcf9355339f |
Concept ACK! Can this work for clang too? |
efcf935
to
a01e476
Compare
c8e1d1f
to
6e88952
Compare
A couple changes. NOTE: you now need to set HOST when doing the depends build. i.e
We should be able to do something similar with Clang. |
6e88952
to
0568cec
Compare
Converting this to a draft. I still think using musl libc / this depends based approach is interesting, but will be focussing on #25573 and it's dependant PRs for now. |
0568cec
to
62984e6
Compare
62984e6
to
79cb4f6
Compare
I will probably maintain this branch going forward, but going to close for now re my comment above. |
This proof of concept is one approach to static musl libc based builds. It leverages musl-cross-make to compile a musl libc targeting toolchain, made up of GCC 10.3.0 + binutils 2.37 + musl libc 1.2.3, and then uses that toolchain to build our depends libraries, and ultimately
bitcoind
.More than likely we'd take a different approach in Guix for (potentially) release builds, however, something like this could exist in depends, and provide an alternative to building against glibc outside Guix. Or, this may well end up being something we just throw away in favour of a better approach; still lots to be thought about here.
Only tested compiling on, for
x86_64-pc-linux-gnu
so far.You can use it as follows:
The end result (once stripped) is a ~10mb static
bitcoind
:If you see:
when running, pass
LC_ALL=C
. i.eLC_ALL=C src/bitcoind
.I've taken the binary onto a few different system / inside VMs, and am running a full sync.
Note that all dependencies do compile, except for Qt (build issue with FreeType I have not investigated), I've just excluded all optional dependencies from the depends build above.
When building, you may see warnings about libraries, such as
libstdc++
, as having been moved, during linking, and/or other warnings, from dependencies, such as sqlite, due to-flto
usage.Related to #18110.