|
9 | 9 | @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export CCACHE_PATH=@CCACHE_PATH@ |
10 | 10 | @NUT_AM_MAKE_CAN_EXPORT@@NUT_AM_EXPORT_CCACHE_PATH@export PATH=@PATH_DURING_CONFIGURE@ |
11 | 11 |
|
12 | | -# First target often defines default behavior: all |
13 | | -# We follow up with another pass to `make doc` because our wild recipes |
14 | | -# sometimes preclude generating all of them on the first pass (FIXME!) |
15 | | -# missing e.g. PDF and HTML which then pop up in `make check` footprint, |
16 | | -# or misses a .prep-src-docs stage needed to pattern-make man page files |
17 | | -# with some "make" implementations... |
18 | | -all all-am-local all-local: all-recursive |
19 | | - +@$(MAKE) $(AM_MAKEFLAGS) doc |
20 | | - +@$(MAKE) $(AM_MAKEFLAGS) doc |
21 | | - |
22 | 12 | # include directory for aclocal |
23 | 13 | ACLOCAL_AMFLAGS = -I m4 |
24 | 14 |
|
25 | | -# subdirectories to build and distribute. The order matters, as |
26 | | -# several subdirectories depend on stuff in "common" or tools being built first |
27 | | -SUBDIRS = include common clients conf data docs drivers tools \ |
28 | | - lib scripts server tests |
| 15 | +# Autotools' SUBDIRS (our values are listed below) allow for powerful recursive |
| 16 | +# recipe automation, with one notable weakness: the dirs are processed in a |
| 17 | +# loop sequentially, even in parallel builds (each such sub-make is parallel |
| 18 | +# then). In our case, the HTML/PDF render of ChangeLog can take a minute of |
| 19 | +# work in "docs" while we are not building anything in other dirs. On the up |
| 20 | +# side, that approach does allow for dirs with dependencies to get built first |
| 21 | +# deterministically. For more details search for "am__recursive_targets" in the |
| 22 | +# generated Makefile. |
| 23 | +# |
| 24 | +# The commonly suggested way out of this predicament is to consolidate numerous |
| 25 | +# Makefile.am recipes into one, which alone properly defines all the needed |
| 26 | +# interdependecies that are "known" to one instance of the `make` process. |
| 27 | +# This however loses the ability to quickly e.g. `cd tests && make check`, so |
| 28 | +# the next layer is to re-introduce Makefiles in sub-directories that define |
| 29 | +# a few popular targets to perform via the one big top-level Makefile. |
| 30 | +# |
| 31 | +# Our approach here is to merge the two solutions: do use SUBDIRS the way |
| 32 | +# autotools handle them for the hordes of `*-recursive` targets for us, but |
| 33 | +# define more explicitly the targets for hot code paths (all, check) so that |
| 34 | +# they can run first for certain different directories (in parallel if asked |
| 35 | +# to) with "knowledge" of dependencies, and then a bit wastefully maybe re-run |
| 36 | +# those directories via autotools integration. They should be quick no-ops by |
| 37 | +# then in the anticipated common use-cases. |
| 38 | +# |
| 39 | +# List of source subdirectories to build and distribute, used to spawn automake |
| 40 | +# (alas sequential) target recipes. The order matters, as several subdirectories |
| 41 | +# depend on stuff in "common" or tools being built first! |
| 42 | +SUBDIRS = include common clients conf data drivers tools \ |
| 43 | + lib scripts server tests docs |
| 44 | + |
| 45 | +# Note: not generated from SUBDIRS, because not all are recursive: |
| 46 | +SUBDIRS_ALL_RECURSIVE = \ |
| 47 | + all/include \ |
| 48 | + all/common \ |
| 49 | + all/clients \ |
| 50 | + all/conf \ |
| 51 | + all-recursive/data \ |
| 52 | + all/docs/man \ |
| 53 | + all/docs \ |
| 54 | + all-recursive/docs \ |
| 55 | + all/drivers \ |
| 56 | + all/tools/nut-scanner \ |
| 57 | + all/tools/nutconf \ |
| 58 | + all-recursive/tools \ |
| 59 | + all/lib \ |
| 60 | + all-recursive/scripts \ |
| 61 | + all/server \ |
| 62 | + all/tests/NIT \ |
| 63 | + all-recursive/tests |
| 64 | + |
| 65 | +# Library creation happens in a number of subdirectories, may be optional |
| 66 | +# (e.g. C++ ones are not built without a suitable compiler and enablement). |
| 67 | +# List maintenance is aided by this query: |
| 68 | +# git grep -E 'LTLIBRARIES' '*.am' |
| 69 | +SUBDIRS_ALL_LIBS_LOCAL = \ |
| 70 | + all-libs-local/clients \ |
| 71 | + all-libs-local/common \ |
| 72 | + all-libs-local/drivers \ |
| 73 | + all-libs-local/tests \ |
| 74 | + all-libs-local/tools/nut-scanner |
| 75 | + |
| 76 | +# First target often defines default behavior, and in automake is always at least: |
| 77 | +# all: all-recursive |
| 78 | +# with maybe custom dependencies of "all:" from a Makefile.am tacked on too |
| 79 | +# (which used to cause us a lot of headache, building same things twice at |
| 80 | +# the same time). |
| 81 | + |
| 82 | +#all all-recursive all-am-local all-local: all-fanout-maybe |
| 83 | +all-recursive: all-fanout-maybe |
| 84 | + |
| 85 | +# Run the standard build if going sequential (or with unknown MAKEFLAGS), |
| 86 | +# or fanout if parallel (presuming GNU/BSD/Sun make at least): |
| 87 | +all-fanout-maybe: |
| 88 | + +@if [ x"$(NUT_MAKE_SKIP_FANOUT)" = xtrue ] ; then \ |
| 89 | + echo " SUBDIR-MAKE $@: skip optimization for parallel make - NUT_MAKE_SKIP_FANOUT is set" ; exit 0 ; \ |
| 90 | + fi ; \ |
| 91 | + case "-$(MAKEFLAGS) $(AM_MAKEFLAGS)" in \ |
| 92 | + *-j|*-j" "*|*-{j,l}{0,1,2,3,4,5,6,7,8,9}*|*-[jl][0123456789]*|*{-l,--jobs,--load-average,--max-load}" "{-,0,1,2,3,4,5,6,7,8,9}*|*--jobserver*|*--jobs" "[0123456789]*|*--load-average" "[0123456789]*|*--max-load" "[0123456789]*) \ |
| 93 | + echo " SUBDIR-MAKE $@: implement optimization for parallel make as 'make all-fanout-subdirs'" ; \ |
| 94 | + $(MAKE) $(AM_MAKEFLAGS) all-fanout-subdirs ;; \ |
| 95 | + *) echo " SUBDIR-MAKE $@: skip optimization for parallel make - we seem to run sequentially now, seen MAKEFLAGS='$(MAKEFLAGS)' AM_MAKEFLAGS='$(AM_MAKEFLAGS)'" ;; \ |
| 96 | + esac |
| 97 | + |
| 98 | +# We start with a pass to `make all` in `common` dir because our wild recipes |
| 99 | +# (with other subdirs ensuring the libraries they need have been built) can |
| 100 | +# sometimes cause parallel compilation and library generation for same files |
| 101 | +# driven by different make processes that do not know they aim for same goal, |
| 102 | +# with some "make" implementations... |
| 103 | +# Just in case we followed up with "make doc", since our wild recipes could end |
| 104 | +# up writing into same files and so corrupting them (fixes applied, but...) |
| 105 | + |
| 106 | +# FIXME: Alas, we still tend to step on our toes when making everything at |
| 107 | +# once from scratch, so still do benefit from pre-making the libraries: |
| 108 | +all-fanout-staged: |
| 109 | + +$(MAKE) $(AM_MAKEFLAGS) all/include |
| 110 | + +$(MAKE) $(AM_MAKEFLAGS) all/common |
| 111 | + +$(MAKE) $(AM_MAKEFLAGS) all-fanout-libs |
| 112 | + +$(MAKE) $(AM_MAKEFLAGS) all-fanout-subdirs |
| 113 | + |
| 114 | +all-fanout-subdirs: $(SUBDIRS_ALL_RECURSIVE) |
| 115 | + |
| 116 | +all-fanout-libs all-libs-local: $(SUBDIRS_ALL_LIBS_LOCAL) |
| 117 | + |
| 118 | +#all all-am-local all-local: |
| 119 | +# +@cd common && $(MAKE) $(AM_MAKEFLAGS) all |
| 120 | +# +@$(MAKE) $(AM_MAKEFLAGS) all-recursive |
| 121 | +# +@$(MAKE) $(AM_MAKEFLAGS) doc |
| 122 | +# +@$(MAKE) $(AM_MAKEFLAGS) doc |
29 | 123 |
|
30 | 124 | bindir = @bindir@ |
31 | 125 | sbindir = @sbindir@ |
@@ -58,6 +152,122 @@ if KEEP_NUT_REPORT |
58 | 152 | nodist_data_DATA = config.nut_report_feature.log |
59 | 153 | endif |
60 | 154 |
|
| 155 | +# Not too different from automake generated recursive rules at first sight, |
| 156 | +# but here we do not loop all subdirs sequentially - instead, a sub-make |
| 157 | +# (maybe parallel itself and with parallel flags passed) with a certain |
| 158 | +# target in specified dir is the goal, all as separate targets for this |
| 159 | +# level's Makefile: |
| 160 | +SUBDIR_TGT_RULE = ( \ |
| 161 | + TGT="`echo '$@' | awk -F/ '{print $$1}'`" ; \ |
| 162 | + DIR="`echo '$@' | sed 's,^[^/]*/,,'`" ; \ |
| 163 | + echo " SUBDIR-MAKE STARTING: 'make $$TGT' in $$DIR ..." ; \ |
| 164 | + cd "$(abs_builddir)/$${DIR}" && \ |
| 165 | + $(MAKE) $(AM_MAKEFLAGS) "$${TGT}" || { RES=$$?; echo " SUBDIR-MAKE FAILURE: 'make $$TGT' in $$DIR" >&2 ; exit $$RES ; } ; \ |
| 166 | + echo " SUBDIR-MAKE SUCCESS: 'make $$TGT' in $$DIR" ; \ |
| 167 | + ) |
| 168 | + |
| 169 | +# A way to quickly handle SUBDIRS_ALL_LIBS_LOCAL as dependency for all others |
| 170 | +# (aka `make all-libs-local` also in root dir): |
| 171 | +all-libs-local/common: all/include |
| 172 | + +@$(SUBDIR_TGT_RULE) |
| 173 | + |
| 174 | +all-libs-local/clients: all-libs-local/common |
| 175 | + +@$(SUBDIR_TGT_RULE) |
| 176 | + |
| 177 | +all-libs-local/drivers: all-libs-local/common |
| 178 | + +@$(SUBDIR_TGT_RULE) |
| 179 | + |
| 180 | +all-libs-local/tests: all-libs-local/common |
| 181 | + +@$(SUBDIR_TGT_RULE) |
| 182 | + |
| 183 | +all-libs-local/tools/nut-scanner: all-libs-local/drivers all-libs-local/clients |
| 184 | + +@$(SUBDIR_TGT_RULE) |
| 185 | + |
| 186 | +# Handle all SUBDIRS_ALL_RECURSIVE in a way that dependencies can be specified, |
| 187 | +# and portably to different make program implementations. Note we may revisit |
| 188 | +# some dirs via "all-recursive" of a parent after "all" in them first, but it is |
| 189 | +# expected to be a quick no-op (beneficial overall in parallel make situation). |
| 190 | +# NOTE: "lib" dir only delivers pkg-config metadata or legacy scripts for any |
| 191 | +# third-party development to integrate with NUT libs, no library recipes there. |
| 192 | + |
| 193 | +all/include \ |
| 194 | +all/conf \ |
| 195 | +all/docs/man \ |
| 196 | +all/lib \ |
| 197 | +all-recursive/data: |
| 198 | + +@$(SUBDIR_TGT_RULE) |
| 199 | + |
| 200 | +all/docs: |
| 201 | + +@DOCS_NO_MAN=true; export DOCS_NO_MAN; $(SUBDIR_TGT_RULE) |
| 202 | + |
| 203 | +all-recursive/docs: all/docs all/docs/man |
| 204 | + +@$(SUBDIR_TGT_RULE) |
| 205 | + |
| 206 | +# Dependencies below are dictated by who needs whose library from another dir |
| 207 | +# (generated by a sub-make there, so we pre-emptively ensure it exists to avoid |
| 208 | +# conflicts of several make's writing to same files). Aided by this query: |
| 209 | +# git grep -E '/[^ ]*\.la([ :]|$)' '*.am' |
| 210 | +# It does help to spell out all dependencies, even if transitive, to ensure |
| 211 | +# that the top-level make completes needed (all-libs*) targets before drilling. |
| 212 | +all/common: all/include all-libs-local/common |
| 213 | + +@$(SUBDIR_TGT_RULE) |
| 214 | + |
| 215 | +all/clients: all/common all-libs-local/clients |
| 216 | + +@$(SUBDIR_TGT_RULE) |
| 217 | + |
| 218 | +# only libupsclient is needed for dummy-ups, |
| 219 | +# but we do wholesale subdir all-libs-local at the moment... |
| 220 | +if SOME_DRIVERS |
| 221 | +all/drivers: all-libs-local/clients all-libs-local/common |
| 222 | + +@$(SUBDIR_TGT_RULE) |
| 223 | +else !SOME_DRIVERS |
| 224 | +dummy-ups/drivers: all-libs-local/clients all-libs-local/common |
| 225 | + +@$(SUBDIR_TGT_RULE) |
| 226 | + |
| 227 | +all/drivers: dummy-ups/drivers all/common all-libs-local/drivers |
| 228 | + +@$(SUBDIR_TGT_RULE) |
| 229 | +endif !SOME_DRIVERS |
| 230 | + |
| 231 | +all/server: all-libs-local/common |
| 232 | + +@$(SUBDIR_TGT_RULE) |
| 233 | + |
| 234 | +all/tools/nut-scanner: all-libs-local/tools/nut-scanner all-libs-local/drivers all-libs-local/common |
| 235 | + +@$(SUBDIR_TGT_RULE) |
| 236 | + |
| 237 | +# only libnutscan is needed for nutconf, |
| 238 | +# but we do wholesale subdir all-libs-local at the moment... |
| 239 | +all/tools/nutconf: all-libs-local/tools/nut-scanner all-libs-local/common |
| 240 | + +@$(SUBDIR_TGT_RULE) |
| 241 | + |
| 242 | +all-recursive/tools: all/tools/nutconf all/tools/nut-scanner |
| 243 | + +@$(SUBDIR_TGT_RULE) |
| 244 | + |
| 245 | +# At least prereqs for NIT, maybe for certain compiled tests too: |
| 246 | +all/tests/NIT: all/clients all/server all/drivers all-recursive/tools all-recursive/data |
| 247 | + +@$(SUBDIR_TGT_RULE) |
| 248 | + |
| 249 | +all/tests: all-libs-local/tests all-libs-local/drivers all-libs-local/common all-libs-local/clients |
| 250 | + +@$(SUBDIR_TGT_RULE) |
| 251 | + |
| 252 | +all-recursive/tests: all/tests/NIT all/tests |
| 253 | + +@$(SUBDIR_TGT_RULE) |
| 254 | + |
| 255 | +if HAVE_MINGW_RESGEN |
| 256 | +if HAVE_WINDOWS |
| 257 | +all/scripts/Windows: all-libs-local/common |
| 258 | + +@$(SUBDIR_TGT_RULE) |
| 259 | +else !HAVE_WINDOWS |
| 260 | +all/scripts/Windows: |
| 261 | + +@$(SUBDIR_TGT_RULE) |
| 262 | +endif !HAVE_WINDOWS |
| 263 | +else !HAVE_MINGW_RESGEN |
| 264 | +all/scripts/Windows: |
| 265 | + +@$(SUBDIR_TGT_RULE) |
| 266 | +endif !HAVE_MINGW_RESGEN |
| 267 | + |
| 268 | +all-recursive/scripts: all/scripts/Windows |
| 269 | + +@$(SUBDIR_TGT_RULE) |
| 270 | + |
61 | 271 | # ---------------------------------------------------------------------- |
62 | 272 | # flags to pass to ./configure when calling "make distcheck" and "make |
63 | 273 | # distcheck-light". Try to check as many features as possible! Also |
|
0 commit comments