Skip to content

Commit 739de63

Browse files
Fix native CI: glibc C23 compat shim for leanc linking
Two-compiler strategy verified in Docker (Ubuntu 24.04): 1. System clang++ -stdlib=libc++ builds all deps (full system headers) 2. leanc compiles a C23 compat shim (glibc_isoc23_compat.c) 3. lake build links everything with leanc The compat shim bridges the glibc version gap: system clang++ compiles against glibc 2.38+ which redirects strtoull→__isoc23_strtoull when _GNU_SOURCE is defined, but leanc's bundled older glibc lacks these C23 symbols. The shim forwards them to the regular versions.
1 parent 9924cc8 commit 739de63

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ jobs:
2626
run: |
2727
sudo apt-get update
2828
sudo apt-get install -y cmake build-essential nlohmann-json3-dev \
29-
uuid-dev libssl-dev python3 python3-pip
29+
uuid-dev libssl-dev python3 python3-pip \
30+
clang libc++-dev libc++abi-dev
3031
3132
- name: Install Lean via elan
3233
run: |
@@ -38,20 +39,23 @@ jobs:
3839

3940
- name: Build C++ FFI library
4041
run: |
41-
# Use leanc (Lean's clang wrapper) so compiled code uses leanc's
42-
# bundled glibc headers, matching the glibc leanc links against.
43-
# System clang++ uses system glibc 2.39 headers which redirect
44-
# strtoull→__isoc23_strtoull (C23), missing from leanc's older glibc.
45-
# STATIC_LIBRARY skips link tests that fail with leanc's sysroot.
46-
# LibUUID paths provided explicitly since leanc's sysroot hides them.
42+
# Use system clang++ with libc++ so cmake can find all system
43+
# libraries and headers (leanc's sysroot is too minimal for libzmq).
44+
# The -stdlib=libc++ ensures C++ ABI matches Lean's linker.
4745
cmake -S . -B build-cmake \
48-
-DCMAKE_C_COMPILER=leanc \
49-
-DCMAKE_CXX_COMPILER=leanc \
50-
-DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY \
51-
-DLibUUID_INCLUDE_DIR=/usr/include \
52-
-DLibUUID_LIBRARY=/usr/lib/x86_64-linux-gnu/libuuid.a
46+
-DCMAKE_C_COMPILER=clang \
47+
-DCMAKE_CXX_COMPILER=clang++ \
48+
-DCMAKE_CXX_FLAGS="-stdlib=libc++"
5349
cmake --build build-cmake
5450
51+
- name: Build glibc C23 compat shim
52+
run: |
53+
# System clang++ compiles against glibc 2.38+ which redirects
54+
# strtoull→__isoc23_strtoull (C23) when _GNU_SOURCE is defined.
55+
# leanc's bundled older glibc lacks these symbols, so we provide
56+
# a shim compiled with leanc that forwards C23→regular versions.
57+
leanc -c src/glibc_isoc23_compat.c -o build-cmake/glibc_isoc23_compat.o
58+
5559
- name: Build Lean kernel
5660
run: lake build xlean
5761

Dockerfile.native

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
FROM ubuntu:24.04
2+
3+
RUN apt-get update && apt-get install -y \
4+
cmake build-essential nlohmann-json3-dev \
5+
uuid-dev libssl-dev python3 python3-pip \
6+
clang libc++-dev libc++abi-dev \
7+
curl git
8+
9+
# Install Lean via elan
10+
RUN curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- -y --default-toolchain leanprover/lean4:v4.28.0-rc1
11+
ENV PATH="/root/.elan/bin:${PATH}"
12+
13+
WORKDIR /app
14+
COPY . /app
15+
16+
# Step 1: Build C++ FFI library with system clang++ -stdlib=libc++
17+
RUN cmake -S . -B build-cmake \
18+
-DCMAKE_C_COMPILER=clang \
19+
-DCMAKE_CXX_COMPILER=clang++ \
20+
-DCMAKE_CXX_FLAGS="-stdlib=libc++" && \
21+
cmake --build build-cmake
22+
23+
# Step 2: Build glibc C23 compat shim with leanc
24+
RUN leanc -c src/glibc_isoc23_compat.c -o build-cmake/glibc_isoc23_compat.o
25+
26+
# Step 3: Build Lean kernel
27+
RUN lake build xlean
28+
29+
CMD ["bash"]

lakefile.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,15 @@ lean_exe xlean where
4848
-- All deps built from source via FetchContent; do NOT add system lib
4949
-- paths like -L/usr/lib/x86_64-linux-gnu because leanc uses --sysroot
5050
-- with its own bundled glibc, and system glibc conflicts (__libc_csu_init).
51+
-- glibc_isoc23_compat.o provides __isoc23_strtoull etc. shims: system
52+
-- clang++ compiles against glibc 2.38+ which redirects strtoull→C23
53+
-- variants, but leanc's older glibc lacks them.
5154
#["-L./build-cmake/_deps/xeus-build",
5255
"-L./build-cmake/_deps/xeus-zmq-build",
5356
"-L./build-cmake/_deps/libzmq-build/lib",
5457
"-Wl,--start-group",
5558
"./build-cmake/libxeus_ffi.a",
59+
"./build-cmake/glibc_isoc23_compat.o",
5660
"-lxeus", "-lxeus-zmq", "-lzmq",
5761
"-Wl,--end-group",
5862
"-lpthread", "-lm", "-ldl"]

src/glibc_isoc23_compat.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* glibc C23 compatibility shim for leanc linking.
3+
*
4+
* When compiled with system clang++ against glibc >= 2.38, _GNU_SOURCE causes
5+
* strtoull/strtoll to redirect to __isoc23_strtoull/__isoc23_strtoll (C23
6+
* variants). But leanc's bundled older glibc lacks these symbols.
7+
*
8+
* This shim provides the missing symbols by forwarding to the regular versions
9+
* available in leanc's glibc. No headers needed - just forward declarations.
10+
*/
11+
12+
/* Forward declarations matching libc signatures */
13+
extern unsigned long long strtoull(const char *, char **, int);
14+
extern long long strtoll(const char *, char **, int);
15+
extern unsigned long strtoul(const char *, char **, int);
16+
extern long strtol(const char *, char **, int);
17+
18+
unsigned long long __isoc23_strtoull(const char *nptr, char **endptr, int base) {
19+
return strtoull(nptr, endptr, base);
20+
}
21+
22+
long long __isoc23_strtoll(const char *nptr, char **endptr, int base) {
23+
return strtoll(nptr, endptr, base);
24+
}
25+
26+
unsigned long __isoc23_strtoul(const char *nptr, char **endptr, int base) {
27+
return strtoul(nptr, endptr, base);
28+
}
29+
30+
long __isoc23_strtol(const char *nptr, char **endptr, int base) {
31+
return strtol(nptr, endptr, base);
32+
}

0 commit comments

Comments
 (0)