-
Notifications
You must be signed in to change notification settings - Fork 419
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
Bundle clang+lld+libc++ for Linux #733
Conversation
Do you have any idea how this would work on NixOS? We need an (OS-provided) compiler wrapper to find the ELF interpreter, include files, etc. The bundled clang requires some additional libraries:
The
After adding enough stuff to LD_LIBRARY_PATH to actually get this to run, as expected, clang fails to build an executable:
|
Btw, the |
@gebner It looks like we should really compile LLVM from source after all... or we do the same thing as with the Lean executable and just copy those deps as well.
|
Ok that's correct, but at least
BTW, I also had to add And even if all include headers are present, the resulting binaries won't run:
|
I'm not sure I understand the intent behind this PR then. If users are supposed to use their own toolchain anyhow, why do we bundle it? Wouldn't it be easier to add an |
Ah, the cpack configuration must be wrong, all the files listed above should be included! I'll take a look. Regarding NixOS, it might be best to completely ignore the bundle and keep using stdenv? We can make it so that when |
That's the only solution I can see. But if we do |
The purpose of this PR is to enable building of pure Lean programs (including precompiling modules) without system dependencies. That a C compiler is bundled & used for this should be regarded as an implementation detail. As soon as additional C code comes into play, it's likely that so do additional headers from /usr/include, at which point I don't expect the bundle to behave well (so use your system compiler for foreign code). But maybe that is too pessimistic and we can add at least the libc headers in the future. All this work is also not super important on Linux to begin with because usually a C toolchain is already present there. It's mostly a PoC before attempting the same on macOS and Windows, where it's more important. |
And that none of this would be necessary if only everyone used Nix goes without saying :) . |
I see, but I'm not sure if this is such a big issue (on Linux). Even rustup requires a system compiler. Once we start bundling half a linux distribution, we might as well distribute docker images...
Completely agreed here, it's much harder to install a working C compiler on windows. |
That's true, I was actually surprised by this and had to double-check! But it is worth keeping in mind that while Rust is a programming language, that is only part of the story for Lean. If efficiently working on mathlib requires a C compiler for precompilation, it should work out of the box. |
167a778
to
fbc2e76
Compare
Before merging this, could you please make a tag (so that binary releases get pushed) and give me a few days to fix and test the elan package in nixpkgs? |
fbc2e76
to
e55cc67
Compare
@gebner Can do. Could you try if everything "just works" now if |
I've built lake successfully with |
Thanks, that makes me fairly confident that this PR introduces no observable difference in behavior as long as |
@tydeu What do you think, should Lake copy libgmp next to each executable? I'm assuming this is already an issue on master, e.g. a Lean program built in a mingw shell should fail to find libgmp when run outside of the shell. |
@Kha you are correct, running the executable outside of mingw does crash due to not being able to find libgmp. I am suprised I never stumbled onto that before! More to your point, the copying should probably occur during the creation of a "distribution" of package/application, which Lake does not yet provide a means of doing, However, it is certainly something on the TODO list. Such a However, this does raise the question of whether it might be worth it in the medium to long term to move from libgmp to a different multi-precision library that can be linked statically to make Lean's core self-contained. |
If libgmp is bundled with Lean and not installed in the system, which can already be the case today, you won't even be able to run the binary yourself unless you set LD_LIBRARY_PATH/... to the specific Lean toolchain's lib/ directory (recall that elan does not change the environment, so it can't do it for you). So I think copying should happen immediately.
That would be nice, but I'm not aware of a serious alternative. Writing (a verified) one in Lean with at least reasonable performance might be a nice student project though... |
Openssl has a bignum library that is performance-oriented https://github.com/openssl/openssl/blob/master/crypto/bn. I guess the problem there is that it would have to be copied as it doesn't have its own git. (The API: https://github.com/openssl/openssl/blob/master/include/openssl/bn.h) Though personally, I would be happy with just a simple one (which there are a lot of), I just want unbounded ints, not good performance with millions of digits. It would be nice with a GMP API compatible one, so both would be an option. I looked around a bit and came across whyMP https://gitlab.inria.fr/why3/whymp (Oops, that one is GPLv3 too, so that doesn't work) |
Okay, I will get to work on that soon. Do you mind creating an issue for it over on leanprover/lake? Also, is |
Last time I checked, https://github.com/libtom/libtommath was another reasonable non-copyleft licensed alternative to GMP. My impression is that nobody in the Lean ecosystem makes "serious" use of big integers at the moment (let's say >100 digits). Using an asymptotically slower but easier to distribute implementation is a reasonable choice, certainly as a default (keeping GMP as a build-time option). |
Packaged in Ubuntu, MSYS2, and Homebrew, looks pretty good to me. |
e55cc67
to
2fd4126
Compare
Also, do so only for releases since `zstd -19` takes a while. Also, stop double-wrapping artifacts
80498c1
to
b36e253
Compare
a3b419a
to
6153b79
Compare
6153b79
to
6a0938b
Compare
Closing in favor of #795 |
…eanprover#733) `linarith` needs various things that haven't been ported yet. This PR adds various sorried stubs in ad-hoc ported files ahead of where we're currently up to. Co-authored-by: Scott Morrison <[email protected]>
TODO: * Before merge - [x] fix a bug in linarith in mathlib3 I just found ... - [x] depends on: leanprover#519 - [x] style lint - [x] docs - [X] move theory stubs to a separate PR, for easier tracking: leanprover#733 - [x] failing to parse the `LinarithConfig` option * Before or after merge? - [ ] Implement the `removeNe` preprocessor. - [ ] Add support for restricting to a single type. How to store a `Type` in `LinarithConfig`? * After merge - [ ] Teach `norm_num` to solve `example [LinearOrderedRing α] : (0 : α) < 37 := by norm_num`. - [ ] Port `zify_proof` (plumbing for `zify`), and add the `natToInt` preprocessor. Mostly done now, but see leanprover#741 before all the tests will work. - [ ] Port `cancel_denoms` tactic, and add the `cancelDenoms` preprocessor. - [ ] Add the `nlinarith` preprocessor and front-end syntax. Co-authored-by: Mario Carneiro <[email protected]> Co-authored-by: Scott Morrison <[email protected]>
Alternative approach to #659: instead of relying on Zig, we bundle everything necessary for standalone compilation ourselves. This way we're kept in control and can use a uniform, mature toolchain across all platforms. And hopefully avoid unexplainable errors that we could not reproduce without Zig.
Specifically, what we bundle in the case of x86-64 Linux is
As can be seen, the bundle size is dominated completely by the
clang
andlld
executables. That Zig manages to combine both of them and their own compiler in an executable smaller thanclang
is an impressive feat and demonstrates that this bundle could still be optimized, though I don't think it's a dealbreaker for us.A special issue on Linux is the glibc. We bundle a relatively old version of it, glibc 2.27 from Nixpkgs 19.03, so that Lean programs linked against it work on most somewhat recent distros. For running we always use the system glibc, which is why we put the bundled one in a separate directory.
Apart from the glibc, a Lean program built with this bundle does have more runtime dependencies, namely the libc++ and GMP DSOs:
For the tests, I simply set
LD_LIBRARY_PATH
to the bundle'slib/
, but that isn't really an option in general. libc++ (BSD-like/MIT) we should probably link statically (like it seems to be the case with libstdc++ right now), but that is problematic with GMP because of its LGPL license. The best approach I can come up with is to use the "Windows approach": put$ORIGIN
(the executable's own directory) in its rpath and copy libgmp.so next to it (which is basically free with hardlinks). The second step should probably be done by Lake, not leanc.