af126b8f0cf9ddc553a78869a3c820a4bd4fdc59
braney
  Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125

Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.

Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.

This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.

Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.

diff --git src/makefile src/makefile
index 5063b868a3a..de267ff054f 100644
--- src/makefile
+++ src/makefile
@@ -8,34 +8,41 @@
 
 beta: check-beta clean
 	${MAKE} cgi-beta
 
 # do a git update and clean
 update:
 	${GIT} pull
 	${MAKE} clean
 ##
 # topLibs
 ##
 TOP_LIBS = lib parasol/lib submodules/htslib
 ifneq ($(wildcard jkOwnLib/*),)
   TOP_LIBS += jkOwnLib
 endif
-topLibs: ${TOP_LIBS:%=%.topLibs}
+topLibs: zlibNg ${TOP_LIBS:%=%.topLibs}
 %.topLibs: topChecks
 	${MAKE} -C $*
 
+# zlib-ng is a submodule but it is not in TOP_LIBS, because its default target
+# builds the shared library and the test programs too and we only link libz.a.
+# Its Makefile is written by configure, which topChecks runs.  refs #38125
+.PHONY: zlibNg
+zlibNg: topChecks
+	${MAKE} -C submodules/zlib-ng libz.a
+
 .PHONY: topChecks
 topChecks:
 	@./checkUmask.sh
 	@./checkCompileFlags.sh
 	@MACHTYPE=${MACHTYPE} ./machTest.sh
 	@./submodules/submoduleSetup
 
 optLib:
 	cd optimalLeaf && ${MAKE}
 
 ##
 # hgLib
 ##
 ifneq ($(wildcard hg/makefile),)
    HGLIB_DIRS += hg/lib
@@ -99,30 +106,31 @@
 userApps: ${USER_APP_DIRS:%=%.userApps} ${ALMOST_USER_APP_DIRS:%=%.almostUserApps}
 
 %.userApps: topLibs hgLib destBin
 	${MAKE} -C $* userApps
 
 # these dont have userApps targets
 %.almostUserApps: topLibs hgLib destBin
 	${MAKE} -C $*
 
 destBin:
 	${MKDIR} ${DESTBINDIR}
 
 CLEAN_DIRS = ${STD_DIRS} lib hg jkOwnLib submodules/htslib utils webBat isPcr
 
 clean: ${CLEAN_DIRS:%=%.clean}
+	if [ -e submodules/zlib-ng/Makefile ] ; then ${MAKE} -C submodules/zlib-ng clean ; fi
 	find . -name \*.o -print | xargs --no-run-if-empty rm
 	rm -f tags TAGS
 	rm -f cscope.out cscope.files cscope.po.out
 
 %.clean:
 	if [ -e "$*/makefile" ] ; then ${MAKE} -C $* clean ; fi
 
 
 TEST_DIRS = blat gfServer hg lib utils
 test:: $(TEST_DIRS:%=%.test)
 %.test:
 	if test -d $* ; then ${MAKE} -C $* test; fi
 
 LIB_TAGS_IN = lib/*.[hc] */lib/*.[hc] */*/lib/*.[hc] */*/*/lib/*.[hc] jkOwnLib/*.c \
 	inc/*.h */inc/*.h */*/inc/*.h */*/*/inc/*.h */cgilib/*.[hc]