FROM ubuntu:22.04 RUN apt-get update && apt-get install -y \ build-essential \ libgtk-4-dev \ pkg-config \ libcurl4-openssl-dev \ binutils \ file \ && rm -rf /var/lib/apt/lists/* WORKDIR /build # All sources arrive in /build — runtime/ subdirectory contains the el runtime, # top-level contains elc-generated app/vessel C files. COPY runtime/ runtime/ COPY el_native_vessel.c el_native_vessel.h native_hello.c ./ # Compile el_gtk4.c RUN gcc -DEL_TARGET_LINUX $(pkg-config --cflags gtk4) \ -std=c11 -I/build/runtime \ -c /build/runtime/el_gtk4.c -o /build/el_gtk4.o && \ echo "el_gtk4.c compiled OK" # Compile el_seed.c RUN gcc -DEL_TARGET_LINUX $(pkg-config --cflags gtk4) \ -std=c11 -I/build/runtime \ -c /build/runtime/el_seed.c -o /build/el_seed.o && \ echo "el_seed.c compiled OK" # Compile el_runtime.c RUN gcc -std=c11 -I/build/runtime \ -c /build/runtime/el_runtime.c -o /build/el_runtime.o && \ echo "el_runtime.c compiled OK" # Patch el_runtime.o: hide __-prefixed symbols that el_seed.o also defines. # This is the Linux objcopy equivalent of macOS nmedit -s. # el_seed.o is canonical for all __ symbols; el_runtime.o provides high-level # builtins (str_len, json_get_string, etc.) that el_seed.o does NOT export. RUN nm /build/el_seed.o | awk '/[0-9a-f]+ T /{print $3}' | sort > /build/.seed_T.txt && \ nm /build/el_runtime.o | awk '/[0-9a-f]+ T /{print $3}' | sort > /build/.rt_T.txt && \ comm -12 /build/.seed_T.txt /build/.rt_T.txt > /build/.dups.txt && \ if [ -s /build/.dups.txt ]; then \ ARGS=$(awk '{printf "--localize-symbol=%s ", $1}' /build/.dups.txt); \ eval "objcopy $ARGS /build/el_runtime.o"; \ echo "Patched $(wc -l < /build/.dups.txt) duplicate symbols in el_runtime.o"; \ else \ echo "No duplicate symbols found"; \ fi # Compile vessel RUN gcc -DEL_TARGET_LINUX -std=c11 -I/build/runtime \ -include /build/runtime/el_native_target.h \ -c /build/el_native_vessel.c -o /build/el_native_vessel.o && \ echo "vessel compiled OK" # Compile app (before patching vessel, so we know which symbols to localise) RUN gcc -DEL_TARGET_LINUX -std=c11 -I/build/runtime \ -include /build/runtime/el_native_target.h \ -include /build/el_native_vessel.h \ -c /build/native_hello.c -o /build/native_hello.o && \ echo "app compiled OK" # Patch el_native_vessel.o: # 1. Localise main() so it doesn't conflict with the app's main. # 2. Localise any T/B symbols the app also defines (elc emits shared globals # like TOKEN_PRIMARY in every translation unit; GNU ld rejects duplicates # unlike macOS ld which picks the first one silently). RUN nm /build/native_hello.o | awk '/[0-9a-f]+ [TBb] /{print $3}' | sort > /build/.app_syms.txt && \ nm /build/el_native_vessel.o | awk '/[0-9a-f]+ [TBb] /{print $3}' | sort > /build/.vessel_syms.txt && \ comm -12 /build/.app_syms.txt /build/.vessel_syms.txt > /build/.vessel_dups.txt && \ echo "main" >> /build/.vessel_dups.txt && \ sort -u /build/.vessel_dups.txt -o /build/.vessel_dups.txt && \ ARGS=$(awk '{printf "--localize-symbol=%s ", $1}' /build/.vessel_dups.txt) && \ eval "objcopy $ARGS /build/el_native_vessel.o" && \ echo "Patched $(wc -l < /build/.vessel_dups.txt) symbols in el_native_vessel.o" # Link — add -lm for math functions (exp, log, etc.) used by el_runtime.c RUN gcc \ /build/native_hello.o \ /build/el_native_vessel.o \ /build/el_gtk4.o \ /build/el_runtime.o \ /build/el_seed.o \ $(pkg-config --libs gtk4) -ldl -lpthread -lcurl -lm \ -o /build/native-hello-linux && \ echo "==> Linked: native-hello-linux" && \ file /build/native-hello-linux