build: scope .NOTPARALLEL to locale targets only, restore parallel build
The locale Makefile (extra/locale/Makefile.in) had a bare ".NOTPARALLEL:"
directive (no prerequisites) since commit 4c68c74d ("locale: disable
parallel build as it is broken here", 2016-09-27). That commit intended
to disable parallel execution only for the locale subdirectory build,
because of a race observed there at the time.
However, extra/locale/Makefile.in is `include`-d into the top-level
Makefile (Makefile.in:32), and the bare form of .NOTPARALLEL applies
globally to the make invocation, not just to the included fragment.
>From the GNU Make manual:
If .NOTPARALLEL is mentioned as a target, then this invocation of
make will be run serially, even if the -j option is given.
As a result, every uClibc-ng build since 2016 ran strictly serially,
regardless of -jN, across every architecture and target -- even on
multi-core build hosts.
Measured on arm-bbs-linux-uclibcgnueabihf, 16-core build host:
before: make -j16 cold build: 2m 18s real / 1m 38s user
(user/real == 1.0 -- one core busy)
after: make -j16 cold build: 0m 42s real / 2m 14s user
(user/real == 3.2 -- effective parallel)
3.3x wall-clock speedup on a 16-core machine.
Fix: list the locale-generated headers and data files explicitly as
.NOTPARALLEL prerequisites. This is the GNU Make 4.4+ form, where the
serial constraint is scoped to those specific targets (and their own
prerequisites). GNU Make < 4.4 silently ignores the prerequisite list
and falls back to global serialization (i.e. the previous behavior),
so this change is fully backward-compatible -- new make versions get
the speedup, old make versions are unchanged.
The targets listed cover every recipe that writes to a generated file
via shell redirection (`> $@`, `-o $@`, etc.) inside the locale build,
preserving the original protection where the 2016 race was observed:
- c8tables.h, wctables.h, locale_tables.h (raw generator output)
- locale_collate.h (depends on locale_tables.h
via grep/sed pipeline)
- lt_defines.h (greps locale_tables.h +
locale_collate.h)
- locale_data.c (gen_ldc output)
- uClibc_locale_data.h (combines the above)
- include/bits/uClibc_locale_data.h (final install target)
The host-tool compilations (gen_wc8bit, gen_wctype, gen_collate,
gen_locale, gen_ldc) are intentionally not in the list -- they have no
inter-dependencies and benefit from parallel compilation.
Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>