Build System

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Build System

Post by jzgriffin »

Right now I have a fairly large collection of makefiles for a build system, all configured with four .mak files in /scripts. They make life pretty easy, so long as I don't add any new directories, rename anything, etc. I was wondering if there were any better alternatives and what other OSdevs use. There's no need for the ability to work on Windows, since I find OSdev on Windows a miserable experience and don't support it.
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post by 01000101 »

sorry, I use batch files. :roll:
Hangin10
Member
Member
Posts: 162
Joined: Wed Feb 27, 2008 12:40 am

Post by Hangin10 »

I was using batch files, as I do for most all of my projects (which usually just takes a g++ *.cpp to compile anyway, essentially). But once I learnt how to use makefiles, boy did it both cut down compile time and make things much prettier to handle.

If there's an easier way to do things, I'd also love to hear about it.
There's probably a way to allow make to search various directories for C and O files and then link everything together in one statement with user defined flags, but I haven't found it yet.

I've also been writing a FAT12 tool so that I can add a make-grub-image portion to my makefile. Disk image tools are lacking on Windows, IMO. I don't necessarily want to mount stuff, just manufacture the image with a certain layout. It's almost done. I'll release it with source if anyone really wants it (it's bound to suck) when it is done. Lot of college work lately, so I haven't had much time to work on stuff :(.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

The PDCLib Makefile (abridged in the Makefile wiki article) is the best I have put together so far, and has served me (with slight modifications) in a number of other projects already.

I have a strong preference for using "standard" solutions for various reasons, which is why I didn't look into alternatives (like CMake, Ant or the like) too closely. I wouldn't dream of using a build system that's tied to a specific IDE, for example.


Edit:
There's probably a way to allow make to search various directories for C and O files and then link everything together in one statement with user defined flags, but I haven't found it yet.
See the wiki article I referenced above - it's quite easy actually.
Every good solution is obvious once you've found it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Build System

Post by Brendan »

Hi,

I write most of my source code in assembly, where the first file is the only file that includes other files.

Because of this I wrote my own utility to parse the first file and determine if anything has changed, so that I have no need to maintain makefiles, etc - I just tell my utility which file is the first file and it handles everything else.

To be more specific, my utility checks if anything changed, then runs NASM or YASM while converting the original source code into cross-linked HTML files, then generates a dissassembly while generating a hex dump while generating a list of debugging markers. It'll also build many seperate binaries in parallel.

In this way, I can use one command to start my utility and have 30 different binaries all being converted, assembled, disassembled, etc in parallel. This large amount of parallelism makes a huge difference to the time it takes to build my project - it's significantly faster than "make -j".

To tie everything together I use a bash script. This just runs "make" to update my utilities (written in C), then runs my build utility to update most of the binaries, then runs my build utility again to update anything that's left, then it does some simple stuff (e.g. copy the resulting boot image and some other stuff to my TFTP server's directory).

Lastly, I use KDE's keyboard shortcuts so that when I press F12 it runs my bash script (and builds everything in the project).

If you add it all up, it means that I can press one key and turn on several computers, and the entire project will be rebuilt before those computers are ready to boot from network; and there's no makefile maintenance to annoy me (I don't need to touch anything unless I add a new target binary to the project).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post by jzgriffin »

This command can be used in makefiles to find lists of .c, .s, .asm, and .cpp files in the current directory and all subdirectories, then replace the extensions with .o:

Code: Select all

OBJ = $(shell find . -type f -name "*.[cs]" -o -name "*.asm" -o -name "*.cpp" | sed -e "s/\\.\(c\|s\|asm\|cpp\)/\\.o/g")
Example:

Code: Select all

CC = gcc
CFLAGS = -Wall -Werror -O3
AS = nasm
ASFLAGS = -f elf
CXX = g++
CXXFLAGS = $(CFLAGS)
RM = rm -f

BIN = output
OBJ = $(shell find . -type f -name "*.[cs]" -o -name "*.asm" -o -name "*.cpp" | sed -e "s/\\.\(c\|s\|asm\|cpp\)/\\.o/g")

.PHONY: clean distclean

all: $(BIN)

$(BIN): $(OBJ)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

%.o: %.asm
    $(AS) $(ASFLAGS) $< -o $@

%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

%.o: %.s
    $(AS) $(ASFLAGS) $< -o $@

clean:
    $(RM) $(OBJ)

distclean:
    $(RM) $(BIN) $(OBJ)
Could be useful.

Is there any known workaround to the problem I mentioned earlier, about it being a pain to update the subdirectory makefiles when I need to add a new option to a $(MAKE) call, add a new directory, rename a preexisting directory, etc.?

Edit: Sounds like a sweet setup, Brendan.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Jeremiah Griffin wrote:This command can be used in makefiles to find lists of .c, .s, .asm, and .cpp files in the current directory and all subdirectories, then replace the extensions with .o:

Code: Select all

OBJ = $(shell find . -type f -name "*.[cs]" -o -name "*.asm" -o -name "*.cpp" | sed -e "s/\\.\(c\|s\|asm\|cpp\)/\\.o/g")
Why not using make's patsubst()? That SED regexp looks pretty intimidating (as in, happy debugging if you got one of the backslashes wrong)...
Is there any known workaround to the problem I mentioned earlier, about it being a pain to update the subdirectory makefiles when I need to add a new option to a $(MAKE) call, add a new directory, rename a preexisting directory, etc.?
Have a look at the Wiki page I mentioned above. You could replace the hardcoded PROJDIR with a "find . -type d" if you like. This kind of Makefile doesn't have subdirectory Makefiles.
Every good solution is obvious once you've found it.
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post by jzgriffin »

Cool, cool...I was considering something like that myself, but stripping the ./ prefix so that 'make directoryname' would be possible. How about recursive $(MAKE) options? i.e. --no-print-directory.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Every good solution is obvious once you've found it.
jzgriffin
Member
Member
Posts: 190
Joined: Tue Sep 26, 2006 1:40 pm
Libera.chat IRC: Nokurn
Location: Ontario, CA, USA
Contact:

Post by jzgriffin »

Thanks for the link! I was already going to redo the makefile(s) for my OS rewrite to only have one or two levels of recursion, and now I actually have a proper reason. Even so, I'm still glad to have found $(MAKEFLAGS) in the make documentation. Cheers.
Post Reply