I came across a section in the Automake manual describing problems with Makefile rules with multiple outputs.
https://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html We have such rules in several places for building texi2any. For example, in tta/C/Makefile.am: $(srcdir)/main/command_data.c $(srcdir)/main/command_ids.h $(srcdir)/main/global_multi_commands_case.c $(srcdir)/main/global_unique_commands_case.c $(srcdir)/main/global_commands_types.h: ../data/command_data.txt main/command_data.awk $(GAWK) -v srcdir=$(srcdir)/main -f $(srcdir)/main/command_data.awk \ $(srcdir)/../data/command_data.txt The problem is supposed to be with parallel builds, in that the rule could run multiple times at the same time. For example, if under tta/C, I run "touch ../data/command_data.txt" and then run "make", the output starts: ------------ /bin/bash '/home/g/src/texinfo/GIT/tta/build-aux/missing' gawk -v srcdir=./main -f ./main/command_data.awk \ ./../data/command_data.txt /usr/bin/perl ./../maintain/generate_code_commands_values.pl \ ./../data/commands_values.txt C \ ./main/cmd_text.c \ ./main/cmd_unicode.c \ ./main/cmd_structuring.c \ ./convert/cmd_converter.c \ ./main/command_data.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/generate_code_convert_data.pl \ < ./main/command_data.c \ ./../data/default_css_element_class_styles.csv \ ./../data/default_direction_strings.csv \ ./../data/default_special_unit_info.csv \ ./../data/html_style_commands_element.csv \ C ./main/html_conversion_data.c \ ./main/html_conversion_data.h REMARK: 'Space': no description make all-am make[1]: Entering directory '/home/g/src/texinfo/GIT/tta/C' x86_64-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I./parsetexi -I./convert -I./main -I./structuring_transfo -I. -DDATADIR=\"/usr/local/share\" -DSYSCONFDIR=\"/usr/local/etc\" -I../gnulib/lib -I../gnulib/lib -DPATH_SEP=\":\" -DEMBED_PERL -MT ctexi2any-texi2any.o -MD -MP -MF .deps/ctexi2any-texi2any.Tpo -c -o ctexi2any-texi2any.o `test -f 'texi2any.c' || echo './'`texi2any.c ------------ - but if I run "make -j4" instead, the output starts: ------------ /bin/bash '/home/g/src/texinfo/GIT/tta/build-aux/missing' gawk -v srcdir=./main -f ./main/command_data.awk \ ./../data/command_data.txt /bin/bash '/home/g/src/texinfo/GIT/tta/build-aux/missing' gawk -v srcdir=./main -f ./main/command_data.awk \ ./../data/command_data.txt /bin/bash '/home/g/src/texinfo/GIT/tta/build-aux/missing' gawk -v srcdir=./main -f ./main/command_data.awk \ ./../data/command_data.txt /bin/bash '/home/g/src/texinfo/GIT/tta/build-aux/missing' gawk -v srcdir=./main -f ./main/command_data.awk \ ./../data/command_data.txt /usr/bin/perl ./../maintain/generate_code_commands_values.pl \ ./../data/commands_values.txt C \ ./main/cmd_text.c \ ./main/cmd_unicode.c \ ./main/cmd_structuring.c \ ./convert/cmd_converter.c \ ./main/command_data.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/generate_code_commands_values.pl \ ./../data/commands_values.txt C \ ./main/cmd_text.c \ ./main/cmd_unicode.c \ ./main/cmd_structuring.c \ ./convert/cmd_converter.c \ ./main/command_data.c /usr/bin/perl ./../maintain/generate_code_commands_values.pl \ ./../data/commands_values.txt C \ ./main/cmd_text.c \ ./main/cmd_unicode.c \ ./main/cmd_structuring.c \ ./convert/cmd_converter.c \ ./main/command_data.c /usr/bin/perl ./../maintain/generate_code_commands_values.pl \ ./../data/commands_values.txt C \ ./main/cmd_text.c \ ./main/cmd_unicode.c \ ./main/cmd_structuring.c \ ./convert/cmd_converter.c \ ./main/command_data.c /usr/bin/perl ./../maintain/generate_code_convert_data.pl \ < ./main/command_data.c \ ./../data/default_css_element_class_styles.csv \ ./../data/default_direction_strings.csv \ ./../data/default_special_unit_info.csv \ ./../data/html_style_commands_element.csv \ C ./main/html_conversion_data.c \ ./main/html_conversion_data.h /usr/bin/perl ./../maintain/generate_code_convert_data.pl \ < ./main/command_data.c \ ./../data/default_css_element_class_styles.csv \ ./../data/default_direction_strings.csv \ ./../data/default_special_unit_info.csv \ ./../data/html_style_commands_element.csv \ C ./main/html_conversion_data.c \ ./main/html_conversion_data.h REMARK: 'Space': no description /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c REMARK: 'Space': no description /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c /usr/bin/perl ./../maintain/regenerate_C_options_info.pl \ < ./../data/options_data.txt \ ./main/command_data.c \ ./../data/converters_defaults.txt \ ./main/options_init_free.c \ ./main/options_data.h \ ./main/options_defaults.c \ ./main/options_defaults.h \ ./convert/converters_options.c \ ./convert/converters_options.h \ ./main/options_get_perl.c make all-am make[1]: Entering directory '/home/g/src/texinfo/GIT/tta/C' /bin/bash ../libtool --tag=CC --mode=compile x86_64-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I./main -I. -DDATADIR=\"/usr/local/share\" -DSYSCONFDIR=\"/usr/local/etc\" -I/usr/lib/x86_64-linux-gnu/perl/5.34/CORE -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fwrapv -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fPIC -MT main/libtexinfoxs_la-build_perl_info.lo -MD -MP -MF main/.deps/libtexinfoxs_la-build_perl_info.Tpo -c -o main/libtexinfoxs_la-build_perl_info.lo `test -f 'main/build_perl_info.c' || echo './'`main/build_perl_info.c ------------ - as you can see, the rules run multiple times. The node in the Automake manual does not offer a clear solution that is correct. It shows various solutions, some much more complicated than others. It's not clear that these solutions actually work and some of them seem like ideas or proposals rather a recommended solution ("One could imagine something along the following lines."). Have we had this problem? Could we get away with just ignoring it as the proposed solutions are all atrociously complicated? Maybe it is harmless to have multiple processes writing to the generated files at the same time? As these files are generated in srcdir and are distributed, then the rule to rebuild them shouldn't run too often and users of the package would not have to rebuild them, and would be unlikely to run into problems with parallel builds. If we do ignore the problem, we should add a comment stating this in the Makefile.am files. I had an idea that "locking" could be done in a separate helper program. The "make" rule would become something like: LOCK_ONCE=build_aux/lock-once.sh $(srcdir)/main/command_data.c $(srcdir)/main/command_ids.h $(srcdir)/main/global_multi_commands_case.c $(srcdir)/main/global_unique_commands_case.c $(srcdir)/main/global_commands_types.h: ../data/command_data.txt main/command_data.awk $(LOCK_ONCE) $(GAWK) -v srcdir=$(srcdir)/main -f $(srcdir)/main/command_data.awk \ $(srcdir)/../data/command_data.txt Then all the complexity of checking for signals, clean-up etc. could go in the separate program.