@@ -132,36 +132,38 @@ CHECK_INSTALL_STAGE = $(abs_top_builddir)/.install-stage
132132
133133check-install-layout :
134134 @echo " === check-install-layout: staged install must hide details/ and *_impl.hpp ==="
135- @rm -rf $(CHECK_INSTALL_STAGE )
136- @$(MAKE ) $(AM_MAKEFLAGS ) install DESTDIR=$(CHECK_INSTALL_STAGE ) > check-install.log 2>&1 || { \
137- echo " FAIL: staged install failed" ; \
138- cat check-install.log; \
139- rm -f check-install.log; \
135+ @if test " $( CHECK_INSTALL_SHARED) " ! = " yes" ; then \
140136 rm -rf $(CHECK_INSTALL_STAGE ) ; \
141- exit 1; \
142- }
143- @rm -f check-install.log
137+ $(MAKE ) $(AM_MAKEFLAGS ) install DESTDIR=$(CHECK_INSTALL_STAGE ) > check-install.log 2>&1 || { \
138+ echo " FAIL: staged install failed" ; \
139+ cat check-install.log; \
140+ rm -f check-install.log; \
141+ rm -rf $(CHECK_INSTALL_STAGE ) ; \
142+ exit 1; \
143+ }; \
144+ rm -f check-install.log; \
145+ fi
144146 @leaked_details=` find $( CHECK_INSTALL_STAGE) -type d -name details 2> /dev/null` ; \
145147 if test -n " $$ leaked_details" ; then \
146148 echo " FAIL: details/ directory leaked into install:" ; \
147149 echo " $$ leaked_details" ; \
148- rm -rf $(CHECK_INSTALL_STAGE ) ; \
150+ if test " $( CHECK_INSTALL_SHARED ) " ! = " yes " ; then rm -rf $( CHECK_INSTALL_STAGE) ; fi ; \
149151 exit 1; \
150152 fi
151153 @leaked_impl=` find $( CHECK_INSTALL_STAGE) -name ' *_impl.hpp' 2> /dev/null` ; \
152154 if test -n " $$ leaked_impl" ; then \
153155 echo " FAIL: *_impl.hpp file leaked into install:" ; \
154156 echo " $$ leaked_impl" ; \
155- rm -rf $(CHECK_INSTALL_STAGE ) ; \
157+ if test " $( CHECK_INSTALL_SHARED ) " ! = " yes " ; then rm -rf $( CHECK_INSTALL_STAGE) ; fi ; \
156158 exit 1; \
157159 fi
158160 @umbrella_count=` find $( CHECK_INSTALL_STAGE) -name ' httpserver.hpp' | wc -l | tr -d ' ' ` ; \
159161 if test " $$ umbrella_count" ! = " 1" ; then \
160162 echo " FAIL: expected exactly 1 installed httpserver.hpp, got $$ umbrella_count" ; \
161- rm -rf $(CHECK_INSTALL_STAGE ) ; \
163+ if test " $( CHECK_INSTALL_SHARED ) " ! = " yes " ; then rm -rf $( CHECK_INSTALL_STAGE) ; fi ; \
162164 exit 1; \
163165 fi
164- @rm -rf $(CHECK_INSTALL_STAGE )
166+ @if test " $( CHECK_INSTALL_SHARED ) " ! = " yes " ; then rm -rf $(CHECK_INSTALL_STAGE ) ; fi
165167 @echo " PASS: staged install layout is clean"
166168
167169# ---------------------------------------------------------------------------
@@ -200,13 +202,33 @@ CHECK_HYGIENE_STAGE = $(abs_top_builddir)/.hygiene-stage
200202CHECK_HYGIENE_CXX = $(CXX ) -std=c++20 -E -I$(CHECK_HYGIENE_STAGE )$(includedir ) $(CPPFLAGS )
201203HEADER_HYGIENE_STRICT ?= no
202204
203- check-hygiene :
204- @echo " === check-hygiene: <httpserver.hpp> must not transitively include backend headers ==="
205+ # Sentinel file: only re-run the staged install when headers have changed.
206+ # This is an mtime gate used exclusively for standalone `make check-hygiene`
207+ # invocations — it avoids paying a full `make install` cost on every
208+ # repeated standalone run. When check-local drives check-hygiene it sets
209+ # CHECK_HYGIENE_SHARED=yes and passes CHECK_HYGIENE_STAGE pointing at its
210+ # own pre-built shared stage, so this stamp target is bypassed entirely.
211+ HYGIENE_STAMP = $(CHECK_HYGIENE_STAGE ) /.hygiene-stamp
212+
213+ $(HYGIENE_STAMP ) : $(wildcard $(top_srcdir ) /src/httpserver/* .hpp)
205214 @rm -rf $(CHECK_HYGIENE_STAGE )
206215 @$(MAKE ) $(AM_MAKEFLAGS ) install DESTDIR=$(CHECK_HYGIENE_STAGE ) > check-hygiene-install.log 2>&1 || { \
207216 echo " FAIL: staged install failed" ; cat check-hygiene-install.log; \
208217 rm -f check-hygiene-install.log; rm -rf $(CHECK_HYGIENE_STAGE ) ; exit 1; }
209218 @rm -f check-hygiene-install.log
219+ @touch $(HYGIENE_STAMP )
220+
221+ check-hygiene :
222+ @echo " === check-hygiene: <httpserver.hpp> must not transitively include backend headers ==="
223+ @if test " $( CHECK_HYGIENE_SHARED) " ! = " yes" ; then \
224+ $(MAKE ) $(AM_MAKEFLAGS ) $(HYGIENE_STAMP ) ; \
225+ else \
226+ if ! test -d " $( CHECK_HYGIENE_STAGE) " ; then \
227+ echo " FAIL: CHECK_HYGIENE_SHARED=yes but stage dir '$( CHECK_HYGIENE_STAGE) ' does not exist." ; \
228+ echo " Always pair CHECK_HYGIENE_SHARED=yes with CHECK_HYGIENE_STAGE=<valid-dir>." ; \
229+ exit 1; \
230+ fi ; \
231+ fi
210232 @status=0; \
211233 if ! $( CHECK_HYGIENE_CXX) $( top_srcdir) /test/headers/consumer_umbrella_no_backend.cpp > check-hygiene.i 2> check-hygiene.err; then \
212234 if test " $( HEADER_HYGIENE_STRICT) " = " yes" ; then \
@@ -220,7 +242,7 @@ check-hygiene:
220242 sed ' s/^/ /' check-hygiene.err | tail -10; \
221243 fi ; \
222244 else \
223- leaks=` grep -hE ' ^# [0-9]+ "[^"]*($(HEADER_HYGIENE_FORBIDDEN))"' check-hygiene.i | awk ' {print $$3}' | sort -u` ; \
245+ leaks=` grep -hE ' ^# [0-9]+ "[^"]*/ ($(HEADER_HYGIENE_FORBIDDEN))"' check-hygiene.i | awk ' {print $$3}' | sort -u` ; \
224246 if test -n " $$ leaks" ; then \
225247 if test " $( HEADER_HYGIENE_STRICT) " = " yes" ; then \
226248 echo " FAIL: forbidden headers leaked through <httpserver.hpp>:" ; \
@@ -235,16 +257,35 @@ check-hygiene:
235257 fi ; \
236258 fi ; \
237259 rm -f check-hygiene.i check-hygiene.err; \
238- rm -rf $(CHECK_HYGIENE_STAGE ) ; \
239260 exit $$ status
240261
241- check-local : check-headers check-install-layout check-hygiene
262+ # check-local runs check-install-layout and check-hygiene against a single
263+ # shared staged install to avoid paying two full `make install` costs on
264+ # every `make check`. Both sub-checks can still be invoked standalone (they
265+ # will do their own install when CHECK_*_SHARED is not set).
266+ check-local : check-headers
267+ @echo " === Shared staged install for check-install-layout and check-hygiene ==="
268+ @rm -rf $(abs_top_builddir ) /.shared-check-stage
269+ @$(MAKE ) $(AM_MAKEFLAGS ) install DESTDIR=$(abs_top_builddir ) /.shared-check-stage > check-shared-install.log 2>&1 || { \
270+ echo " FAIL: shared staged install failed" ; cat check-shared-install.log; \
271+ rm -f check-shared-install.log; rm -rf $(abs_top_builddir ) /.shared-check-stage; exit 1; }
272+ @rm -f check-shared-install.log
273+ @$(MAKE ) $(AM_MAKEFLAGS ) check-install-layout \
274+ CHECK_INSTALL_STAGE=$(abs_top_builddir ) /.shared-check-stage \
275+ CHECK_INSTALL_SHARED=yes
276+ @$(MAKE ) $(AM_MAKEFLAGS ) check-hygiene \
277+ CHECK_HYGIENE_STAGE=$(abs_top_builddir ) /.shared-check-stage \
278+ CHECK_HYGIENE_SHARED=yes
279+ @rm -rf $(abs_top_builddir ) /.shared-check-stage
242280
243281.PHONY : check-headers check-install-layout check-hygiene
244282
245283MOSTLYCLEANFILES = $(DX_CLEANFILES ) *.gcda *.gcno *.gcov
246284DISTCLEANFILES = DIST_REVISION
247285
286+ clean-local :
287+ rm -rf $(CHECK_HYGIENE_STAGE ) $(abs_top_builddir ) /.shared-check-stage $(CHECK_INSTALL_STAGE )
288+
248289pkgconfigdir = $(libdir ) /pkgconfig
249290pkgconfig_DATA = libhttpserver.pc
250291
0 commit comments