tags:

views:

790

answers:

3

In a recent issue, I've found that DJGPP can only accept the DOS command line character limit. To work around this limitation, I've decided to try to write a makefile to allow me to pass longer strings. In the process of hacking together a makefile and testing it, I've come across a strange error. The makefile is as follows:

AS  := nasm
CC  := gcc
LD  := ld

TARGET   := $(shell basename $(CURDIR))
BUILD    := build
SOURCES  := source

CFLAGS  := -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
      -nostdinc -fno-builtin -I./include
ASFLAGS := -f aout

export OUTPUT   := $(CURDIR)/$(TARGET)

CFILES   := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES   := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))

SOBJS   := $(SFILES:.s=.o)
COBJS   := $(CFILES:.c=.o)
OBJS    := $(SOBJS) $(COBJS)

build   : $(TARGET).img

$(TARGET).img   : $(TARGET).bin
    concat.py

$(TARGET).bin   : $(OBJS)
    $(LD) -T link.ld -o $@ $^

$(SOBJS)    : %.o : %.asm
    $(AS) $(ASFLAGS) $< -o $@

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

When attempting to run it, I receive this error:

make: *** No rule to make target `consoleio.c', needed by `consoleio.o'.  Stop.

What I don't understand is why it's trying to find a rule for .c files. From what I understand, if the file is there, it should just use it. How do I make make not need a rule for .c files?

+2  A: 

Let's try a non-comment answer...

Possibility A:

  • Your macro for SFILES is looking for files ending in '.s'.
  • Your rule for compiling SOBJS is looking for files ending in '.asm'.

Possibility B:

  • Your rule for SOBJS and COBJS is in a notation I don't recognize.
  • According to the GNU Make manual, you can write implicit rules as:

    %.o : %.c ; command

You seem to have a list of targets $(SOBJS) that depends on '%.o : %.asm'. I'm not sure how make will interpret that.

Personally, I would not trust wild-cards in build rules. I'd much rather spend the time listing exactly which source files are needed to build the code. I don't often run into this problem as a result.

Jonathan Leffler
+2  A: 

What you are trying to do will not work without VPATH, and since you are still learning makefiles, I would avoid using VPATH.

The rule is looking for "consoleio.c", which if I understood your makefile correctly does not exist; what exists is "source/consoleio.c". You probably should change it to something like "$(SOURCES)/%.c" instead of "%c".

I didn't check your syntax for that rule, however. If it's incorrect, the builtin "%.o: %.c" rule will be used instead, which would have the same problem.

The way you are doing is not the usual way I've seen, however. The usual way is to:

  • Create an implicit rule "%.o: %.c" (or in your case "%.o: $(SOURCES)/%.c")
  • Explicit list the dependencies for each file: "foo.o: foo.c bar.h baz.h" (with no command, the implicit rule has the command)
CesarB
I don't even know what VPATH is, so I probably shouldn't be using it. This is what I get for not knowing how to write a makefile...
Cristián Romo
+2  A: 

@CesarB seems to have nailed the issue, I'll just add a couple of observations.

  1. I'd strongly recommend against using wildcards in build rules. The build rules should clearly define exactly what is being built, and not depend on what files happen to be in the directory.

  2. I'd also recommend against using VPATH unless you are (1) building in a separate build directory, or (2) have your source files spread out over a large number of directories. If all your sources are in a single directory, using VPATH is only going to confuse.

  3. The := assignment form is usually only used when the variable evaluation is known to take long time, such as when using a $(shell ...). Otherwise, "=" is preferrable.

  4. Using "export" to propagate OUTDIR to concat.py (which I presume it is, since concat.py doesn't take any parameters) is a code smell. If possible, pass it as a parameter instead.

JesperE
Yes, concat.py needs to be revised. It was coded up on the spur of the moment to piece together specific files, so I will be fixing that in the near future.
Cristián Romo