[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
parallel build of gettext may fail
From: |
Ralf Wildenhues |
Subject: |
parallel build of gettext may fail |
Date: |
Fri, 27 Oct 2006 17:51:43 +0200 |
User-agent: |
Mutt/1.5.13 (2006-10-09) |
Hello Bruno,
gettext-tools/libgettextpo/Makefile.am contains a code snippet like
this:
BUILT_SOURCES += config.h
config.h:
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
: "Avoid double inclusion, to avoid a warning about redefinition of
DLL_VARIABLE."; \
[...]
} > config.h && \
{ $(MAKE) $(BUILT_SOURCES) || { rm -f config.h; exit 1; }; } && \
if test -n "$(HAVE_GLOBAL_SYMBOL_PIPE)"; then \
{ \
for f in $(libgettextpo_la_AUXSOURCES) $(libgnu_la_SOURCES)
$(libgnu_la_LIBADD); do \
case $$f in \
*.c | *.$(OBJEXT) | *.lo ) \
sf=`echo "$$f" | sed -e 's,\\.[^.]*$$,,'`.c; \
of=`echo "$$f" | sed -e 's,^.*/,,' -e
's,\\.[^.]*$$,,'`.$(OBJEXT); \
$(COMPILE) -c $(srcdir)/$$sf || { rm -f config.h; exit 1; }; \
sh ./exported.sh $$of 1>&5; \
rm -f $$of; \
;; \
esac; \
done; \
} 5>&1 \
| sed -e 's,.* ,,' | LC_ALL=C sort | LC_ALL=C uniq \
| sed -e 's,^obstack_free$$,__obstack_free,' \
| sed -e 's,^\(.*\)$$,#define \1 libgettextpo_\1,' > config.h-t && \
if test -f config.h; then \
cat config.h-t >> config.h; \
rm -f config.h-t; \
else \
rm -f config.h-t; \
exit 1; \
fi \
fi
MOSTLYCLEANFILES += config.h config.h-t
This code warrants (at least) two comments:
1) Since the inner $(MAKE) is unaware of the work of any outer ones
on the `$(BUILT_SOURCES)' targets, there is a race condition for
parallel make invocations. This race easily breaks a build on a system
with several CPUs:
$ make -j2
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
: "Avoid double inclusion, to avoid a warning about redefinition of
DLL_VARIABLE."; \
[...]
echo '#endif /* GTPO_CONFIG_H */'; \
} > config.h && \
{ make config.h gettext-po.h alloca.h configmake.h stdint.h || { rm -f
config.h; exit 1; }; } && \
if test -n "1"; then \
{ \
for f in ../src/str-list.c ../src/dir-list.c ../src/message.c
../src/msgl-ascii.c ../src/po-error.c ../src/po-xerror.c ../src/write-catalog.c
../src/write-po.c ../src/open-catalog.c ../src/po-charset.c ../src/po-lex.c
../src/po-gram-gen.c ../src/read-po.c ../src/read-catalog-abstract.c
../src/read-catalog.c ../src/plural-table.c ../src/format-c.c
../src/format-sh.c ../src/format-python.c ../src/format-lisp.c
../src/format-elisp.c ../src/format-librep.c ../src/format-scheme.c
../src/format-java.c ../src/format-csharp.c ../src/format-awk.c
../src/format-pascal.c ../src/format-ycp.c ../src/format-tcl.c
../src/format-perl.c ../src/format-perl-brace.c ../src/format-php.c
../src/format-gcc-internal.c ../src/format-qt.c ../src/format-boost.c
../src/format.c ../src/plural-exp.c ../src/plural-eval.c ../src/msgl-check.c
allocsa.h allocsa.c basename.h basename.c c-ctype.h c-ctype.c c-strcase.h
c-strcasecmp.c c-strncasecmp.c c-strstr.h c-strstr.c error-progname.h
error-progname.c exit.h exitfail.h exitfail.c fstrcmp.h fstrcmp.c fwriteerror.h
fwriteerror.c gcd.h gcd.c gettext.h hash.h hash.c linebreak.h linebreak.c
lbrkprop.h localcharset.h localcharset.c lock.h lock.c mbswidth.h mbswidth.c
minmax.h pathname.h concatpath.c progname.h progname.c size_max.h striconv.h
striconv.c tls.h tls.c ucs4-utf8.h utf16-ucs4.h utf8-ucs4.h wcwidth.h xalloc.h
xmalloc.c xstrdup.c xallocsa.h xallocsa.c xerror.h xerror.c xsize.h xstriconv.h
xstriconv.c xvasprintf.h xvasprintf.c xasprintf.c ; do \
case $f in \
*.c | *.o | *.lo ) \
sf=`echo "$f" | sed -e 's,\\.[^.]*$,,'`.c; \
of=`echo "$f" | sed -e 's,^.*/,,' -e 's,\\.[^.]*$,,'`.o; \
gcc -DHAVE_CONFIG_H -I. -I..
-I../../../gettext-0.16/gettext-tools/libgettextpo -I.
-I../../../gettext-0.16/gettext-tools/libgettextpo -I..
-I../../../gettext-0.16/gettext-tools -I../src
-I../../../gettext-0.16/gettext-tools/src -I../intl
-I../../../gettext-0.16/gettext-tools/../gettext-runtime/intl -g -O2 -c
../../../gettext-0.16/gettext-tools/libgettextpo/$sf || { rm -f config.h; exit
1; }; \
sh ./exported.sh $of 1>&5; \
rm -f $of; \
;; \
esac; \
done; \
} 5>&1 \
| sed -e 's,.* ,,' | LC_ALL=C sort | LC_ALL=C uniq \
| sed -e 's,^obstack_free$,__obstack_free,' \
| sed -e 's,^\(.*\)$,#define \1 libgettextpo_\1,' > config.h-t && \
if test -f config.h; then \
cat config.h-t >> config.h; \
rm -f config.h-t; \
else \
rm -f config.h-t; \
exit 1; \
fi \
fi
cp ../../../gettext-0.16/gettext-tools/libgettextpo/gettext-po.h.in
gettext-po.h-tmp
mv gettext-po.h-tmp gettext-po.h
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
cat ../../../gettext-0.16/gettext-tools/libgettextpo/alloca_.h; \
} > alloca.h-t
mv -f alloca.h-t alloca.h
make[1]: Entering directory `/tmp/gettext/build-0.16/gettext-tools/libgettextpo'
make[1]: `config.h' is up to date.
make[1]: `gettext-po.h' is up to date.
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
cat ../../../gettext-0.16/gettext-tools/libgettextpo/alloca_.h; \
} > alloca.h-t
rm -f configmake.h-t configmake.h
mv -f alloca.h-t alloca.h
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
echo '#define PREFIX "/usr/local"'; \
[...]
echo '#define PKGLIBEXECDIR ""'; \
} | sed '/""/d' > configmake.h-t
mv configmake.h-t configmake.h
mv: cannot stat `alloca.h-t': No such file or directory
make[1]: *** [alloca.h] Error 1
make[1]: Leaving directory `/tmp/gettext/build-0.16/gettext-tools/libgettextpo'
rm -f stdint.h-t stdint.h
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
sed -e 's/@''HAVE_WCHAR_H''@/1/g' \
[...]
-e 's/@''WINT_T_SUFFIX''@/u/g' \
< ../../../gettext-0.16/gettext-tools/libgettextpo/stdint_.h; \
} > stdint.h-t
make: *** [config.h] Error 1
make: *** Waiting for unfinished jobs....
mv stdint.h-t stdint.h
2) Solaris make with its dreaded VPATH rewriting "feature" will, in this
loop:
for f in $(libgettextpo_la_AUXSOURCES) $(libgnu_la_SOURCES)
$(libgnu_la_LIBADD); do
\
case $$f in \
*.c | *.$(OBJEXT) | *.lo ) \
sf=`echo "$$f" | sed -e 's,\\.[^.]*$$,,'`.c; \
of=`echo "$$f" | sed -e 's,^.*/,,' -e
's,\\.[^.]*$$,,'`.$(OBJEXT); \
$(COMPILE) -c $(srcdir)/$$sf || { rm -f config.h; exit 1; }; \
rewrite all f that point to files from the source tree to contain a
$(srcdir) prefix. Since you do not strip it, the compile command will
pass a doubled $(srcdir) prefix.
Automake itself works around this (in non-inference rules) like this:
... -c `test -f '$(SOURCE)' || echo '$(srcdir)/'`$(SOURCE)
with $(SOURCE) replaced by the source file name.
Hope that helps.
Cheers,
Ralf
- parallel build of gettext may fail,
Ralf Wildenhues <=