Page 1 of 1

Building individual directories separately

Posted: Sun Jan 22, 2012 7:16 am
by CWood
Since this doesn't directly pertain to OSDev, I decided to put it here.

I've recently decided to scrap the monolithic design, in favor of a picokernel (hadn't done anything on the kernel at this point ^^), and leave off the bootloader, until later, and use GRUB for now (also means that my kernel is multiboot compliant, which is always a plus). So, I'm now working on said picokernel, and am currently adding modules. I've got most issues worked out, but one still stands. The makefile.

Is there any way to get my makefile to generate a separate executable, for each directory in the Modules/ directory, without having to declare a separate rule for each (makefiles are supposed to be low maintenance, aren't they?), so that I don't have to modify said file each time I add support for a new piece of hardware, etc.

Understandably, make isn't designed for this kind of issue, as generally, programmers don't have to deal with this sorta thing daily, so would I have to declare a makefile for each and every module, simply having each one the same (wastes disk space), or, failing that, is there a commandline hack that I could do, that does it for me?

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 7:41 am
by turdus
CWood wrote:Is there any way to get my makefile to generate a separate executable, for each directory in the Modules/ directory
Yes. http://www.gnu.org/software/make/manual/make.html

There are many ways to do this, here's mine:

Code: Select all

ASMSRCS=${wildcard */${ARCH}/main.asm} ${wildcard */*/${ARCH}/main.asm} ${wildcard */*/*/${ARCH}/main.asm}
ASMBINS=${ASMSRCS:/${ARCH}/main.asm=.o}

${ASMBINS}: ${ASMSRCS}
	@echo " ASM	${basename $@} (${ARCH})"
	@make ARCH="${ARCH}" -C ${basename $@}/${ARCH} -k --no-print-directory

clean: ${ASMBINS}
	@rm -f ${ASMBINS}
This will walk through every directory that holds a subdirectory named after the architecture I'm compiling for, and has a main.asm in it (if you don't want separation per architecture, you can check the existence of a Makefile in each subdirectory). It will enter each of that directory and interpret the Makefile there to assemble the object file.
Directory structure looks like (where drv/ is similar to your Modules/ directory):

Code: Select all

./drv/Makefile
./drv/pci/ne2k/x86_32/main.asm
./drv/pci/ne2k/x86_32/Makefile
./drv/pci/ne2k/x86_64/main.asm
./drv/pci/ne2k/x86_64/Makefile
./drv/ps2/x86_32/main.asm
./drv/ps2/x86_32/Makefile
./drv/ps2/x86_64/main.asm
./drv/ps2/x86_64/Makefile
...etc.
I have different Makefile for each module, but you can use the same by changing main Makefile, and instead of calling make again call gcc or whatever you like.

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 10:42 am
by Solar
Damn... I just realize I never finished the Makefile tutorial, rev. 2... and this scratch version isn't very helpful yet...

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 11:21 am
by CWood
Thanks for your replys guys, really appreciated.

@berkus:
CMake looks interesting, currently doing research, but this is the same as doing it through command-line fu: I'm tight for time, and I'd sooner spend the time hacking on my kernel, rather than doing sysadmining on my project :-)

@turdus:
If avoidable, I want to try to stay away from a makefile in every directory, as that is unbelievably messy (just like my existing makefile ^^). Just spent the last few hours fighting with my problem. The issue is, that each directory has an arbitrary amount of files, that I need linking into a flat binary file; one per directory.

Is it possible to declare a target, with a dependency such as:

Code: Select all

modules: `find $ModuleDir -type d` 
and then use pattern rules to apply commands to said directories? Hmm...

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 11:43 am
by CWood
@berkus:
Fair point. Tomorrow, I'll get learning. Right now, I've had enough misbehaving code for one day, thank you very much :)

Cheers,
Connor

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 11:45 am
by bluemoon
CWood wrote: If avoidable, I want to try to stay away from a makefile in every directory, as that is unbelievably messy (just like my existing makefile ^^). Just spent the last few hours fighting with my problem. The issue is, that each directory has an arbitrary amount of files, that I need linking into a flat binary file; one per directory.
How about this?

Code: Select all

MODULES := $(wildcard mod_*)

all: project

project: $(MODULES)
        @echo [make all] $(MODULES)

mod_%: mod_%/Makefile
        @echo make -f $@/Makefile

mod_%/Makefile: Makefile.template Makefile
        @echo cp $@ $<
The Makefile for modules are synchronized automatically, and I guess you don't worry on disk space.

Re: Building individual directories separately

Posted: Sun Jan 22, 2012 3:25 pm
by CWood
@Solar:
just read through the code for your new makefile, mostly self documenting, understood most of it, and gonna have a go at using it tomorrow :D Thanks! Can't wait till you update the wiki with it!

Re: Building individual directories separately

Posted: Mon Jan 23, 2012 2:20 am
by Solar
@ CWood:

It's basically a bastardized version of what Automake does, without the need for Automake (Makefile.am) itself, and resulting in a single Makefile setup (instead of the recursive make that Automake generates).

Currently I'm away from dev'ing, and working on a major LaTeX / translation project, that's why the tutorial was left hanging. I'm glad you could make sense out of the uncommented source.

Re: Building individual directories separately

Posted: Mon Jan 23, 2012 4:07 am
by turdus
CWood wrote:If avoidable, I want to try to stay away from a makefile in every directory
It's possible, as I wrote instead of calling make you can call gcc or whathever. I need Makefile because different architectures require different tools.
CWood wrote:The issue is, that each directory has an arbitrary amount of files, that I need linking into a flat binary file; one per directory.
Then the way I showed would work for you. The variable will contain all object files in subdirectories, so it's easy to link them together. As for "find -d" it would not work, you should name a source files otherwise you won't be able to get object file names.

Code: Select all

CSRCS=${wildcard */*.c} ${wildcard */*/*.c} ${wildcard */*/*/*.c}
CBINS=${CSRCS:.c=.o}

${CBINS}: ${CSRCS}
   @gcc $@ -c ${$@:.c=.o}

link: ${CBINS}
   @gcc ${CBINS} -o linkedtogether.o
This will call gcc for every .c file, and afterwards link all .o into one object, regardless of which subdirectory they're in. You might have mess with proper paths if you do not enter subdirectories, tough.

Re: Building individual directories separately

Posted: Mon Jan 23, 2012 6:34 am
by Solar
I added some comments to the scratch version of "Makefile2" (as linked above). If anyone feels like picking up the ball and take it from there, feel free to do so. I won't be doing anything C/C++ related for some time, so I won't put it to the test anytime soon.

Re: Building individual directories separately

Posted: Thu Mar 01, 2012 12:46 pm
by gravaera
You can also generate relocatable archives for each directory, which is what I do. Good luck :)