Page 1 of 1

Makefile problem

Posted: Sun Feb 17, 2008 2:46 am
by davidv1992
I recently started on a OS project, and as I build it with Cygwin (instead of VC++ which i sue for me other projects) I decided to create a makefile to simplify building.

However, somehow it only compiles one of the two .S files in my kernel, and the other is just given to the linker, which, obviously, doesn't like that.

this is the Makefile I use, based on the tutorial/example in the wiki:

Code: Select all

AUXFILES := Makefile
PROJDIRS := General Boot IDTManager Exceptions
SRCFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.c")
HDRFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.h")
ASMFILES := $(shell find $(PROJDIRS) -mindepth 1 -maxdepth 3 -name "*.S");
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES)) $(patsubst %.S,%.o,$(ASMFILES))
DEPFILES := $(patsubst %.c,%.d,$(SRCFILES))

ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES) $(ASMFILES)

.PHONY: clean

CC := gcc

CFLAGS := -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align \
          -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations \
          -Wredundant-decls -Wnested-externs -Winline -Wno-long-long \
          -Wconversion -Wstrict-prototypes

AS := nasm

all: kernel

kernel: $(OBJFILES)
	@ld -o kernel -Map kernelmap $? boot/linker.ld

clean:
	-@for file in $(OBJFILES) $(DEPFILES) kernel; do if [ -f $$file ]; then rm $$file; fi;

-include $(DEPFILES)

todolist:
	-@for file in $(ALLFILES); do grep -H TODO $$file; done; true

%.o: %.c Makefile
	@$(CC) $(CFLAGS) -DNDEBUG -MD -MP -std=c99 -c $< -o $@
%.o: %.S Makefile
	@$(AS) -f elf -o $@ $<
What is wrong and how can I solve it???

Posted: Mon Feb 18, 2008 1:56 am
by Solar
Hmm... can't see a problem ATM. What is the exact behaviour / error message?

Try "make -n" to see what commands it executes exactly (overrides the "@"). If that doesn't help, try "make -d" for debug mode.

Posted: Mon Feb 18, 2008 2:41 am
by davidv1992
make -n is a usefull tip, to see exactly what it did I simply removed all the @ by hand and watched as it made the output to the file.

The problem is this:
I have 2 assembler code files in my kernel, boot/boot.S and Exceptions/exc_wrap.S
Both should be picked up by the find command and put in the macro ASMFILES, right?
As far as i can check they are.
However, the patsubst that should change their .S into .o before adding them to the OBJFILES macro only converts the first of the two, as far as I can check, leading to a compilation of only the first, and the second is just passed to the linker, who's reaction is to complain.

Posted: Mon Feb 18, 2008 5:30 am
by Solar
I still don't see how this could be happening.

As for testing, simply add a couple of targets like this to assert your lists:

Code: Select all

print_asmfiles:
        echo $(ASMFILES)

print_objfiles:
        echo $(OBJFILES)
Two unrelated notes:

1) .S is for files that, before being assembled, have to pass through the preprocessor (for those who, like me, prefer to have CPP handle includes and macro definitions - it's consistent with C/C++ and allows for identical dependency handling for ASM sources). Your ASM files are only assembled, not preprocessed, so the canonical extension should be *.s.

2) "all" should be .PHONY, too.

Posted: Mon Feb 18, 2008 5:54 am
by davidv1992
i added those, and one to show what the patsubst gives, and this is the result:

print_asmfiles:
Boot/boot.S Exceptions/exc_wrap.S

print_asmobj: (the output of the patsubst thing)
Boot/boot.o Exceptions/exc_wrap.S

print_objfiles:
Boot/kmain.o IDTManager/IDTManager.o Exceptions/exceptions.o Exceptions/IOStub.o Boot/boot.o Exceptions/exc_wrap.S


and in the case it could make any difference.
Does it matter that I use cygwin as my build enviroment?

EDIT: got it, it was the ; I accidentally put begind the ASMFILES line...

Posted: Mon Feb 18, 2008 6:16 am
by Solar
Yikes. Little cause, big effect. :-D