Skip to content
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

chore: CI: build 64-bit platforms consistently with GMP #5144

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ jobs:
"release": true,
"check-level": 2,
"shell": "msys2 {0}",
"CMAKE_OPTIONS": "-G \"Unix Makefiles\" -DUSE_GMP=OFF",
"CMAKE_OPTIONS": "-G \"Unix Makefiles\"",
// for reasons unknown, interactivetests are flaky on Windows
"CTEST_OPTIONS": "--repeat until-pass:2",
"llvm-url": "https://github.com/leanprover/lean-llvm/releases/download/15.0.1/lean-llvm-x86_64-w64-windows-gnu.tar.zst",
Expand All @@ -227,7 +227,7 @@ jobs:
{
"name": "Linux aarch64",
"os": "nscloud-ubuntu-22.04-arm64-4x8",
"CMAKE_OPTIONS": "-DUSE_GMP=OFF -DLEAN_INSTALL_SUFFIX=-linux_aarch64",
"CMAKE_OPTIONS": "-DLEAN_INSTALL_SUFFIX=-linux_aarch64",
"release": true,
"check-level": 2,
"shell": "nix develop .#oldGlibcAArch -c bash -euxo pipefail {0}",
Expand Down
6 changes: 5 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@
# more convenient `ctest` output
CTEST_OUTPUT_ON_FAILURE = 1;
} // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux {
GMP = pkgsDist.gmp.override { withStatic = true; };
GMP = (pkgsDist.gmp.override { withStatic = true; }).overrideAttrs (attrs:
pkgs.lib.optionalAttrs (pkgs.stdenv.system == "aarch64-linux") {
# would need additional linking setup on Linux aarch64, we don't use it anywhere else either
hardeningDisable = [ "stackprotector" ];
});
LIBUV = pkgsDist.libuv.overrideAttrs (attrs: {
configureFlags = ["--enable-static"];
hardeningDisable = [ "stackprotector" ];
Expand Down
32 changes: 23 additions & 9 deletions src/library/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,30 @@ namespace lean {
struct olean_header {
// 5 bytes: magic number
char marker[5] = {'o', 'l', 'e', 'a', 'n'};
// 1 byte: version, currently always `1`
uint8_t version = 1;
// 42 bytes: build githash, padded with `\0` to the right
char githash[42];
// 1 byte: version, incremented on structural changes to header
uint8_t version = 2;
// 1 byte of flags:
// * bit 0: whether persisted bignums use GMP or Lean-native encoding
// * bit 1-7: reserved
uint8_t flags =
#ifdef LEAN_USE_GMP
0b1;
#else
0b0;
#endif
// 33 bytes: Lean version string, padded with '\0' to the right
// e.g. "4.12.0-nightly-2024-10-18". May not be null-terminated.
char lean_version[33];
// 81b008650766442a0dfa9faa796e4588c9d7d3a1
// 40 bytes: build githash, padded with `\0` to the right
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no padding here, right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There can be, if the githash is empty. I don't think there is anything syntactically restricting it to be exactly 40 bytes, although it will be for actual lean releases.

char githash[40];
// address at which the beginning of the file (including header) is attempted to be mmapped
size_t base_addr;
// payload, a serialize Lean object graph; `size_t` has same alignment requirements as Lean objects
size_t data[];
};
// make sure we don't have any padding bytes, which also ensures `data` is properly aligned
static_assert(sizeof(olean_header) == 5 + 1 + 42 + sizeof(size_t), "olean_header must be packed");
static_assert(sizeof(olean_header) == 5 + 1 + 1 + 33 + 40 + sizeof(size_t), "olean_header must be packed");
Copy link
Contributor

@eric-wieser eric-wieser Oct 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps worth having an static_assert(offsetof(olean_header,data) % 40 == 0) or whatever the actual alignment requirements are.


extern "C" LEAN_EXPORT object * lean_save_module_data(b_obj_arg fname, b_obj_arg mod, b_obj_arg mdata, object *) {
std::string olean_fn(string_cstr(fname));
Expand Down Expand Up @@ -96,6 +109,7 @@ extern "C" LEAN_EXPORT object * lean_save_module_data(b_obj_arg fname, b_obj_arg
// see/sync with file format description above
olean_header header = {};
header.base_addr = base_addr;
strncpy(header.lean_version, get_short_version_string().c_str(), sizeof(header.lean_version));
strncpy(header.githash, LEAN_GITHASH, sizeof(header.githash));
out.write(reinterpret_cast<char *>(&header), sizeof(header));
out.write(static_cast<char const *>(compactor.data()), compactor.size());
Expand Down Expand Up @@ -140,16 +154,16 @@ extern "C" LEAN_EXPORT object * lean_read_module_data(object * fname, object *)

olean_header default_header = {};
olean_header header;
if (!in.read(reinterpret_cast<char *>(&header), sizeof(header))) {
if (!in.read(reinterpret_cast<char *>(&header), sizeof(header))
|| memcmp(header.marker, default_header.marker, sizeof(header.marker)) != 0) {
return io_result_mk_error((sstream() << "failed to read file '" << olean_fn << "', invalid header").str());
}
if (memcmp(header.marker, default_header.marker, sizeof(header.marker)) != 0
|| header.version != default_header.version
if (header.version != default_header.version || header.flags != default_header.flags
#ifdef LEAN_CHECK_OLEAN_VERSION
|| strncmp(header.githash, LEAN_GITHASH, sizeof(header.githash)) != 0
#endif
) {
return io_result_mk_error((sstream() << "failed to read file '" << olean_fn << "', invalid header").str());
return io_result_mk_error((sstream() << "failed to read file '" << olean_fn << "', incompatible header").str());
}
char * base_addr = reinterpret_cast<char *>(header.base_addr);
char * buffer = nullptr;
Expand Down
4 changes: 4 additions & 0 deletions src/library/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,9 @@ optional<name> is_unsafe_rec_name(name const & n) {
return option_ref<name>(lean_is_unsafe_rec_name(n.to_obj_arg())).get();
}

static std::string * g_short_version_string = nullptr;
std::string const & get_short_version_string() { return *g_short_version_string; }

static std::string * g_version_string = nullptr;
std::string const & get_version_string() { return *g_version_string; }

Expand Down Expand Up @@ -863,6 +866,7 @@ void initialize_library_util() {
if (std::strlen(LEAN_SPECIAL_VERSION_DESC) > 0) {
out << "-" << LEAN_SPECIAL_VERSION_DESC;
}
g_short_version_string = new std::string(out.str());
if (std::strlen(LEAN_PLATFORM_TARGET) > 0) {
out << ", " << LEAN_PLATFORM_TARGET;
}
Expand Down
1 change: 1 addition & 0 deletions src/library/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ name mk_unsafe_rec_name(name const & n);
/** Return some(n') if \c n is a name created using mk_unsafe_rec_name(n') */
optional<name> is_unsafe_rec_name(name const & n);

LEAN_EXPORT std::string const & get_short_version_string();
LEAN_EXPORT std::string const & get_version_string();

expr const & extract_mdata(expr const &);
Expand Down
31 changes: 22 additions & 9 deletions stage0/src/library/module.cpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions stage0/src/library/util.cpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions stage0/src/library/util.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion stage0/stdlib/Init/Data/Array.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading