autoconf: Parallel Make
1
1 12.10 Parallel Make
1 ===================
1
1 Support for parallel execution in `make' implementation varies.
1 Generally, using GNU make is your best bet.
1
1 When NetBSD or FreeBSD `make' are run in parallel mode, they will
1 reuse the same shell for multiple commands within one recipe. This can
1 have various unexpected consequences. For example, changes of
1 directories or variables persist between recipes, so that:
1
1 all:
1 @var=value; cd /; pwd; echo $$var; echo $$$$
1 @pwd; echo $$var; echo $$$$
1
1 may output the following with `make -j1', at least on NetBSD up to 5.1
1 and FreeBSD up to 8.2:
1
1 /
1 value
1 32235
1 /
1 value
1 32235
1
1 while without `-j1', or with `-B', the output looks less surprising:
1
1 /
1 value
1 32238
1 /tmp
1
1 32239
1
1 Another consequence is that, if one command in a recipe uses `exit 0'
1 to indicate a successful exit, the shell will be gone and the remaining
1 commands of this recipe will not be executed.
1
1 The BSD `make' implementations, when run in parallel mode, will also
1 pass the `Makefile' recipes to the shell through its standard input,
1 thus making it unusable from the recipes:
1
1 $ cat Makefile
1 read:
1 @read line; echo LINE: $$line
1 $ echo foo | make read
1 LINE: foo
1 $ echo foo | make -j1 read # NetBSD 5.1 and FreeBSD 8.2
1 LINE:
1
1 Moreover, when FreeBSD `make' (up at least to 8.2) is run in parallel
1 mode, it implements the `@' and `-' "recipe modifiers" by dynamically
1 modifying the active shell flags. This behavior has the effects of
1 potentially clobbering the exit status of recipes silenced with the `@'
1 modifier if they also unset the `errexit' shell flag, and of mangling
1 the output in unexpected ways:
1
1 $ cat Makefile
1 a:
1 @echo $$-; set +e; false
1 b:
1 -echo $$-; false; echo set -
1 $ make a; echo status: $?
1 ehBc
1 *** Error code 1
1 status: 1
1 $ make -j1 a; echo status: $?
1 ehB
1 status: 0
1 $ make b
1 echo $-; echo set -
1 hBc
1 set -
1 $ make -j1 b
1 echo $-; echo hvB
1
1 You can avoid all these issues by using the `-B' option to enable
1 compatibility semantics. However, that will effectively also disable
1 all parallelism as that will cause prerequisites to be updated in the
1 order they are listed in a rule.
1
1 Some make implementations (among them, FreeBSD `make', NetBSD
1 `make', and Solaris `dmake'), when invoked with a `-jN' option, connect
1 the standard output and standard error of all their child processes to
1 pipes or temporary regular files. This can lead to subtly different
1 semantics in the behavior of the spawned processes. For example, even
1 if the `make' standard output is connected to a tty, the recipe command
1 will not be:
1
1 $ cat Makefile
1 all:
1 @test -t 1 && echo "Is a tty" || echo "Is not a tty"
1 $ make -j 2 # FreeBSD 8.2 make
1 Is not a tty
1 $ make -j 2 # NetBSD 5.1 make
1 --- all ---
1 Is not a tty
1 $ dmake -j 2 # Solaris 10 dmake
1 HOSTNAME --> 1 job
1 HOSTNAME --> Job output
1 Is not a tty
1
1 On the other hand:
1
1 $ make -j 2 # GNU make, Heirloom make
1 Is a tty
1
1 The above examples also show additional status output produced in
1 parallel mode for targets being updated by Solaris `dmake' and NetBSD
1 `make' (but _not_ by FreeBSD `make').
1
1 Furthermore, parallel runs of those `make' implementations will
1 route standard error from commands that they spawn into their own
1 standard output, and may remove leading whitespace from output lines.
1