Building individual directories separately

Programming, for all ages and all languages.
Post Reply
CWood
Member
Member
Posts: 127
Joined: Sun Jun 20, 2010 1:21 pm

Building individual directories separately

Post 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?
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Building individual directories separately

Post 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.
Last edited by turdus on Sun Jan 22, 2012 8:03 am, edited 1 time in total.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Building individual directories separately

Post by Solar »

Damn... I just realize I never finished the Makefile tutorial, rev. 2... and this scratch version isn't very helpful yet...
Every good solution is obvious once you've found it.
CWood
Member
Member
Posts: 127
Joined: Sun Jun 20, 2010 1:21 pm

Re: Building individual directories separately

Post 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...
CWood
Member
Member
Posts: 127
Joined: Sun Jun 20, 2010 1:21 pm

Re: Building individual directories separately

Post 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
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Building individual directories separately

Post 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.
CWood
Member
Member
Posts: 127
Joined: Sun Jun 20, 2010 1:21 pm

Re: Building individual directories separately

Post 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!
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Building individual directories separately

Post 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.
Every good solution is obvious once you've found it.
User avatar
turdus
Member
Member
Posts: 496
Joined: Tue Feb 08, 2011 1:58 pm

Re: Building individual directories separately

Post 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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Building individual directories separately

Post 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.
Every good solution is obvious once you've found it.
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Building individual directories separately

Post by gravaera »

You can also generate relocatable archives for each directory, which is what I do. Good luck :)
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
Post Reply