caab4045fa20627f1602955c53cacc05ea07de24
braney
  Fri Aug 14 11:01:17 2026 -0700
stop directory makefiles from overriding the tree compiler flags, refs #38094

hg/hgTracks/makefile has carried "COPT = -ggdb" since 2019-02-01.  Every
directory makefile includes inc/common.mk on its first line, so that
assignment came after the tree default and replaced it.  The result is that
hgTracks itself has shipped with no optimization for seven years, while every
library it links against was built with -O3.  Building it with the tree
default is 17.5% faster over a set of eight sessions, and 1.95x faster on a
wide clinical view, with byte identical PNG output.

Twenty three makefiles had a COPT or CFLAGS override.  All are removed here.
hg/visiGene/vgPrepImage keeps its defines, but appends them with += instead
of assigning over the tree flags, because the ERMapper JPEG2000 headers need
them.

Compiling hg/hgTracks with optimization exposed seven errors that only appear
under -O3.  Four source files are fixed: hgTracks.c used an uninitialized
labelfont, expRatioTracks.c and simpleTracks.c had five strncpy calls that
could leave a string unterminated, and netTrack.c had two int buffers too
small to hold the value written into them.  The last two look like real
latent bugs, not warning noise.

checkCompileFlags.sh is added to stop this from recurring.  The topChecks
target runs it, so every build path reaches it.  It fails the build on any
COPT assignment, any CFLAGS assignment that is not +=, and any CFLAGS +=
carrying an -O flag.  The check cannot live in inc/common.mk, because at the
point common.mk is parsed the overriding line has not been read yet.  A
command line override such as "make COPT='-O0 -g'" still works, since the
check reads only file contents.

The 2026 conversion of the tree to -O3 did not find this.  That work was
driven by the warnings -O3 produces, and a directory that overrides COPT
never receives the flag, so it never warns.

Verified: the tree builds at -O3 with no new errors and no new warnings, and
80 rendered images compare pixel identical against the old build.

diff --git src/makefile src/makefile
index d5da91726b5..5063b868a3a 100644
--- src/makefile
+++ src/makefile
@@ -1,201 +1,202 @@
 include inc/localEnvironment.mk
 include inc/common.mk
 
 all: utils cgi blatSuite
 
 alpha: clean
 	${MAKE} utils-alpha cgi-alpha blatSuite
 
 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: topChecks
 	${MAKE} -C $*
 
 .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
    HGLIB_CHECK = hgLibChecks
 endif
 ifneq ($(wildcard hg/cgilib/makefile),)
    HGLIB_DIRS += hg/cgilib
 endif
 
 hgLib: ${HGLIB_CHECK} | ${HGLIB_DIRS:%=%.hgLib}
 %.hgLib:
 	${MAKE} -C $*
 hgLibChecks:
 	@./hg/sqlEnvTest.sh
 
 libs: topLibs hgLib optLib
 
 cgi: libs
 	cd hg && ${MAKE} cgi
 	cd utils/bedToBigBed && ${MAKE} cgi
 
 cgi-alpha: libs logUser
 	cd hg && ${MAKE} alpha
 	cd utils/bedToBigBed && ${MAKE} alpha
 
 cgi-beta: check-beta libs logUser
 	cd hg && ${MAKE} beta
 	cd utils/bedToBigBed && ${MAKE} beta
 
 # This log file can be useful when debugging problems on the alpha and beta builds.
 logUser:
 ifeq (${IS_HGWDEV},yes)
 	echo ${USER}, $(MAKECMDGOALS), `date` >> ${CGI_BIN}/buildLog.txt
 endif
 
 check-beta:
 	# this will fail if we are not in a beta checkout:
 	${GIT} branch | egrep '\* v[0-9]+_branch' > /dev/null	
 
 BLAT_SUITE_DIRS = blat gfClient gfServer webBlat hg/pslPretty hg/pslReps \
 	hg/pslSort utils/nibFrag utils/faToNib utils/faToTwoBit utils/twoBitToFa \
 	utils/twoBitInfo isPcr blatz
 
 blatSuite: ${BLAT_SUITE_DIRS:%=%.blatSuite}
 
 %.blatSuite: topLibs hgLib
 	 ${MAKE} -C $*
 
 # all of these application makefiles have been updated to include use
 #	of DESTDIR and BINDIR
 
 # common subdirs uses by multiple targets
 STD_DIRS = ameme index dnaDust protDust weblet aladdin primeMate fuse meta tagStorm \
 	tabFile parasol blat
 
 USER_APP_DIRS = utils parasol hg hg/utils \
 	hg/makeDb tabFile
 ALMOST_USER_APP_DIRS = blat gfClient gfServer isPcr ameme index/ixIxx utils/userApps
 
 .PHONY: userApps
 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}
 	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]
 
 # build tags for libraries
 .PHONY: tags
 tags:
 	ctags ${LIB_TAGS_IN}
 
 cscope.out:
 	find `pwd` -name '*.c' -o -name '*.h' > cscope.files
 	cscope -qRb `cat cscope.files`
 search: cscope.out
 	cscope -d
 
 # build emacs tags for libraries
 .PHONY: etags
 etags:
 	etags ${LIB_TAGS_IN}
 
 # build tags for all files
 .PHONY: tags-all
 tags-all:
 	find . -name '*.[ch]' | grep -v "/userApps/" | ctags -L -
 
 # build emacs tags for all files
 .PHONY: etags-all
 etags-all:
 	find . -name '*.[ch]' | etags -
 
 UTILS_DIRS = ${DIRS} utils
 .PHONY: utils
 utils: ${UTILS_DIRS:%=%.utils} ${STD_DIRS:%=%.utils}
 
 %.utils: libs destBin hgutils
 	@${MKDIR} ${SCRIPTS}
 	${MAKE} -C $*
 
 utils-alpha: ${UTILS_DIRS:%=%.utils-alpha}
 
 %.utils-alpha: libs destBin hgutils
 	if [ -e "$*/makefile" ] ; then ${MAKE} -C $* ; fi
 
 hgutils: libs destBin
 	cd hg && ${MAKE} utils
 
 ##  cellar archive for obsolete programs
 
 cellarDirs = cdnaAli getgene idbQuery reformat scanIntrons tracks wormAli \
 	xenoAli
 
 buildCellar: $(cellarDirs:%=%.cellar)
 
 %.cellar: libs destBin
 	cd $* && echo $* && $(MAKE)
 
 cleanCellar: $(cellarDirs:%=%.cellarClean)
 %.cellarClean:
 	cd $* && echo $* && $(MAKE) clean
 
 ## top level target for everything html related
 DOCS_LIST = hg/htdocs hg/js hg/htdocs/style
 doc: ${DOCS_LIST:%=%.docuser}
 %.docuser:
 	cd $* && $(MAKE)
 
 doc-alpha: ${DOCS_LIST:%=%.docalpha}
 %.docalpha:
 	cd $* && $(MAKE) alpha
 
 doc-beta: ${DOCS_LIST:%=%.docbeta}
 %.docbeta:
 	cd $* && $(MAKE) beta
 
 doc-install: ${DOCS_LIST:%=%.docinstall}
 %.docinstall:
 	cd $* && $(MAKE) install