L. Z.
L. Z.

Reputation: 102

Makefile for assembly programs treats source files as target

I am new to GNU make. I would like to compile all my assembly source files into separate object files with the same names. In the future, if I add more assembly source files, the Makefile should still work without modification.

e.g. I am in root directory

$ ls
Makefile obj src
$ ls src
file1.s file2.s

After make I want

$ ls obj
file1.o file2.o

In the future if I add a file3.s to my src directory, after make I would like a new file3.o in my obj directory.

I've read about static pattern rules in the GNU make manual, and I think it is what I need. I have written the following Makefile:

path = /path/to/toolchain/bin
AS = $(path)/llvm-mc
ASFLAGS = -filetype=obj

srcdir = src
sources = $(srcdir)/*.s
objdir = obj
objects = $(objdir)/*.o

.PHONY: all
all: $(objects)

$(objects): $(objdir)/%.o: $(srcdir)/%.s
        $(AS) $(ASFLAGS) $< -o $@

.PHONY: clean
clean:
        rm $(objects)

After running make in shell, I got the error:

make: *** No rule to make target `src/*.s', needed by `obj/*.o'.  Stop.

Can anyone tell me what mistake I made? I have checked that I used tab in front of the recipe. Thank you in advance.

Upvotes: 0

Views: 508

Answers (1)

MadScientist
MadScientist

Reputation: 100966

This cannot work:

objects = $(objdir)/*.o

When you run make for the first time, what will this expand to? You have no object files, so the wildcard will expand to no files. Or if you have some object files and create a new source file what will it expand to? It will expand only to the existing object files.

Since you're only asking make to build object files that already exist, it will never build ones that don't exist.

What you need to do is tell make to build an object file for every source file.

You can do that like this:

srcdir = src
sources = $(wildcard $(srcdir)/*.s)
objdir = obj
objects = $(sources:$(srcdir)/%.c=$(objdir)/%.o)

Upvotes: 5

Related Questions