Page 2 of 2
Re: Makefile wiki
Posted: Sun Mar 04, 2012 3:25 pm
by Solar
Well, the $? was the right thing to do in the tutorial, because the command was to replace object files in a linker archive - in that case, you only need the
newer object files, not all of them.
You copy&pasted that into a linker command... which requires a somewhat different handling.
I also found that in order to compile the test drivers, the Makefile dependency needed to be removed and the compiler flags rewritten.
Why would you need to remove the Makefile dependency? The variable $< is replaced with the
first dependency; whether or not you have "Makefile" as second dependency shouldn't make a difference for the command (and, as I said, results in the test drivers being rebuilt when the Makefile changes). Works fine for me.
I don't see what you mean with "rewritten compiler flags".
Re: Makefile wiki
Posted: Mon Mar 05, 2012 1:43 am
by Civillian
Solar wrote:Works fine for me.
For me, it gave a "no rule to make target." That version of the makefile is in the first
$?-related post.
Solar wrote:I don't see what you mean with "rewritten compiler flags".
This is probably not the best way to do it, but I get linker warnings and corrupted executables if I don't.
Code: Select all
CFLAGS := -std=c99 -Werror $(WARNINGS) -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -O2 -I ./include
TESTCFLAGS := -std=c99 $(WARNINGS) -nostdinc -m32 -O2 -I ./include
Re: Makefile wiki
Posted: Mon Mar 05, 2012 2:09 am
by Solar
I just realized that the
$? copy&paste-error was mine, sorry.
Civillian wrote:For me, it gave a "no rule to make target." That version of the makefile is in the first $?-related post.
Well, it shouldn't, and it doesn't for me
using a Makefile very similar to the one in the Wiki, is all I can say.
Solar wrote:I don't see what you mean with "rewritten compiler flags".
This is probably not the best way to do it, but I get linker warnings and corrupted executables if I don't.
Ah, I see - your test drivers needing different CFLAGS than the kernel proper. No surprise there. I'd daresay quite some portion of kernel code can't be tested in user space.
Re: Makefile wiki
Posted: Mon Mar 05, 2012 2:42 am
by Civillian
Solar wrote:Well, it shouldn't, and it doesn't for me
using a Makefile very similar to the one in the Wiki, is all I can say.
Rhetorical question: why did I put "Makefile" in a file named "GNUmakefile"?
Solar wrote:Ah, I see - your test drivers needing different CFLAGS than the kernel proper. No surprise there. I'd daresay quite some portion of kernel code can't be tested in user space.
I wonder if I should put back
-fno-builtin.
As for untestable portions, I'm not worried. All my tests so far have failed: they didn't find any bugs.
Re: Makefile wiki
Posted: Mon Mar 05, 2012 2:53 am
by Solar
Civillian wrote:Rhetorical question: why did I put "Makefile" in a file named "GNUmakefile"?
The question might be rhetoric, but I don't have the slightest idea what you're hinting at. (
Edit: Clarified via PM.)
Civillian wrote:As for untestable portions, I'm not worried. All my tests so far have failed: they didn't find any bugs.
That's not a failure, that's a success in confidence. Also, if some future change breaks compatibility,
you will be immediately aware of it. Moreover, if a bug
is reported (or discovered), your existing test framework should make it easy to trigger the bug in test (instead of live running of your kernel, which is much harder to debug).
Re: Makefile wiki
Posted: Mon Mar 05, 2012 5:51 am
by Civillian
The makefile is nearing completion. Now I increased its verbosity, because I'm uncomfortable with "no news".
The final thing missing would be NASM-generated dependencies. But that can wait...
Code: Select all
KERNNAME := kernel.bin
PROJDIRS := header include lib
SRCFILES := $(shell find $(PROJDIRS) -type f -name "*.c")
ASMFILES := $(shell find $(PROJDIRS) -type f -name "*.s")
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES)) $(patsubst %.s,%.o,$(ASMFILES))
TESTFILES := $(patsubst %.c,%_test,$(SRCFILES))
DEPFILES := $(patsubst %.c,%.d,$(SRCFILES))
TESTDEPFILES := $(patsubst %,%.d,$(TESTFILES))
WARNINGS := -Wall -Wextra -pedantic
CFLAGS := -std=c99 -Werror $(WARNINGS) -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -O2 -I ./include
TESTCFLAGS := -std=c99 $(WARNINGS) -nostdinc -fno-builtin -m32 -O2 -I ./include
ASFLAGS := -f elf -Ox
LDFLAGS := -T linker.ld -m elf_i386
.PHONY: build clean check tests
build: $(KERNNAME)
$(KERNNAME): $(OBJFILES) linker.ld
@echo -n "ld:"; \
for file in $(OBJFILES); do \
echo "\t $$file"; \
done; \
echo "\t -> " $@
@ld $(LDFLAGS) -o $@ $(OBJFILES)
clean:
-@$(RM) -v $(wildcard $(OBJFILES) $(DEPFILES) $(TESTFILES) $(TESTDEPFILES) $(KERNNAME) $(shell find -type f -name "*~"))
check: tests
-@failed=0; file_count=0; \
echo "---"; \
for file in $(TESTFILES); do \
echo "test:\t $$file"; \
./$$file; \
failed=`expr $$failed + $$?`; \
file_count=`expr $$file_count + 1`; \
done; \
echo "\ttests failed: $$failed in $$file_count test files.\n"
tests: $(TESTFILES)
-include $(DEPFILES) $(TESTDEPFILES)
%.o: %.c GNUmakefile
@echo "gcc:\t" $< "\t-> " $@
@$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
%.o: %.s GNUmakefile
@echo "nasm:\t" $< "\t-> " $@
@nasm $(ASFLAGS) $< -o $@
%_test: %.c GNUmakefile
@echo "gcc:\t" $< "\t-> " $@
@$(CC) $(TESTCFLAGS) -MMD -MP -D TESTING $< -o $@
Re: Makefile wiki
Posted: Mon Mar 05, 2012 6:04 am
by Solar
Civillian wrote:The final thing missing would be NASM-generated dependencies.
It appears that NASM has quite similar dependency-generating options as GCC (-MD, -MP et al.):
clicky
Re: Makefile wiki
Posted: Mon Mar 05, 2012 6:53 am
by Civillian
Thanks for the link, which was more informative than the manpage.
Here's the NASM dependencies makefile, which
seems to be working.
Code: Select all
KERNNAME := kernel.bin
PROJDIRS := header include lib
SRCFILES := $(shell find $(PROJDIRS) -type f -name "*.c")
ASMFILES := $(shell find $(PROJDIRS) -type f -name "*.s")
OBJFILES := $(patsubst %.c,%.o,$(SRCFILES)) $(patsubst %.s,%.o,$(ASMFILES))
TESTFILES := $(patsubst %.c,%_test,$(SRCFILES))
DEPFILES := $(patsubst %.c,%.d,$(SRCFILES))
ASMDEPFILES := $(patsubst %.s,%.s.dep,$(ASMFILES))
TESTDEPFILES := $(patsubst %,%.d,$(TESTFILES))
WARNINGS := -Wall -Wextra -pedantic
CFLAGS := -std=c99 -Werror $(WARNINGS) -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -O2 -I ./include
TESTCFLAGS := -std=c99 $(WARNINGS) -nostdinc -fno-builtin -m32 -O2 -I ./include
ASFLAGS := -f elf -Ox -w+all
LDFLAGS := -T linker.ld -m elf_i386
.PHONY: build clean check tests
build: $(KERNNAME)
$(KERNNAME): $(OBJFILES) linker.ld
@echo -n "ld:"; \
for file in $(OBJFILES); do \
echo "\t $$file"; \
done; \
echo "\t -> " $@
@ld $(LDFLAGS) -o $@ $(OBJFILES)
clean:
-@$(RM) -v $(wildcard $(OBJFILES) $(DEPFILES) $(TESTFILES) $(TESTDEPFILES) $(ASMDEPFILES) $(KERNNAME) $(shell find -type f -name "*~"))
check: tests
-@failed=0; file_count=0; \
echo "---"; \
for file in $(TESTFILES); do \
echo "test:\t $$file"; \
./$$file; \
failed=`expr $$failed + $$?`; \
file_count=`expr $$file_count + 1`; \
done; \
echo "\ttests failed: $$failed in $$file_count test files.\n"
tests: $(TESTFILES)
-include $(DEPFILES) $(TESTDEPFILES) $(ASMDEPFILES)
%.o: %.c GNUmakefile
@echo "gcc:\t" $< "\t-> " $@
@$(CC) $(CFLAGS) -MMD -MP -c $< -o $@
%.o: %.s GNUmakefile
@echo "nasm:\t" $< "\t-> " $@
@nasm $(ASFLAGS) -MD $<.dep -MP $< -o $@
%_test: %.c GNUmakefile
@echo "gcc:\t" $< "\t-> " $@
@$(CC) $(TESTCFLAGS) -MMD -MP -D TESTING $< -o $@
Re: Makefile wiki
Posted: Mon Mar 05, 2012 10:42 am
by Civillian
For my current needs, the makefile is complete, unless anyone spots bugs.
Otherwise, thank you Solar, and Cognition, for your contributions.
See you all later.
Edit:
Rewritten the
check section. In my test drivers, I usually include more than one test, so the exit code in case of failure may be greater than 1.
Code: Select all
check: tests
-@echo "--- TESTING BEGIN ---"; \
for file in $(TESTFILES); do \
./$$file; \
exit_code=$$?; \
if [ $$exit_code -gt 0 ]; then \
echo -n "FAILS ($$exit_code)\t"; \
else \
echo -n " *OK*\t\t"; \
fi; \
echo "$$file"; \
done; \
echo "--- TESTING END ---"