When building Ruby parallely with BSD make (FreeBSD make), it fails to build.
Reported by FreeBSD Ruby folks. Please keep in mind I didn't find out the root cause.
cd ruby-2.6.5
make distclean
./configure --enable-shared --disable-readline --disable-libedit
make
`ruby' is up to date.
*** Following extensions are not compiled:
readline:
Could not be configured. It will not be installed.
/home/sair/tmp/ruby-2.6.5/ext/readline/extconf.rb:52: readline not found
Check ext/readline/mkmf.log for more details.
gdbm:
Could not be configured. It will not be installed.
Check ext/gdbm/mkmf.log for more details.
*** Fix the problems, then remove these directories and try again if you want.
making enc
making trans
`trans' is up to date.
making encs
Generating RDoc documentation
Subject changed from fails to build with BSD make possibly due to race condition to fails to build with BSD make when any -j option is given (including -j 1)
Now it turned out the build fails even -j 1 is specified. Any value to -j option will fail.
Not giving -j option goes fine.
The conditions in libruby-static and libruby-shared are different intentionally.
First:
It seems that it is not intended to call $(PRE_LIBRARY_UPDATE) in Ruby's Makefile,
when libruby.so.26 is built.
Comparing to libruby-static library build,
Ruby's Makefile should be fixed like Makefile.in.patch.
Get rid of FreeBSD make incompatibility [Bug #16331]
FreeBSD make works differently with -j option.
-j max_jobs
Specify the maximum number of jobs that make may have running
at any one time. The value is saved in .MAKE.JOBS. Turns
compatibility mode off, unless the B flag is also specified.
When compatibility mode is off, all commands associated with a
target are executed in a single shell invocation as opposed to
the traditional one shell invocation per line. This can break
traditional scripts which change directories on each command
invocation and then expect to start with a fresh environment on
the next line. It is more efficient to correct the scripts
rather than turn backwards compatibility on.
I executed following shell script on my FreeBSD test environment and got attached log file.
#!/bin/shLANG=C
(echo System Information:
echo----------------------------------------------------------------------
dmesg
echo----------------------------------------------------------------------echo Package Information:
echo----------------------------------------------------------------------
pkg info -aqecho----------------------------------------------------------------------cd /tmp
for ver in 2.6.5 2.7.0-rc2
do
echo Test build of ${ver}:
tar xfpJ /net/freebsd/ports/distfiles/ruby/ruby-${ver}.tar.xz
cd ruby-${ver}echo Configure:
echo----------------------------------------------------------------------
./configure
echo----------------------------------------------------------------------echo Build:
echo----------------------------------------------------------------------
make -j$(sysctl -n kern.smp.cpus)echo----------------------------------------------------------------------cd ..
rm-rf ruby-${ver}done) | 2>&1 tee buildtest-with-bmake-and-j-option.log
As you can see, make -j works fine with 2.6.5 but fails with 2.7.0-rc2.
Does this log mean the following libraries are stopped by make due to the first failure in cxxanyargs or in yet another branch?
--- ext/-test-/cxxanyargs/all ---
A failure has been detected in another branch of the parallel make
make[2]: stopped in /tmp/ruby-2.7.0-rc2/ext/-test-/cxxanyargs
*** [ext/-test-/cxxanyargs/all] Error code 2
make[1]: stopped in /tmp/ruby-2.7.0-rc2
--- ext/-test-/exception/all ---
A failure has been detected in another branch of the parallel make
make[2]: stopped in /tmp/ruby-2.7.0-rc2/ext/-test-/exception
*** [ext/-test-/exception/all] Error code 2
make[1]: stopped in /tmp/ruby-2.7.0-rc2
--- ext/-test-/enumerator_kw/all ---
A failure has been detected in another branch of the parallel make
make[2]: stopped in /tmp/ruby-2.7.0-rc2/ext/-test-/enumerator_kw
*** [ext/-test-/enumerator_kw/all] Error code 2
make[1]: stopped in /tmp/ruby-2.7.0-rc2
--- ext/psych/all ---
A failure has been detected in another branch of the parallel make
make[2]: stopped in /tmp/ruby-2.7.0-rc2/ext/psych
*** [ext/psych/all] Error code 2
make[1]: stopped in /tmp/ruby-2.7.0-rc2
4 errors
make[1]: stopped in /tmp/ruby-2.7.0-rc2
*** [build-ext] Error code 2
Ignore expected errors on compiling C++ source [Bug #16331]
BSD make can run parallel more aggressively than GNU make. It communicate
with other make process through -J option in MAKEFLAGS environment variable
to notify a build failure happend in an other pararell make process. https://www.freebsd.org/cgi/man.cgi?make
It usually works well but ext/-test-/cxxanyargs/Makefile has two targets
which are expected to fail (failure.o and failurem1.o).
Additional note:
To test and debug this issue, following command will speed up it. make -f exts.mk -j8 clean all