Skip to content

Commit 75daec0

Browse files
committed
drop! add comprehensive diagnostics and attempt USE_HOMEBREW_LIBICONV fix
This commit is laden with diagnostic output to understand the iconv/libintl linking failure on macOS 15 (Darwin 24). The diagnostics inspect: - System iconv location and exported symbols - Homebrew libiconv locations for both architectures and their symbols - What symbols libintl.a actually needs (undefined symbols) - What Homebrew's gettext/libintl.dylib links against (via otool -L) - The actual link command flags when the build fails Buried in the middle of this diagnostic noise is a real fix attempt: setting USE_HOMEBREW_LIBICONV and ICONVDIR to empty in config.mak. The hypothesis is that on Darwin 24+, config.mak.uname sets USE_HOMEBREW_LIBICONV which causes the Makefile to add -L/opt/homebrew/opt/libiconv/lib, directing the linker to Homebrew's libiconv.a. But Homebrew's libiconv exports _libiconv symbols while Homebrew's libintl was built against system iconv expecting _iconv symbols. By unsetting these variables, we should fall back to the system's /usr/lib/libiconv.dylib which is universal and has the correct symbols. If this fails, the diagnostics should reveal why.
1 parent a3f632e commit 75daec0

1 file changed

Lines changed: 114 additions & 59 deletions

File tree

.github/workflows/build-git-installers.yml

Lines changed: 114 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -412,49 +412,80 @@ jobs:
412412
# Make universal gettext library
413413
lipo -create -output libintl.a /usr/local/opt/gettext/lib/libintl.a /opt/homebrew/opt/gettext/lib/libintl.a
414414
415-
# === DEBUGGING: Inspect libraries and their properties ===
416-
echo "=== DEBUG: Architecture info for libintl.a sources ==="
417-
echo "--- x86_64 libintl.a ---"
418-
lipo -info /usr/local/opt/gettext/lib/libintl.a || echo "Not found"
419-
echo "--- arm64 libintl.a ---"
420-
lipo -info /opt/homebrew/opt/gettext/lib/libintl.a || echo "Not found"
421-
echo "--- Our combined libintl.a ---"
415+
# === COMPREHENSIVE DIAGNOSTICS ===
416+
echo "========================================================"
417+
echo "=== DIAGNOSTICS: Understanding the iconv/libintl situation ==="
418+
echo "========================================================"
419+
420+
echo ""
421+
echo "=== 1. SYSTEM INFO ==="
422+
sw_vers
423+
uname -a
424+
echo "Darwin major version: $(uname -r | cut -d. -f1)"
425+
426+
echo ""
427+
echo "=== 2. OUR UNIVERSAL libintl.a ==="
428+
echo "--- Architecture ---"
422429
lipo -info libintl.a
430+
echo "--- Undefined iconv symbols (what libintl needs) ---"
431+
nm -u libintl.a 2>/dev/null | grep -i iconv || echo "No iconv references"
432+
433+
echo ""
434+
echo "=== 3. WHAT DID HOMEBREW'S GETTEXT LINK AGAINST? ==="
435+
echo "--- x86_64 libintl.8.dylib dependencies (otool -L) ---"
436+
otool -L /usr/local/opt/gettext/lib/libintl.8.dylib 2>/dev/null || echo "Not found"
437+
echo "--- arm64 libintl.8.dylib dependencies (otool -L) ---"
438+
otool -L /opt/homebrew/opt/gettext/lib/libintl.8.dylib 2>/dev/null || echo "Not found"
439+
440+
echo ""
441+
echo "=== 4. SYSTEM ICONV (what libintl expects) ==="
442+
echo "--- /usr/lib/libiconv* files ---"
443+
ls -la /usr/lib/libiconv* 2>/dev/null || echo "No /usr/lib/libiconv* files"
444+
echo "--- /usr/lib/libiconv.2.dylib architecture ---"
445+
lipo -info /usr/lib/libiconv.2.dylib 2>/dev/null || file /usr/lib/libiconv.2.dylib 2>/dev/null || echo "Not found"
446+
echo "--- /usr/lib/libiconv.2.dylib exported symbols (first 10 with iconv) ---"
447+
nm -gU /usr/lib/libiconv.2.dylib 2>/dev/null | grep -i iconv | head -10 || echo "Cannot read or no iconv symbols"
448+
449+
echo ""
450+
echo "=== 5. HOMEBREW LIBICONV (what we must NOT use for linking) ==="
451+
echo "--- x86_64 Homebrew libiconv ---"
452+
ls -la /usr/local/opt/libiconv/lib/ 2>/dev/null || echo "Not installed"
453+
if [ -f /usr/local/opt/libiconv/lib/libiconv.a ]; then
454+
echo "--- x86_64 libiconv.a architecture ---"
455+
lipo -info /usr/local/opt/libiconv/lib/libiconv.a
456+
echo "--- x86_64 libiconv.a exported symbols (first 10 with iconv) ---"
457+
nm -gU /usr/local/opt/libiconv/lib/libiconv.a 2>/dev/null | grep -i iconv | head -10 || echo "No symbols"
458+
fi
459+
echo "--- arm64 Homebrew libiconv ---"
460+
ls -la /opt/homebrew/opt/libiconv/lib/ 2>/dev/null || echo "Not installed"
461+
if [ -f /opt/homebrew/opt/libiconv/lib/libiconv.a ]; then
462+
echo "--- arm64 libiconv.a architecture ---"
463+
lipo -info /opt/homebrew/opt/libiconv/lib/libiconv.a
464+
echo "--- arm64 libiconv.a exported symbols (first 10 with iconv) ---"
465+
nm -gU /opt/homebrew/opt/libiconv/lib/libiconv.a 2>/dev/null | grep -i iconv | head -10 || echo "No symbols"
466+
fi
423467
424-
echo "=== DEBUG: What iconv symbols does libintl.a need? ==="
425-
echo "--- Undefined symbols in our libintl.a (looking for iconv) ---"
426-
nm -u libintl.a 2>/dev/null | grep -i iconv || echo "No iconv references found"
427-
428-
echo "=== DEBUG: System libiconv location and architecture ==="
429-
echo "--- /usr/lib/libiconv* ---"
430-
ls -la /usr/lib/libiconv* 2>/dev/null || echo "No /usr/lib/libiconv*"
431-
for f in /usr/lib/libiconv*; do
432-
echo "--- lipo -info $f ---"
433-
lipo -info "$f" 2>/dev/null || file "$f" 2>/dev/null || echo "Cannot inspect $f"
434-
done
435-
436-
echo "=== DEBUG: Homebrew libiconv (if installed) ==="
437-
echo "--- /usr/local/opt/libiconv ---"
438-
ls -la /usr/local/opt/libiconv/lib/ 2>/dev/null || echo "No x86_64 Homebrew libiconv"
439-
echo "--- /opt/homebrew/opt/libiconv ---"
440-
ls -la /opt/homebrew/opt/libiconv/lib/ 2>/dev/null || echo "No arm64 Homebrew libiconv"
441-
442-
echo "=== DEBUG: What libiconv.a files exist in common paths? ==="
443-
find /usr/lib /usr/local /opt/homebrew -name 'libiconv*' -type f 2>/dev/null || echo "Find failed"
444-
445-
echo "=== DEBUG: System iconv symbols ==="
446-
echo "--- Symbols exported by /usr/lib/libiconv.2.dylib (first 20 with iconv) ---"
447-
nm -gU /usr/lib/libiconv.2.dylib 2>/dev/null | grep -i iconv | head -20 || echo "Cannot read symbols"
448-
449-
echo "=== DEBUG: Current directory contents ==="
450-
ls -la *.a 2>/dev/null || echo "No .a files in current directory"
451-
452-
echo "=== DEBUG: gettext package info ==="
468+
echo ""
469+
echo "=== 6. SYMBOL NAME COMPARISON ==="
470+
echo "The critical question: do symbol names match?"
471+
echo "--- libintl.a NEEDS these undefined symbols: ---"
472+
nm -u libintl.a 2>/dev/null | grep -i iconv | sort -u
473+
echo "--- System /usr/lib/libiconv.2.dylib EXPORTS: ---"
474+
nm -gU /usr/lib/libiconv.2.dylib 2>/dev/null | grep -i iconv | head -5 || echo "Cannot read"
475+
echo "--- Homebrew arm64 libiconv.a EXPORTS: ---"
476+
nm -gU /opt/homebrew/opt/libiconv/lib/libiconv.a 2>/dev/null | grep -i iconv | head -5 || echo "Cannot read"
477+
478+
echo ""
479+
echo "=== 7. GETTEXT PACKAGE INFO ==="
453480
echo "--- x86_64 gettext ---"
454-
arch -x86_64 /usr/local/bin/brew info gettext 2>/dev/null | head -10 || echo "Cannot get info"
481+
arch -x86_64 /usr/local/bin/brew info gettext 2>/dev/null | head -15 || echo "Cannot get info"
455482
echo "--- arm64 gettext ---"
456-
brew info gettext 2>/dev/null | head -10 || echo "Cannot get info"
457-
echo "=== END DEBUG ==="
483+
brew info gettext 2>/dev/null | head -15 || echo "Cannot get info"
484+
485+
echo ""
486+
echo "========================================================"
487+
echo "=== END DIAGNOSTICS ==="
488+
echo "========================================================"
458489
459490
- name: Log in to Azure
460491
uses: azure/login@v2
@@ -533,15 +564,19 @@ jobs:
533564
# used in 'git version --build-options'. We'll fix that in code.
534565
HOST_CPU = universal
535566
BASIC_CFLAGS += -arch arm64 -arch x86_64
567+
568+
# CRITICAL FIX: Disable USE_HOMEBREW_LIBICONV
569+
# On Darwin 24+ (macOS 15), config.mak.uname sets USE_HOMEBREW_LIBICONV
570+
# which causes ICONVDIR to point to Homebrew's libiconv. But Homebrew's
571+
# libiconv exports _libiconv/_libiconv_open symbols (with prefix), while
572+
# Homebrew's gettext/libintl was built against system iconv which uses
573+
# _iconv/_iconv_open symbols (no prefix). We must use the system's
574+
# /usr/lib/libiconv.dylib which is universal and has the correct symbols.
575+
USE_HOMEBREW_LIBICONV =
576+
ICONVDIR =
536577
EOF
537578
538579
# Configure the Git build to find our universal libintl.a
539-
# Note: We do NOT add -liconv to LDFLAGS because that would cause the
540-
# linker to find Homebrew's libiconv.a (which exports _libiconv symbols)
541-
# before the system's libiconv.dylib (which exports _iconv symbols).
542-
# Homebrew's gettext/libintl was built against system iconv, so it
543-
# expects _iconv symbols. The Makefile already adds -liconv which will
544-
# correctly find the system's universal /usr/lib/libiconv.dylib.
545580
homebrew_prefix="$(brew --prefix)"
546581
cat >>git/config.mak <<EOF
547582
CFLAGS = -I$homebrew_prefix/include -I/usr/local/opt/gettext/include
@@ -562,26 +597,46 @@ jobs:
562597
# To make use of the catalogs...
563598
export XML_CATALOG_FILES=$homebrew_prefix/etc/xml/catalog
564599
565-
# === DEBUGGING: Show config.mak and build environment ===
566-
echo "=== DEBUG: Contents of git/config.mak ==="
600+
# === PRE-BUILD DIAGNOSTICS ===
601+
echo "========================================================"
602+
echo "=== PRE-BUILD DIAGNOSTICS ==="
603+
echo "========================================================"
604+
echo ""
605+
echo "=== Contents of git/config.mak ==="
567606
cat git/config.mak
568-
echo "=== DEBUG: Current working directory ==="
607+
echo ""
608+
echo "=== Current working directory ==="
569609
pwd
570-
echo "=== DEBUG: .a files in current directory ==="
610+
echo "=== .a files in current directory ==="
571611
ls -la *.a 2>/dev/null || echo "No .a files"
572-
echo "=== DEBUG: Library search paths ==="
573-
echo "LDFLAGS will expand $(pwd) to: $(pwd)"
574-
echo "=== END PRE-BUILD DEBUG ==="
612+
echo "=== Verify libintl.a is here and universal ==="
613+
lipo -info libintl.a 2>/dev/null || echo "libintl.a not found!"
614+
echo "========================================================"
575615
576616
make -C git -j$(sysctl -n hw.physicalcpu) V=1 GIT-VERSION-FILE dist dist-doc 2>&1 | tee build.log || {
577-
echo "=== BUILD FAILED - Showing last 100 lines of build.log ==="
617+
echo ""
618+
echo "========================================================"
619+
echo "=== BUILD FAILED ==="
620+
echo "========================================================"
621+
echo ""
622+
echo "=== Last 100 lines of build.log ==="
578623
tail -100 build.log
579-
echo "=== DEBUG: Searching for link command in log ==="
580-
grep -A5 "LINK git" build.log || echo "No LINK git found"
581-
echo "=== DEBUG: Searching for -liconv in log ==="
582-
grep -- "-liconv" build.log | head -10 || echo "No -liconv found"
583-
echo "=== DEBUG: Searching for -lintl in log ==="
584-
grep -- "-lintl" build.log | head -10 || echo "No -lintl found"
624+
echo ""
625+
echo "=== Searching for the actual LINK command that failed ==="
626+
grep -B2 "Undefined symbols" build.log | head -20 || echo "Pattern not found"
627+
echo ""
628+
echo "=== All -L flags in link commands ==="
629+
grep -oE '\-L[^ ]+' build.log | sort -u | head -20 || echo "No -L flags found"
630+
echo ""
631+
echo "=== All -l flags in link commands ==="
632+
grep -oE '\-l[a-zA-Z0-9_]+' build.log | sort -u | head -20 || echo "No -l flags found"
633+
echo ""
634+
echo "=== Lines containing ICONVDIR ==="
635+
grep -i iconvdir build.log | head -10 || echo "No ICONVDIR references"
636+
echo ""
637+
echo "=== Lines containing libiconv ==="
638+
grep -i libiconv build.log | head -10 || echo "No libiconv references"
639+
echo "========================================================"
585640
exit 1
586641
}
587642

0 commit comments

Comments
 (0)