mold icon indicating copy to clipboard operation
mold copied to clipboard

static linking under cmake

Open CosmicToast opened this issue 3 years ago • 14 comments
trafficstars

CMake does not provide any consistent configure-time way to create fully statically linked distributions like mine. While it's preferable to meson (which explicitly breaks static linking even when authors want it), it would be nice to have a MIMALLOC_STATIC option or similar to provide feature parity (rather than a MOSTLY_STATIC option).

CosmicToast avatar Oct 03 '22 00:10 CosmicToast

While it's preferable to meson (which explicitly breaks static linking even when authors want it)

Interesting claim.

...

Moving on, what's the problem with configuring vendored dependencies as static, and using -static etc. in your LDFLAGS? If the external find_package() results are hardcoding shared versions, well, cmake wants you to build a different copy of the package with BUILD_SHARED_LIBS=OFF and put that in your search path.

It would probably be possible to use pkg_check_modules instead. :)

eli-schwartz avatar Oct 03 '22 01:10 eli-schwartz

mold -run doesn't work if mold is a statically-linked executable, and that's why I provide "mostly static" as opposed to a fully static. Don't you want to have that feature?

rui314 avatar Oct 03 '22 05:10 rui314

Hmm, shouldn't that only require mold-wrapper.so to be built dynamically, though?

eli-schwartz avatar Oct 03 '22 05:10 eli-schwartz

Oh, sorry, the feature that doesn't work without dynamic linking is LTO. LTO uses dlopen to use a compiler-supplied linker plugin.

rui314 avatar Oct 03 '22 05:10 rui314

Interesting claim.

In particular I'm talking about this sentiment (I happen to want all of those to be statically linked :) ). If this has changed in the meanwhile, I would be glad to hear it (especially if there's a configure-time override now).

the feature that doesn't work without dynamic linking is LTO LTO uses dlopen to use a compiler-supplied linker plugin Don't you want to have that feature?

While I am very much in favour of LTO, it's outside of my specific usage scope. My use-cases involve making arbitrary systems possible to try in any OS+Arch (so not triple) system, as well as research projects (e.g, currently, a "development-files"-only distribution).

Ultimately, the thing to keep in mind is that with the current Makefile system, making such a build is trivial. With the new CMake system, it is not. As such, I would treat this as a regression.

CosmicToast avatar Oct 03 '22 15:10 CosmicToast

In particular I'm talking about this sentiment (I happen to want all of those to be statically linked :) ). If this has changed in the meanwhile, I would be glad to hear it (especially if there's a configure-time override now).

There is -Dprefer_static=true to toggle pkg-config etc. dependency lookups to be found statically project-wide by default. It's also possible to pass the static kwarg manually via a custom user option e.g. static: get_option('foodep-static').

Platform libraries tied to the libc are usually linked as -lfoo instead of finding the absolute filepath, so those respect LDFLAGS=-static instead. No one ever implemented a special list of libs that should be found by absolute path, but also "enforce using the shared version because people usually want that" and I disagree with the logic behind adding one. :)

eli-schwartz avatar Oct 03 '22 15:10 eli-schwartz

While I am very much in favour of LTO, it's outside of my specific usage scope.

I tend to agree. "Don't you want to have that feature" is the wrong question to be asking. The real question is "should everyone be forced to use this feature no matter what, and is it ever possible that some people might not need it in particular workflows".

(I do agree that LTO is very nice and I'd usually use it.)

eli-schwartz avatar Oct 03 '22 15:10 eli-schwartz

There is [...]

So just to clarify, nowadays, LDFLAGS=-static meson configure -Dprefer_static=true should be sufficient to generate fully statically linked executables? I'm at work right now and can't test, but will do so afterwards (assuming this is correct). Thanks for the clarification either way!

"should everyone be forced to use this feature no matter what, and is it ever possible that some people might not need it in particular workflows".

The latter in particular. I also agree that LTO is good and if I could have it be available (if not forcefully on) on a statically linked package, I would like that. However, to me, it's not a strict requirement, while the static linkage is "the whole point" of my binaries, so it gets a lowered priority.

On an unrelated note, I do wonder if dlopen might be theoretically possible (in the future) when statically linking against musl, since ld.so on musl systems is the musl library itself.

CosmicToast avatar Oct 03 '22 16:10 CosmicToast

So just to clarify, nowadays, LDFLAGS=-static meson configure -Dprefer_static=true should be sufficient to generate fully statically linked executables?

a) yes b) back in the day, you had to implement prefer_static as a custom project option and pass it into every dependency lookup

IIRC my main use case was building one project, that being fully static recovery system binaries of pacman, which worked quite well with option b, as long ago as a couple of years.

eli-schwartz avatar Oct 03 '22 17:10 eli-schwartz

As an aside, prefer_static=true does work for me - looks like it's fairly new though (released this july). Thanks a lot for letting me know about this, it makes my job immeasurably easier.

CosmicToast avatar Oct 03 '22 20:10 CosmicToast

Good to know that you found a solution.

Speaking of LTO, mold doesn't have any ./configure-time options. However you build it, the resulting binary will include all the features it supports and behaves exactly the same. So, for example, unlike GNU ld or LLVM lld, zlib and zstd compressions are always compiled in to mold (if your system does not have them, bundled ones are linked to mold). I think I like this property; mold behavior depends only on its version and command line options. So I don't like to add an option to make some feature compile-time option. If you do this for your system, it's up to you, but I prefer not to officially support such compile-time options.

rui314 avatar Oct 04 '22 07:10 rui314

Good to know that you found a solution.

The solution was regarding meson projects; it unfortunately does not apply to mold.

However you build it, the resulting binary will include all the features it supports and behaves exactly the same.

This issue isn't about disabling LTO, but producing a fully static binary. The LTO discussion is there to say that I do not mind if LTO does not work as a consequence (so long as "does not work" doesn't imply broken binaries, of course) - which was the concern you brought up here:

[LTO] doesn't work if mold is a statically-linked executable, and that's why I provide "mostly static" as opposed to a fully static. Don't you want to have that feature?

To reiterate the mold-specific situation: I already currently produce fully static mold binaries using the make-based build system. I can't do this with the cmake based system (at least not without modifying the cmakelists). Therefore, that is a regression, so long as the makefile is to be deprecated.

If you try to build mold with LDFLAGS=-static right now it will fail because CMake will explicitly specify libz.so and libcrypto.so. If you combine that with MOSTLY_STATIC it will link dynamically to libz, libc++, libc and libm (ending up more dynamic than otherwise). Furthermore, even if there were specific override flags for the two of those libraries alone, any future dependencies would subsequently break this as well, so long as there wasn't a unified option for static linkage.

Just in case, again, this issue is not about disabling LTO, it is about getting a fully static mold binary, something that is currently possible without any unusual steps using the Makefile build system.

CosmicToast avatar Oct 04 '22 11:10 CosmicToast

I think it's "fairly likely" (lol) that the LTO feature does not require linking dynamically to libz.so and statically to libzstd.a regardless of libc / libc++.

eli-schwartz avatar Oct 04 '22 12:10 eli-schwartz

The point I wanted to say is that I don't want to provide an official way to do X that (as an unintended consequence) disables some other feature Y of the linker, whatever X or Y are This is for the sake of build reproducibility across hosts.

I think it's "fairly likely" (lol) that the LTO feature does not require linking dynamically to libz.so and statically to libzstd.a regardless of libc / libc++.

It seems statically-linked binaries cannot call dlopen but the LTO plugin depends on it.

rui314 avatar Oct 05 '22 00:10 rui314