[syslinux] Missing make dependencies?

Jonathan Boeing jonathan.n.boeing at gmail.com
Mon Feb 9 19:04:51 PST 2015


I'm seeing some sporadic build failures with 'make -j4'.  The failures are:

make[4]: *** No rule to make target 'hello.c32', needed by 'all'.  Stop.

I've only seen the failures with com32/samples/hello.c32 and com32/rosh/rosh.c32.
I'm not a make expert, but I think it's due to missing dependencies.  This patch
seems to fix my failures, but I'm wondering (if my analysis is correct) if there
are a few more missing.


diff --git a/com32/Makefile b/com32/Makefile
index c5784be..b18414f 100644
--- a/com32/Makefile
+++ b/com32/Makefile
@@ -18,6 +18,6 @@ gfxboot: lib libutil gpllib
 hdt: lib libupload cmenu gpllib libutil
 lua/src: cmenu modules
 modules: lib libutil gpllib
-rosh: lib libutil
-samples: libutil elflink/ldlinux
+rosh: lib libutil gpllib
+samples: libutil elflink/ldlinux gpllib
 sysdump: lib libutil libupload gpllib


In a successful build, libgpl.c32 finished building before hello.c32 and rosh.c32.
In a failed build, libgpl.c32 was unfinished when hello.c32 failed.

The race between libgpl.c32 and hello.c32 seems to trip up make.
Here's a 'make --debug' excerpt from the point of failure:

--------------------------------------------------
Updating goal targets....
Considering target file 'all'.
 File 'all' does not exist.
 Looking for an implicit rule for 'all'.
 No implicit rule found for 'all'.
  Considering target file 'hello.c32'.
   File 'hello.c32' does not exist.
   Looking for an implicit rule for 'hello.c32'.
   Trying pattern rule with stem 'hello'.
   Trying implicit prerequisite 'hello.elf'.
   Trying pattern rule with stem 'hello'.
   Trying implicit prerequisite 'hello.elf'.
   Looking for a rule with intermediate file 'hello.elf'.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem 'hello'.
    Trying implicit prerequisite 'hello.o'.
    Trying pattern rule with stem 'hello'.
    Trying implicit prerequisite 'hello.o'.
    Looking for a rule with intermediate file 'hello.o'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem 'hello'.
     Trying implicit prerequisite 'hello.S'.
     Trying pattern rule with stem 'hello'.
     Trying implicit prerequisite 'hello.c'.
     Found prerequisite 'hello.c' as VPATH '/home/john/git/syslinux/com32/samples/hello.c'
    Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/libutil/libutil.c32'.
    Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.
    Looking for a rule with intermediate file '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
   No implicit rule found for 'hello.c32'.
   Finished prerequisites of target file 'hello.c32'.
  Must remake target 'hello.c32'.
make[4]: *** No rule to make target 'hello.c32', needed by 'all'.  Stop.
make[4]: Leaving directory '/home/john/git/syslinux/efi64/com32/samples'
Reaping losing child 0x1112500 PID 22647 
/home/john/git/syslinux/com32/Makefile:7: recipe for target 'samples' failed
make[3]: *** [samples] Error 2
Removing child 0x1112500 PID 22647 from chain.
Released token for child 0x1112500 (samples).
make[3]: *** Waiting for unfinished jobs....
--------------------------------------------------

The output from a successful build is the same until the 'Trying rule prerequisite libgpl.c32'.

--------------------------------------------------
Updating goal targets....
Considering target file 'all'.
 File 'all' does not exist.
 Looking for an implicit rule for 'all'.
 No implicit rule found for 'all'.
  Considering target file 'hello.c32'.
   File 'hello.c32' does not exist.
   Looking for an implicit rule for 'hello.c32'.
   Trying pattern rule with stem 'hello'.
   Trying implicit prerequisite 'hello.elf'.
   Trying pattern rule with stem 'hello'.
   Trying implicit prerequisite 'hello.elf'.
   Looking for a rule with intermediate file 'hello.elf'.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem 'hello'.
    Trying implicit prerequisite 'hello.o'.
    Trying pattern rule with stem 'hello'.
    Trying implicit prerequisite 'hello.o'.
    Looking for a rule with intermediate file 'hello.o'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem 'hello'.
     Trying implicit prerequisite 'hello.S'.
     Trying pattern rule with stem 'hello'.
     Trying implicit prerequisite 'hello.c'.
     Found prerequisite 'hello.c' as VPATH '/home/john/git/syslinux/com32/samples/hello.c'
    Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/libutil/libutil.c32'.
    Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.
    Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/lib/libcom32.c32'.
   Found an implicit rule for 'hello.c32'.
      Considering target file 'hello.c'.
       Looking for an implicit rule for 'hello.c'.
       No implicit rule found for 'hello.c'.
       Finished prerequisites of target file 'hello.c'.
--------------------------------------------------

Failed build:
Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.
Looking for a rule with intermediate file '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.

Successful build:
Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/gpllib/libgpl.c32'.
Trying rule prerequisite '/home/john/git/syslinux/efi64/com32/lib/libcom32.c32'.


Looking at mk/elf.mk, you can trace the expansion from .c32 -> .elf -> .o -> .S -> .c,
and then the expansion from $(C_LIBS) -> libutil.c32 libgpl.c32 libcom32.c32

--------------------------------------------------
GPLLIB     = $(objdir)/com32/gpllib/libgpl.c32
<snip>
C_LIBS	   += $(objdir)/com32/libutil/libutil.c32 $(GPLLIB) \
	     $(objdir)/com32/lib/libcom32.c32

.SUFFIXES: .lss .c .o

.PRECIOUS: %.o
%.o: %.S
	$(CC) $(SFLAGS) -c -o $@ $<

.PRECIOUS: %.o
%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

<snip>

.PRECIOUS: %.elf
%.elf: %.o $(C_LIBS)
	$(LD) $(LDFLAGS) -o $@ $^

%.c32: %.elf
	$(OBJCOPY) --strip-debug --strip-unneeded $< $@
--------------------------------------------------


If I'm understanding it correctly: 
 - the make rules for %.c32 pull in the $(C_LIBS) libutil.c32 libgpl.c32 libcom32.c32
 - the subdir dependencies in com32/Makefile don't all list all three $(C_LIBS)
 - the build fails when a non-library subdir (i.e. samples) wins the race against a $(C_LIB)

If that's right, wouldn't the subdir parallel dependencies in com32/Makefile all need
to include at least lib, libutil, and gpllib?

# Parallel dependencies
chain mboot menu: lib libutil gpllib
cmenu: lib libutil
elflink/ldlinux gpllib libupload libutil: lib
gfxboot: lib libutil gpllib
hdt: lib libupload cmenu gpllib libutil
lua/src: cmenu modules
modules: lib libutil gpllib
rosh: lib libutil
samples: libutil elflink/ldlinux
sysdump: lib libutil libupload gpllib


Regards,
Jonathan Boeing


More information about the Syslinux mailing list