← board

Extern variables from C headers on ESP

Repro 1: the header import drops extern variables (host, no ESP needed)

cat > exth.h <<'EOF'
typedef struct { int a; int b; } pair_t;
extern pair_t g_pair;
extern const pair_t g_cpair;
extern int g_int;
EOF
cat > t.pas <<'EOF'
program t;
uses exth;
var p: ^pair_t;
begin
  p := @g_pair;
  writeln(p^.a, ' ', g_cpair.b, ' ', g_int);
end.
EOF
pascal26 -I. -Fu. t.pas t
# error: undefined variable (g_pair)   ... (g_cpair)

pair_t imports fine; only the variables are missing.

Repro 2: Pascal's own external variable is refused on ESP

In a unit compiled with --target=riscv32 --platform=esp --emit-obj:

var g_wifi_osi_funcs: wifi_osi_funcs_t; cvar; external;
error: --emit-obj: an imported variable (g_wifi_osi_funcs) is not supported
for xtensa/riscv32 objects: the reference would relocate into this object's
own .bss and read zero. Export an accessor from the defining side instead

On ESP the defining side is a prebuilt IDF blob (libnet80211.a, libwpa_supplicant), so the suggested accessor would need a C shim in the app. That is exactly what header import should make unnecessary.

What the app does meanwhile

The same trick as before the port: procedure g_wifi_osi_funcs; external; is declared purely to take its link-time address, and is cast to the header's real types (PWpaCryptoFuncs(@g_wifi_default_wpa_crypto_funcs)^). This works because a text UND symbol relocates correctly. That makes it likely that (2) only needs a data UND symbol with the same R_RISCV_* relocations that a call/address-of already gets. test/abi_import_check.pas compares the resulting wifi_init_config_t byte for byte with gcc's layout: 0 differences.

Acceptance

Log