cac1fca3406536a9f42965bbbebc101b62d8d8e3
braney
  Wed Sep 9 18:01:54 2026 -0700
submoduleSetup: anchor on kent/src so it works from either caller's cwd

Every path in submoduleSetup is relative to kent/src, but its two callers
invoke it from different directories: src/makefile runs
./submodules/submoduleSetup from src, while userApps/fetchKentSource.sh cds
into src/submodules first and runs ./submoduleSetup.

Since the zlib-ng change this broke the userApps source build.  From
src/submodules the guard "[ ! -e submodules/zlib-ng/Makefile ]" is true
because that path cannot exist there, so the configure block ran and its
redirect to submodules/zlib-ng-configure.log failed on a missing directory:

./submoduleSetup: line 41: submodules/zlib-ng-configure.log:
No such file or directory
Error: zlib-ng configure failed, see submodules/zlib-ng-configure.log
make: *** [Makefile:28: fetchSource] Error 1

The htslib serial-probe block added for the AVX2 -j race has the same path
problem, but its guard is not negated, so from src/submodules it silently
tested a path that could not exist and never ran at all -- leaving the
userApps build exposed to the very race that block exists to prevent.

Fix both by cd'ing to the script's own parent directory up front, so the
caller's cwd no longer matters.  Verified from both call sites: the
userApps path now configures zlib-ng and pre-generates htscodecs.mk with
correct probe flags (HTS_CFLAGS_AVX2 = -mavx2 -mpopcnt), and a re-run from
src is a quiet no-op.

refs #38125

diff --git src/submodules/submoduleSetup src/submodules/submoduleSetup
index b3d12f06d6a..3be933f5428 100755
--- src/submodules/submoduleSetup
+++ src/submodules/submoduleSetup
@@ -1,74 +1,82 @@
 #!/bin/bash
 set -beEu -o pipefail
 
 # Do required submodule setup to support building the browser
 # Sync submodules to the commits pinned by the parent repo, and check for
 # having remains of old htslib copy to deal with switch from old version.
 
+# Every path below is relative to kent/src, but callers reach this script from
+# different directories: src/makefile runs ./submodules/submoduleSetup from
+# src, while userApps/fetchKentSource.sh cds into src/submodules first.  Anchor
+# on kent/src ourselves so the caller's cwd does not matter.  Without this the
+# zlib-ng configure below died on its own log path, and the htslib probe guard
+# silently tested a path that could not exist and so never ran.  refs #38125
+cd "$(dirname "$0")/.."
+
 if [ -e htslib ] ; then
     echo "*********************************************************************" >&2
     echo "Note: an outdated kent/src/htslib/ exists in the working tree." >&2
     echo "      It is no longer used and can be removed."   >&2
     echo "*********************************************************************" >&2
 fi
 
 if git rev-parse --is-inside-work-tree >/dev/null 2>&1 ; then
     # Sync submodules to the commits pinned by the parent repo on every build,
     # not just on first-time init, so a moved pointer (e.g. after a pull) is
     # always checked out.  --init covers the first-time case, --recursive also
     # updates the nested htscodecs submodule.  git is silent when already in sync.
     git -c protocol.file.allow=always submodule update --init --recursive
 elif [ ! -e submodules/htslib/hts.c -o ! -e submodules/htslib/htscodecs/htscodecs/htscodecs.c \
        -o ! -e submodules/zlib-ng/deflate.c ] ; then
     # not a git working tree (e.g. a source release); submodule sources must
     # already be present since they can not be checked out without git.
     echo "Error: submodule sources under submodules/ are missing and this" >&2
     echo "       is not a git working tree, so they can not be initialized." >&2
     exit 1
 fi
 
 # Configure zlib-ng, which has no Makefile until its configure script runs.
 # --zlib-compat gives the ordinary zlib API and symbol names, so libpng, htslib
 # and our own code need no change.  --static builds only libz.a, which is all we
 # link.  configure compiles every SIMD variant and picks one at run time, so a
 # single build serves both the AVX-512 machines and the AVX2 ones, and on ARM it
 # picks up NEON and the ARMv8 CRC instructions.  Done here, serially, for the
 # same reason as the htslib probe below: the parallel build must not race on it.
 # refs #38125
 if [ ! -e submodules/zlib-ng/Makefile ] ; then
     echo "Note: configuring zlib-ng (serial, once)" >&2
     # log kept outside the submodule so it does not show up as untracked there
     (cd submodules/zlib-ng && ./configure --zlib-compat --static) \
         > submodules/zlib-ng-configure.log 2>&1 \
         || { echo "Error: zlib-ng configure failed, see submodules/zlib-ng-configure.log" >&2 ; exit 1 ; }
     # zlib-ng's own .gitignore does not cover everything its configure writes, so
     # ignore the rest locally rather than carrying a patch to upstream.  This is
     # the submodule's private exclude file, not a tracked one.
     zngExclude=$(cd submodules/zlib-ng && git rev-parse --git-path info/exclude 2>/dev/null || true)
     if [ -n "$zngExclude" ] ; then
         mkdir -p "$(dirname "$zngExclude")" 2>/dev/null || true
         for f in zlib.h zlib_name_mangling.h test.c ; do
             grep -qxF "$f" "$zngExclude" 2>/dev/null || echo "$f" >> "$zngExclude"
         done
     fi
 fi
 
 # Generate htslib's compiler-probe makefile fragment (htscodecs.mk) and config.h
 # SERIALLY, here, before the parallel ("make -j") build descends into htslib.
 # hts_probe_cc.sh probes SIMD (SSE4/AVX2/AVX512) support using fixed-name
 # conftest.* temp files in submodules/htslib/.  Under -j, a concurrent writer
 # can clobber conftest.c between its creation and compilation, so the AVX2 probe
 # "succeeds" with no -mavx2 flag; that records HTS_BUILD_AVX2=1 with an empty
 # HTS_CFLAGS_AVX2 in htscodecs.mk.  config.h then defines HAVE_AVX2, enabling
 # AVX2 source that is compiled without -mavx2 -> "target specific option
 # mismatch" build failure.  Both files are no-prerequisite make targets, so the
 # corrupt result is cached and reused until deleted.  Building them single-
 # threaded here guarantees the probe runs exactly once and the -j build never
 # triggers it.  Only done when they are missing, so it does not force needless
 # htslib recompiles on incremental builds.
 if [ -e submodules/htslib/Makefile ] && \
    { [ ! -e submodules/htslib/htscodecs.mk ] || [ ! -e submodules/htslib/config.h ]; } ; then
     echo "Note: pre-generating htslib htscodecs.mk and config.h (serial; avoids -j probe race)" >&2
     make -C submodules/htslib -j1 htscodecs.mk config.h >/dev/null
 fi