lkubuntu

A listing of random software, tips, tweaks, hacks, and tutorials I made for Ubuntu

shbuild – An alternative to GNU Make… using shell scripts

I’ve been trying to find a make alternative or interface using more common languages, and so far, the only one I’ve found was waf (which, IMHO, wasn’t well documented and overly complex). Maybe I haven’t done enough research, but seriously, why do people have to reinvent the wheel for just a build system?

I spent around two days writing this (haven’t wrote shell scripts for a while), and I’m pleased of the result. Notice that this script is still in alpha stage, so I can’t guarantee that everything will work as expected. The main difference between this build system and others is that it works by commands (functions), which then runs the compilers, linkers, and whatever else is needed. Because of this design, it should (in theory) be more powerful and easier to code than a normal makefile. Here is an example of what I’m saying (sorry about the horrible formatting, wordpress breaks it):

Buildfile:

build() {
sources='file1.c file2.c file3.c file4.c file5.c file6.c main.c'
objects='file1.o file2.o file3.o file4.o file5.o file6.o main.o'
output="main"
runtargets $sources $objects 'gcc -c $target -o $output'
gcc $objects -o $output
}
addcmd build build Builds the project
default_command=build

Makefile:

all: main
file1.o: file1.c
gcc -c file1.c -o file1.o
file2.o: file2.c
gcc -c file2.c -o file2.o
(repeat this for each of the targets...)
main: file1.o file2.o file3.o file4.o file5.o file6.o main.o
gcc file1.o file2.o file3.o file4.o file5.o file6.o main.o -o main

For me, the buildfile technique seems much cleaner and easier, and anyways, it’s shell, so you can call functions within it to make your life even easier, etc…

The other thing that I spent a bit of time on was to add common utility functions so you don’t have to write them yourself. Some of them include:

  • Automatic uninstaller
  • printc for printing text in colors
  • Many array utilities
  • Help system (still a WIP)

No documentation is currently available, since I’m still polishing it, but I will add some soon. In the meantime, you can just browse through the source (honestly, it will only take you a couple of minutes, it’s currently very small). You can also check the buildfile for it, as it contains many of the functions you would probably use.

Source is located here: https://github.com/MiJyn/shbuild. You can easily build and install the source by using the “build.sh” script (it’s simply a wrapper to use the unbuilt version of shbuild), like so:

sudo ./build.sh install

Let me know what you think, anything constructive (bug reports, ideas, patches, things that were unclear in this post, etc…) is appreciated :)

About these ads

11 responses to “shbuild – An alternative to GNU Make… using shell scripts

  1. foo January 9, 2013 at 5:52 am

    Please no! We need less build systems not more!

  2. kate gencott January 9, 2013 at 7:50 am

    Keep going on, i appreciate the way you see & think how developing should move on. There is a real need to redefine a bunch of design model.

  3. Lubomir January 9, 2013 at 8:47 am

    The comparison between your Buildfile and Makefile is not really fair: you do not need to repeat the rules for each .o file in Makefile since the default rule is pretty much equivalent (and even it you needed something more elaborate to create .o files, you could use %.o : %.c type of rule and write it only once).

    Big downside of your solution is that running the script, it will recompile the whole project, while make only recompiles the files that changed.

    • MiJyn January 9, 2013 at 4:17 pm

      Oh really? I haven’t heard of the other syntax actually… Thanks for letting me know :) About the script recompiling the whole project, it won’t (runtargets works like the makefile, it checks to see if the output is older than the source before running the command).

  4. Pavel January 9, 2013 at 10:14 am

    because shell scripts will be so fking fast with big projects and are so cross plattform. Throw this away and rather use CMake. Here are some things you might consider when writing a new build system: http://martine.github.com/ninja/manual.html#_philosophical_overview, which google has already done btw.

    • MiJyn January 9, 2013 at 4:23 pm

      I’m actually a fan of CMake, but it’s too high-level for my purposes, and anyways, it uses a non-standard language (shell, in comparison, is a very standard language, and most people know how to use it). And yes, I agree that it isn’t fast or cross-platform, but heck, if it’s only a linux project, why not? Speed should not be affected by the size of the project though.

  5. Vincent Bernat January 9, 2013 at 11:05 am

    Your Makefile is less than minimal. Make already knows how to build .o from .c. If it didn’t, you can put a generic rule .c.o (or %.o: %.c). Make would also take many variables automatically (CFLAGS, CC) that users are expecting to be overridable. There are also shortcuts like $< or $@. If you think that make doesn't do enough things, you should look at automake that will find dependencies and generate useful targets like install or dist that are usually expected from a build system.

  6. Stefano Rivera January 9, 2013 at 3:12 pm

    If your Makefile looks like that, you’re doing something wrong.
    You should be able to do:

    sources=file1.c file2.c file3.c file4.c file5.c file6.c main.c
    objects=file1.o file2.o file3.o file4.o file5.o file6.o main.o
    all: main
    main: $(objects)
        $(CC) -o $@ $^
    • Michael Wild (@themiwi) January 10, 2013 at 5:43 am

      Much better to use:

      objects=$(addsuffix .o,$(basename $(sources))

      • MiJyn January 10, 2013 at 5:48 am

        oh yeah, good idea

  7. Connor January 10, 2013 at 5:02 pm

    A relatively simple boilerplate makefile isn’t any longer than your shell script and doesn’t give up make features like dependency resolution and partial rebuilding.

    http://pastebin.com/123tPAyR

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 174 other followers

%d bloggers like this: