Oddbean new post about | logout
 I'm having trouble, too, since these douchebags of other devs can't be bothered to put together linux apps in anything other than build it yourself source code (which I have no desire to learn ho wto do, as that is effing stupid) or flatpacks which do not work with my distro. WTF!!!
 
 hahahaha. That's the Linux way brother!!! 

But yeah that's kind of how it works. We can't know what hardware or instruction set you have ahead of time, so we have to build from source most times. Windows can make some guarantees like 64bit with SSE and the MS C runtime figures out the rest so that's why most things are pre-compiled on Windows. That and a fully stable/backward compatible ABI which Linux distros often cannot comply with.  
 That's stupid. It should just effing run for the distro. It shouldn't matter what hardware if you build it to run for that operating system. It's not a friggin game, it's a chat app.  
 Wonder why everything is docker docker docker now?? lol

POSIX is a thing, and even targeting generic "linux" and gnu libc is possible, but you'd be surprised how limited it is. Basically no cryptography is available because that's specific to a CPUs ALU (or more specific stuff like floating point units and stuff) which is required for everything. So yeah, if Linux locked their support like Windows does it could work better, but then it wouldn't be called Linux anymore XD 
 This is all stupid. I'm angry right now. I'm not rational. I can say yes to what you said but it doesn't change the fact that it's just effing stupid. In friggin 2024. This just makes me want to go ban to friggin DOS. It wasn't this stupid and worked.  
 I'm totally with you! The state of binary compatibility is piss poor, and since docker, not something that's going to get fixed more than likely. Justine Tunney and her project Cosmopolitan/APE are actually making it possible though. It's a steep learning curve and only possible for programs not libraries.

It's been a weird gray area forever. Linux/FSF/GNU want you to distribute source only, so the user can build. Which is required for true software freedom, but then you get this XD 
 In my non-technical view... 

It's been trash for years but it's just the least worse trash there is at the moment. 😅  
 so if you do static binaries no problemo 
 *Laughs in 100mb+ binaries* 
 This makes me shudder... 
 lol, idk what you are talking about, last time i recall working with btcd it was like 40mb binary and my own stuff rarely gets much past about 20mb... there is a 7mb baseline, ok, i'll grant you that

 
 bitcoind is not statically linked against libc and other platform libraries iirc? Is it even statically linked against openssl? I gotta take a look. 
 i think Go binaries link to libc but that's itt

heres what it produces out of my code for the relay (this includes secp256k1 library:

mleku@iox:~/src/realy.lol/cmd/realy$ ls -lash realy
20M -rwxrwxr-x 1 mleku mleku 20M Nov 10 19:30 realy
mleku@iox:~/src/realy.lol/cmd/realy$ ldd realy
        linux-vdso.so.1 (0x00007a310b5a6000)
        libsecp256k1.so.5 => /lib/libsecp256k1.so.5 (0x00007a310b448000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007a310b200000)
        /lib64/ld-linux-x86-64.so.2 (0x00007a310b5a8000)
 
 also, yes, it will be exactly the same as this except libsecp256k1

and i didn't realise i would have to distribute the binary with it this way... there is ways to make it pull all that in, but it is minimalistic, even so 
 I prefer static linking only when necessary. Had a long chat with some crazy smart peeps on HN a few months back about these issues. It's seems pretty equally divided on static vs dynamic linking. static is a workaround because dynamic is not as well supported as it should be IMO.  
 the problem with dynamic linking is where to get the fucking DLLs to get out of DLL HELL

nothing has changed since that term was coined and the easiest solution is to go static

for 99% of go projects, that aren't using GPUs or specialised libraries like secp256k1 (which you can avoid, just costs you a 4x time cost for each signature/verification)

there is even now many libraries doing standard things like hex encoding and sha256 hash functions that use AVX or whatever it's called on ARM processors now... Go compiler also understands raw assembler 
 For open source, I care about user freedom in the case of linking, which is why noscrypt is licensed under lgpl. I want users to be able to swap/edit libraries or build their own if they want to. Make a common ABI (usually defined in a shared header file, or interface in C#) and have fun.  
 i generally use CC0 these days

simple = better

i do need to learn how to build my stuff purely static tho, damn... or at least to pull in that secp256k1 library to the binary so it runs on linux, good thing i didn't try to distribute a binary! 
 btw, default autotools compiles seem to make the static library... you get a .a, .la (which just points at the .a as its binary) and .so in maybe several versions - at least with libsecp256k1 it was

and so i was able to do this:

mleku@iox:~/src/realy.lol/cmd/realy$ ls -lash|grep realy
 23M -rwxrwxr-x 1 mleku mleku  23M Nov 10 20:16 realy
4.0K -rw-rw-r-- 1 mleku mleku  414 Oct 20 22:57 realy.service
mleku@iox:~/src/realy.lol/cmd/realy$ ldd realy
        not a dynamic executable

and you see, that only added 3mb to the size of the binary and i can distribute that and it will work on any system with glib2 on amd64 architecture 
 this is how i did it:

mleku@iox:~/src/realy.lol$ go build --ldflags '-extldflags "-static"' -o ~/bin/realy ./cmd/realy/. 
# realy.lol/cmd/realy
/usr/bin/ld: /tmp/go-link-1787515793/000021.o: in function `mygetgrgid_r':
/_/GOROOT/src/os/user/cgo_lookup_cgo.go:45:(.text+0x44): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-1787515793/000021.o: in function `mygetgrnam_r':
/_/GOROOT/src/os/user/cgo_lookup_cgo.go:54:(.text+0xe5): warning: Using 'getgrnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-1787515793/000022.o: in function `mygetgrouplist':
/_/GOROOT/src/os/user/getgrouplist_unix.go:15:(.text+0x22): warning: Using 'getgrouplist' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-1787515793/000004.o: in function `_cgo_04fbb8f65a5f_C2func_getaddrinfo':
/tmp/go-build/cgo-gcc-prolog:60:(.text+0x37): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-1787515793/000021.o: in function `mygetpwnam_r':
/_/GOROOT/src/os/user/cgo_lookup_cgo.go:36:(.text+0x18a): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: /tmp/go-link-1787515793/000021.o: in function `mygetpwuid_r':
/_/GOROOT/src/os/user/cgo_lookup_cgo.go:27:(.text+0x249): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
 
 being that glibc has been at version 2 for like 20 years that's probably ok... and even if they do bump to a 3 there probably will be glib.so.2 libraries installed by default for a long time 
 > bitcoind is not statically linked against libc and other platform libraries iirc?

right, the distributed bitcoind binaries are statically linked against everything except libgcc and libc (and companion libs such as libm libatomic etc, if relevant to the platform)

this is the list of allowed dynamic deps (the second part is for bitcoin-qt so not relevant to bitcoind): https://github.com/bitcoin/bitcoin/blob/master/contrib/devtools/symbol-check.py#L95

statically linking to libc is under consideration but it comes with a few issues, so it's not an easy choice

> Is it even statically linked against openssl?

openssl is not used either statically or dynamically 
 TY 
 speaking of that, did you see whitequark's "superlnker" project ? (https://github.com/whitequark/superlinker)

it is a tool that can link a binary and all its dynamic dependencies together into one self-contained binary, even the dynamic linker itself (so the resulting binary can still use dlopen)

it would be risky to use it for production-level distributed software, but i imagine one could use it trivially on bitcoind to make a fully self-contained binary 
 Bookmarked! Will take a look when I get back to my machine later! IIRC dlopen isn't really necessary most of the time right? The OS will map the dynamic library to the function stubs (in .plt) at load time? 

>it would be risky to use it for production-level distributed software, but i imagine one could use it trivially on bitcoind to make a fully self-contained binary
Agreed. Not sure the usefulness though, other than it being a somewhat portable binary if you build it right lol. I tend to enjoy the idea of stable ABIs and dynamic libraries. 
 
 this is never a problem with Go

only with everything else, basically literally everything else is a pain to build anything

the exception being when the Go code dependson C code, then it also sucks in the same way

and a lot of dumbasses in dev think "oh yeah i'll make my go project depend on make and shit" fucks sake 🤦‍♂️ they clearly did not get the whole point of the Go, everything compiles on it, static binary

the only possible excuse for not using pure Go code ever is generalyl hardware drivers, especially GPU libraries

even many of those have moved to fully supported no extra tooling

i tell everyone that #golang is the best, but nobody seems to want to listen, it really is... if you actually use the go tool and don't bullshit it up with C and C++ and FFI and rust and all that other fuckin inane bullshit that is irrelevant to fucking network servers 
 i just need to clarify, it needs linux-vdso.so and libc.so.6 and ld-linux-x86-64.so.2

those are on all linux installations even the most minimal

it is possible to make it completely static with extra flags but that is default