libnh: fix native build of libnh.a on macOS
Fixes four issues that prevented `make WANT_LIBNH=1 all` from producing a libnh.a that could be linked into a host program on macOS. Before these patches, it built but the resulting archive was unusable: macOS ld errored on a nested liblua archive member, was missing date.o and hacklib symbols (`populate_nomakedefs`, `eos`, `lcase`, `mungspaces`, ...), and had duplicate definitions of `main`, `whoami`, etc. Specific changes: 1. sys/libnh/libnhmain.c: drop `static` on `whoami()`. src/earlyarg.c declares it `extern` and calls it from `scores_only()`; the static makes it file-local and that reference goes unresolved. 2. sys/libnh/libnhmain.c: gate the emscripten-only code in get_nhuuid with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID`. The macOS hints define NHUUID for the libnh build (they did so unconditionally before NO_NHUUID even existed), so on native builds the compiler tried to call `emscripten_run_script_int` / `_string` and failed with implicit-function-declaration errors. __EMSCRIPTEN__ is the real signal for "this is being cross-compiled to WASM." 3. sys/unix/hints/macOS.500: in the WANT_LIBNH block, add an explicit `recover: lua_support` dependency (gated by MAKEFILE_TOP). When $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain no longer triggers `lua_support`, so include/nhlua.h never gets generated and recover.c's transitive #include of hack.h fails. 4. sys/unix/hints/macOS.500: rewrite the libnh.a rule. The previous `ar rcs libnh.a $(HOBJ) $(LIBNHSYSOBJ) liblua-$(LUA_VERSION).a` had four problems: (a) ar archives liblua.a as a single opaque member that macOS ld can't dereference, (b) date.o (DATE_O, kept separate from HOBJ) was never archived, so `populate_nomakedefs` and `nomakedefs` were missing, (c) hacklib.a was likewise omitted, and (d) HOBJ already contains $(SYSOBJ) (with unixmain.o) and $(WINOBJ) (the tty windowport), which duplicated symbols from libnhmain.o / winshim.o. The fix uses `libtool -static` so hacklib.a and liblua's archive have their members merged rather than nested, depends on $(LUALIB) so lua_support runs first, includes $(DATE_O) and $(TARGET_HACKLIB), and uses $(filter-out $(SYSOBJ) $(WINOBJ),$(HOBJ)) to drop the duplicates. Verified by clean rebuild on macOS 26 (arm64, Apple clang 17): make spotless make fetch-Lua make WANT_LIBNH=1 all and link-tested with a tiny harness that calls shim_graphics_set_callback() against the resulting libnh.a. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
8fcc15a860
commit
f6afa23e28
@@ -37,7 +37,7 @@ extern struct passwd *getpwnam(const char *);
|
||||
#ifdef CHDIR
|
||||
static void chdirx(const char *, boolean);
|
||||
#endif /* CHDIR */
|
||||
static boolean whoami(void);
|
||||
boolean whoami(void);
|
||||
static void process_options(int, char **);
|
||||
|
||||
#ifdef _M_UNIX
|
||||
@@ -516,7 +516,7 @@ chdirx(const char *dir, boolean wr)
|
||||
#endif /* CHDIR */
|
||||
|
||||
/* returns True iff we set plname[] to username which contains a hyphen */
|
||||
static boolean
|
||||
boolean
|
||||
whoami(void)
|
||||
{
|
||||
/*
|
||||
@@ -805,7 +805,7 @@ get_nhuuid(void)
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
char *uuid = (char *) &stmp[0];
|
||||
#ifndef NONHUUID
|
||||
#ifdef NHUUID
|
||||
#ifdef __EMSCRIPTEN__
|
||||
int uuid_available = 0;
|
||||
#endif
|
||||
#endif
|
||||
@@ -814,7 +814,7 @@ get_nhuuid(void)
|
||||
return;
|
||||
|
||||
#ifndef NONHUUID
|
||||
#ifdef NHUUID
|
||||
#ifdef __EMSCRIPTEN__
|
||||
uuid_available = emscripten_run_script_int(
|
||||
"typeof crypto !== 'undefined'"
|
||||
" && typeof crypto.randomUUID === 'function'");
|
||||
@@ -824,7 +824,7 @@ get_nhuuid(void)
|
||||
uuid = (char *) &stmp[0];
|
||||
}
|
||||
}
|
||||
#endif /* NHUUID */
|
||||
#endif /* __EMSCRIPTEN__ */
|
||||
#endif /* NONHUUID */
|
||||
Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", uuid);
|
||||
}
|
||||
|
||||
@@ -345,6 +345,12 @@ LIBNHSYSOBJ = $(TARGETPFX)libnhmain.o $(TARGETPFX)ioctl.o \
|
||||
#without winshim
|
||||
override GAME=
|
||||
MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) $(TARGETPFX)libnh.a )
|
||||
# With $(GAME) empty, the regular `recover: $(GAME)` chain no longer
|
||||
# triggers lua_support, but recover.c still pulls in hack.h -> nhlua.h
|
||||
# transitively. Make recover depend on lua_support explicitly.
|
||||
ifdef MAKEFILE_TOP
|
||||
recover: lua_support
|
||||
endif
|
||||
endif # WANT_LIBNH
|
||||
|
||||
# Lua
|
||||
@@ -568,8 +574,20 @@ $(TARGETPFX)macuuid.o: ../sys/unix/macuuid.m
|
||||
endif
|
||||
|
||||
ifdef WANT_LIBNH
|
||||
$(TARGETPFX)libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a
|
||||
$(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a
|
||||
# Build libnh.a by merging the engine objects, the shim windowport,
|
||||
# date.o (separate from $(HOBJ) per Makefile.src), hacklib.a, and Lua's
|
||||
# static archive. Use libtool -static rather than ar so hacklib.a and
|
||||
# liblua-$(LUA_VERSION).a have their members merged in -- ar would archive
|
||||
# them as opaque .a members and macOS ld can't dereference those.
|
||||
# Depending on $(LUALIB) triggers the lua_support build (which generates
|
||||
# include/nhlua.h); without it, $(HOBJ) won't compile.
|
||||
# filter-out drops $(SYSOBJ) (which carries unixmain.o) and $(WINOBJ) (the
|
||||
# tty windowport) from $(HOBJ); $(LIBNHSYSOBJ) supplies libnhmain.o and
|
||||
# winshim.o in their place.
|
||||
$(TARGETPFX)libnh.a: $(LUALIB) $(HOBJ) $(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB)
|
||||
libtool -static -o $@ \
|
||||
$(filter-out $(SYSOBJ) $(WINOBJ),$(HOBJ)) \
|
||||
$(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB) $(LUALIB)
|
||||
@echo "$@ built."
|
||||
$(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H)
|
||||
$(CC) $(CFLAGS) -c -o$@ $<
|
||||
|
||||
Reference in New Issue
Block a user