Makefie question

Programming, for all ages and all languages.
Post Reply
McZ

Makefie question

Post by McZ »

I havn't written any Makefiles before but now I would like to use them, so I tried and successfully made my Makefiles with some help by looking at others makefiles and reading Q&A's here at the forum.

altough I have one problem, I have this make file

Code: Select all

all : clib.a kernel.bin

clib.a : 
       make -C clib

kernel.bin :
       make -C kernel

clean :
       make -C clib clean
       make -C kernel clean
so this is the make file in the Root dir of my OS source to compile both my clib code and kernel code.

so to my problem, if I compile a kernel and the clib my writing make at the root dir it will not recompile source files that have been updated after last compile time so I have to clean and rebuild everything or manually go into the clib/kernel dir and write make in the respective source directory where the changes are made and then the updated sourcefiles will recompile and linked to a new updated kernel/clib.

So my question is WHY do I have to manually enter the clib/kernel dir and write make there to recompile updated sources, have I missed something in the "main" makefile

EDIT:

Then I have another question, is it positible to define my CFLAGS to use in the "main" Makefile and then they will be used if not new CFLAGS are defined in subdir makefiles?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Makefie question

Post by Solar »

What you are trying to do here is a "recursive make". Aside from being a pain to maintain (seperate Makefiles in each subdirectory), it is also prone to several subtle problems. You might want to read "Recursive make considered harmful", which points out some caveats of make. I might also point to the top-level, non-recursive Makefile of the PDCLib (see my signature), which - if I may say so myself - shows a couple of nice things you can do with a Makefile.

Your specific problem is that your targets clib.a and kernel.bin are not defined to be ".PHONY", and do not have dependencies. That means, if those two files exist at all, "make" is satisfied, and exits. (Try "touch clean && make clean" to see what I mean - "clean" will exist, so make does nothing.)

If you want the commands to be executed every time you call "make", add the following line:

Code: Select all

.PHONY: clib.a kernel.bin clean
Every good solution is obvious once you've found it.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Makefie question

Post by Colonel Kernel »

I managed to get recursive make to work for me, but it involved upgrading to GNU make 3.81 and using eval all over the place. However, now my makefiles look like this:

Code: Select all


include ../../Build/Makefile.include
include ../Build/Makefile-kernel.include

# Assign some variables that will be common across all architectures.
Executive_sources      = ExceptionDispatcher.c main.c
Executive_includedirs   = ../../../Include ./
Executive_targetdir      = ../../../Lib
Executive_target      = libExecutive.a

# Assign the configurations to each "project" according to architecture...
Executive_x86_uni_configs      = $(kernel_x86_uni_configs)
Executive_x86_uni_sources      = $(Executive_sources) \
                          BootLoaderInfo_x86_Multiboot.c \
                          BootLoaderInfoTranslator_x86_Multiboot.c \
                          ExceptionDispatcher_x86.c \
                          InterruptDispatcher_x86_uni.c \
                          MBMemFieldsPmmRegionList.c \
                          MBMemmapPmmRegionList.c \
                          MBModulePmmRegionList.c \
                          Multiboot.c \
                          WritableTrapFrame_x86.c

Executive_x86_uni_includedirs   = $(Executive_includedirs) \
                           ../../../Include/Kernel/Architecture/x86 \
                           ../../../Include/Kernel/Architecture/x86_uni
Executive_x86_uni_targetdir      = $(Executive_targetdir)
Executive_x86_uni_target      = $(Executive_target)

# Make sure the generated rules can find all the sources.
VPATH = ../Architecture/x86/Executive

$(eval $(call createStandardPrologue,Executive_x86_uni))
$(eval $(call createStandardLibRules,Executive_x86_uni))
which is pretty OK to maintain. Took me a while though. :P
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Makefie question

Post by Solar »

I added a commented version of the PDCLib Makefile into the Wiki, at MartinBaute/Scratchbook. I hope some of the tricks I did there are helpful for others.
Every good solution is obvious once you've found it.
McZ

Re:Makefie question

Post by McZ »

I got my makefiles to work with the .PHONY line, altough I will look into the non-recursive makefiles I have read a little about it looks really advanced so I guess that is why many people still using recursive makefiles.

EDIT: I actually read the entire text about your PDCLib makefile even though I should be in bed for like 1 hour ago but it was interesting and good written. altough I would like to know how I can make one makefile to compile both my kernel and clib I have recreated my sub-makefiles for the kernel and clib to use the self-searching for .c and .asm files it works really nice.. I will try to add the dependency checking too.
Post Reply