Haskell: A Pretty Nice Language
May 19, 2009 at 4:43 pm | In Uncategorized | 2 CommentsI was going through one of those “every language sucks” periods a few days back, so I decided to do something productive and learn me a Haskell. So far, I’m liking it: the pure functional style isn’t as hard as I expected, monads are okay after a bit (though I’m still a little suspicious of them), the strict typing isn’t too much of a burden, the polymorphic types are bliss to use, and the pattern matching is simply wonderful. It also comes with an extensive set of libraries and a central repository, which is nice to find in a non-mainstream language. Overall, I think Haskell is a good language to know.
Super-Makefile has levelled up! SuperMakefile became BashBuild!
May 8, 2009 at 11:55 pm | In coding | Leave a CommentI had just about reached the limits of what was possible with just a makefile, but I still felt like adding more. So I rewrote the thing today as a shell script. Now, you simply call it as ‘./configure’, and it generates the Makefile for you. The script is still configured in much the same manner as the old Makefile, except now you don’t have to specify a compiler.
More importantly, the rewrite has allowed a whole bunch of new tricks, including:
- Command-line specification of the install prefix
- Now the commands are familiar to anyone who has ever done a “./configure && make && sudo make install” before
- Out of source builds are now implemented
- Autodetection of the C compiler
And most importantly:
- Plenty of room to grow
Unfortunately, the code took a major step backwards in attractiveness. Over the next few days I may tinker around with it in an attempt to make it not look quite so bad, and possibly move more logic out into the configure script.
Other major news of the day: I finally dumped bzr for git, just so I could use GitHub. The new project is named BashBuild.
Revenge of the Super-Makefile
May 5, 2009 at 8:35 pm | In coding | Leave a CommentTags: c, coding, makefile
So today I found some more things that the old Makefile was lacking. An “install” target, a “.PHONY” target to prevent breakage down the line, and the ability to recursively build subprojects. A few hours later, I have this:
PROJECT=foo VERSION=0.0.1 SOURCES=bar.c baz.c SUBPROJECTS=xyzzy fnord LIBRARY=-lm INCPATHS=xyzzy fnord LIBPATHS=fnord PREFIX=/usr/local LDFLAGS= CFLAGS=-c -Wall -g CC=gcc # ------------ MAGIC BEGINS HERE ------------- # We want subprojects to use these variables export CC export PREFIX # Automatic generation of some important lists OBJECTS=$(SOURCES:.c=.o) INCFLAGS=$(foreach TMP,$(INCPATHS),-I$(TMP)) LIBFLAGS=$(foreach TMP,$(LIBPATHS),-L$(TMP)) # Set up the output file names for the different output types ifeq "$(LIBRARY)" "shared" BINARY=lib$(PROJECT).so else ifeq "$(LIBRARY)" "static" BINARY=lib$(PROJECT).a else BINARY=$(PROJECT) endif all: $(SOURCES) $(SUBPROJECTS) $(BINARY) $(BINARY): $(OBJECTS) ifdef SOURCES # Assemble the object files into the right type of binary ifeq "$(LIBRARY)" "static" ar rcs $(BINARY) $(OBJECTS) else ifeq "$(LIBRARY)" "shared" $(CC) -shared $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@ else $(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@ endif endif $(SUBPROJECTS): make -e -C $@ .c.o: $(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@ install: @ for i in $(SUBPROJECTS); do make -e -C $${i} install; done ifdef SOURCES ifeq "$(LIBRARY)" "static" install $(BINARY) $(PREFIX)/lib else ifeq "$(LIBRARY)" "shared" install $(BINARY) $(PREFIX)/lib else install $(BINARY) $(PREFIX)/bin endif endif distclean: rm -f $(BINARY) $(OBJECTS) @ for i in $(SUBPROJECTS); do make -C $${i} distclean; done clean: rm -f $(OBJECTS) @ for i in $(SUBPROJECTS); do make -C $${i} clean; done .PHONY: all clean distclean install $(SUBPROJECTS)
It’s longer, but not by too much, and now I can safely say it has everything I have ever needed in a fancy build system. It would be nice if I could get pretty colourized output, but this Makefile reliably builds, cleans, and installs the projects I have tested it on.
The Super-Makefile
May 4, 2009 at 8:36 pm | In coding | Leave a CommentTags: c, coding, makefile
After toying with build systems off and on for months, I concluded today that make is about as advanced as I ever need to get for my projects. In the past, I recall using this gem of a Makefile. But my needs in a build process have grown a little. First of all, I now prefer C to C++, so that had to be changed. Then I had to go about adding static and shared library abilities to it. Then I added “clean” and “distclean” build targets, and include and library search paths got introduced somewhere along the way.
After good half hour of modification, I had the following Makefile, posted here mainly so I can find it easily from any computer. By modifying the first six variables defined in the Makefile, it can be adapted to almost any C project of reasonable complexity. It has no support for cross-platform library identification, out-of-source builds, or debug and release build toggles. But on the other hand, I can never get those things to work right any way.
Toggling between static library, shared library, and executable build modes is performed by setting the LIBRARY variable to “static”, “shared”, or anything that isn’t those two values.
PROJECT=foo SOURCES=bar.c baz.c LIBRARY=nope INCPATHS=../some_other_project/ LIBPATHS=../yet_another_project/ LDFLAGS=-ldosomething CFLAGS=-c -Wall CC=gcc # ------------ MAGIC BEGINS HERE ------------- # Automatic generation of some important lists OBJECTS=$(SOURCES:.c=.o) INCFLAGS=$(foreach TMP,$(INCPATHS),-I$(TMP)) LIBFLAGS=$(foreach TMP,$(LIBPATHS),-L$(TMP)) # Set up the output file names for the different output types ifeq "$(LIBRARY)" "shared" BINARY=lib$(PROJECT).so LDFLAGS += -shared else ifeq "$(LIBRARY)" "static" BINARY=lib$(PROJECT).a else BINARY=$(PROJECT) endif all: $(SOURCES) $(BINARY) $(BINARY): $(OBJECTS) # Link the object files, or archive into a static library ifeq "$(LIBRARY)" "static" ar rcs $(BINARY) $(OBJECTS) else $(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@ endif .c.o: $(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@ distclean: clean rm -f $(BINARY) clean: rm -f $(OBJECTS)
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.