Oops Thanks, it works like a charmSolar wrote:Makefile?However, I'm not entirely sure how this is supposed to work. I can only think of a hack: redirecting stdout to a file (as -M outputs to the screen) and then including that. Can anyone give a proper example how this can be used?
how do you make a *good* makefile?
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: how do you make a *good* makefile?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
[ Project UDI ]
- Steve the Pirate
- Member
- Posts: 152
- Joined: Fri Dec 15, 2006 7:01 am
- Location: Brisbane, Australia
- Contact:
Re: how do you make a *good* makefile?
OK, after a bit of investigationing ( ) I've got it half working, but I haven't got the whole multiple directories thing going. Here's the really simple makefile, which would be in /src/build (where the objects will go):Solar wrote:For an out-of-tree build, you'd have to copy the makefile into the build directory first. For the "usual" out-of-tree builds you know from e.g. the GNU tools, you start with ../<sourcetree>/configure, which creates the Makefile in the current (build) directory.
Code: Select all
test: main.o lib/test.o
g++ $(LDFLAGS) -o test main.o lib/test.o
%.o: ../%.cc
g++ $(CXXFLAGS) -c $< -o $@
EDIT: OK, if I put a rule like 'lib/%.o: ../lib/%.cc', it does work. It is a big improvement already, but is there a way to do it without having a rule for each directory?
- Steve the Pirate
- Member
- Posts: 152
- Joined: Fri Dec 15, 2006 7:01 am
- Location: Brisbane, Australia
- Contact:
Re: how do you make a *good* makefile?
Well, I had a crack at making a big new kernel makefile, and it all seems to work!
How's this:
Old Busted
New Hotness
It puts the kernel binary, disk image and initrd archive all in the build folder. All the object files go either in the top of the build directory (if they are in the top of the kernel source folder), or in a folder in build that corresponds to its folder in the source tree. So kernel/lib/string.cc becomes build/lib/string.o.
How's this:
Old Busted
New Hotness
It puts the kernel binary, disk image and initrd archive all in the build folder. All the object files go either in the top of the build directory (if they are in the top of the kernel source folder), or in a folder in build that corresponds to its folder in the source tree. So kernel/lib/string.cc becomes build/lib/string.o.
Re: how do you make a *good* makefile?
I didn´t want to start a new thread for my makefile problem.
I have a working makefile, but I want to seperate my src dir and my build dir. So that I have the srcs in some "src" dir and the object files in a "build" dir (here is also my makefile). My makefile does work if I run it in the src dir (w/o the PREFIX var), but doesn´t work in my build dir.
This is my makefile:
I have the dirs like this: a dir "loader" with the subdirs "build" and "src" and this makefile is in the dir "build" and it also gets called from there. When I´m doing this I get the following error: "no rule to make target loader.o"! Creating the ".depend" file is working and it looks like it should. If I copy and paste the loader.o rule it works for this object file. But it should work for all object files. The only thing that I changed from my working makefile are the things with the $(PREFIX) var.
I hope you can help me with this.
I have a working makefile, but I want to seperate my src dir and my build dir. So that I have the srcs in some "src" dir and the object files in a "build" dir (here is also my makefile). My makefile does work if I run it in the src dir (w/o the PREFIX var), but doesn´t work in my build dir.
This is my makefile:
Code: Select all
CC = i586-elf-gcc
LD = i586-elf-ld
CFLAGS = -O2 -Wall -nostartfiles -nodefaultlibs -nostdlib -fno-builtin -march=i586 -I $(PREFIX)include
LDFLAGS = -nostdlib -T $(PREFIX)loader.ld
PREFIX = ../src/
SRCS = loader.c printf.c hardware.c memory.c string.c iso9660.c fs.c fat.c fat12.c fat16.c fat32.c cfg.c module.c elf.c idt.c pic.c pit.c kbd.c apic.c
OBJS = $(SRCS:%.c=%.o)
DEPENDFILE = .depend
all: dep loader iso
dep: $(SRCS:%=$(PREFIX)%)
$(CC) -M $(SRCS:%=$(PREFIX)%) -I $(PREFIX)include > $(DEPENDFILE)
-include $(DEPENDFILE)
loader: loader_stub.o $(OBJS)
$(LD) loader_stub.o $(OBJS) -o osloader $(LDFLAGS)
loader_stub.o: smp_startup.o loader_16bit.o $(PREFIX)loader.asm
nasm -O3 $(PREFIX)loader.asm -f elf -o loader_stub.o
loader_16bit.o: $(PREFIX)loader_16bit.asm
nasm -O3 $(PREFIX)loader_16bit.asm -f bin -o loader_16bit.o
smp_startup.o: $(PREFIX)smp_startup.asm
nasm -O3 $(PREFIX)smp_startup.asm -f bin -o smp_startup.o
iso:
cp osloader ../../../cd-rom
clean:
-rm -f osloader
-rm -f *.o
-rm -f *.s
-rm -f $(DEPENDFILE)
I hope you can help me with this.
Re: how do you make a *good* makefile?
You don't have a rule for .o files.
There are several other points I would improve (like, not having to edit the Makefile when I add a source file), but this rule should get you going.
Code: Select all
%.o: %.c Makefile
@$(CC) $(CFLAGS) -c ${PREFIX}$< -o $@
Every good solution is obvious once you've found it.
Re: how do you make a *good* makefile?
Thanks for your help, but I found a solution myself. I only needed to add "VPATH = $(PREFIX)" and it works now.
I want to edit the makefile every time I add a source file, because I have some .c files which should not get compiled and linked.
I don´t know if I´m right, but with your solution it would not work, if I changed a header file that only the files get recompiled which include this header file!?
Also what are the other points you would improve my makefile? I´m always open for learning new things and making things better!
I want to edit the makefile every time I add a source file, because I have some .c files which should not get compiled and linked.
I don´t know if I´m right, but with your solution it would not work, if I changed a header file that only the files get recompiled which include this header file!?
Also what are the other points you would improve my makefile? I´m always open for learning new things and making things better!
Re: how do you make a *good* makefile?
Put them in a different directory?FlashBurn wrote:I want to edit the makefile every time I add a source file, because I have some .c files which should not get compiled and linked.
In PDCLib (my project), I explicitly excluded all .c files on the top directory level from compilation, which allows me to have e.g. "test.c" and "test2.c" in my working dir without screwing up my make process.
Dependencies are cumulative, i.e. the dependencies from your DEPFILE would still apply. My rule states the .c file as dependency so that I can use the implicit variables $@ and $< in the command line.I don´t know if I´m right, but with your solution it would not work, if I changed a header file that only the files get recompiled which include this header file!?
Don't define CC or LD within your Makefile. They are for the user to override. Use ${CC} instead of 'gcc', but don't define it; 'make' will use a sensible default if it isn't defined, or use whatever the user did set to override it. See the 'make' manual for a list of these variables, and their defaults. I would even consider not defining CFLAGS and LDFLAGS either, as they are similarily used for user overrides.Also what are the other points you would improve my makefile? I´m always open for learning new things and making things better!
Your targets 'dep' and 'loader' don't create a file of the same name, but '.depend' and 'osloader', respectively. That means those files get re-made every time, no matter if they're outdated or not. Use 'depend.d' (or something else) as both dependency file name and Makefile target, and either rename the 'loader' target to 'osloader', or the file 'osloader' to 'loader'.
Add '.PHONY: all iso clean' to state that those three targets should always be re-made, even if an up-to-date file of that name already exists. (Try 'touch clean', and your 'make clean' won't get executed unless you remove that file 'clean' again. )
Try to replace:
Code: Select all
loader_16bit.o: $(PREFIX)loader_16bit.asm
nasm -O3 $(PREFIX)loader_16bit.asm -f bin -o loader_16bit.o
smp_startup.o: $(PREFIX)smp_startup.asm
nasm -O3 $(PREFIX)smp_startup.asm -f bin -o smp_startup.o
Code: Select all
%.o: $(PREFIX)%.asm
nasm -O3 $(PREFIX)$< -f bin -o $@
Every good solution is obvious once you've found it.
Re: how do you make a *good* makefile?
Thanks for your tips, I try if I can use them. The last one isn´t possible (I think so), because I need that these 2 files are assembled before the loader.asm, because their binaries are included into this loader.asm.
One thing I don´t really get and these are the things you said about CC and so on. I define them because otherwise the standard CFLAGS/LDFLAGS and CC are used and this doesn´t work because I´m on windows (cygwin) and I use a crosscompiler. I think I saw a makefile which also did this, but it checks on which os it is running on and then sets these vars.
One thing I don´t really get and these are the things you said about CC and so on. I define them because otherwise the standard CFLAGS/LDFLAGS and CC are used and this doesn´t work because I´m on windows (cygwin) and I use a crosscompiler. I think I saw a makefile which also did this, but it checks on which os it is running on and then sets these vars.
Re: how do you make a *good* makefile?
Doesn't matter. The dependencies of loader_stub.o require smp_startup.o and loader_16bit.o to be present; 'make' is smart enough to see there are corresponding .asm files and a .asm - to - .o rule available, and will build the required object files using that rule.FlashBurn wrote:The last one isn´t possible (I think so), because I need that these 2 files are assembled before the loader.asm, because their binaries are included into this loader.asm.
It's a personal thing. I'd leave CC and CFLAGS out of the Makefile and would set them in my environment. But then, I'm a pedant.One thing I don´t really get and these are the things you said about CC and so on. I define them because otherwise the standard CFLAGS/LDFLAGS and CC are used and this doesn´t work because I´m on windows (cygwin) and I use a crosscompiler. I think I saw a makefile which also did this, but it checks on which os it is running on and then sets these vars.
Every good solution is obvious once you've found it.
Re: how do you make a *good* makefile?
The make that I use isn´t smart enough to do the things you thought it would do I just tested it.
I come across a new problem now. I used the same style makefile for my kernel and it works as long as I´m in the src dir, but if I´m in the build dir make errors because it can´t find a rule for making ".depend", but the makefile is the same as the one which works, except for the prefix magic. Maybe you have a tip what this could be? If not its no problem, because I´m still working on completing my loader.
I come across a new problem now. I used the same style makefile for my kernel and it works as long as I´m in the src dir, but if I´m in the build dir make errors because it can´t find a rule for making ".depend", but the makefile is the same as the one which works, except for the prefix magic. Maybe you have a tip what this could be? If not its no problem, because I´m still working on completing my loader.
Re: how do you make a *good* makefile?
Sorry, haven't delved into seperate build directories myself. All I could do is reading the make manual, and I guess you can do that just as well as I.
Every good solution is obvious once you've found it.
Re: how do you make a *good* makefile?
I did, but as always there are some tricks which haven´t to be in the manual But thanks, I have a working makefile for a separate build dir and the problems with the kernel makefile can wait.