A (C++) makefile using a maven like directory structure

Posted: February 11, 2012 in programming
Tags: , , ,

When you’re used to Java, you build your software using the comforting build-tools. Popular examples are Ant and Maven. Personally I love Maven.

When you’re writing an application in C++ it seems like a big step backwards build-tools wise. If you’re an Ant God you might feel a bit more comfortable with using Make. However, writing makefiles (the ‘equivalent’ of the Ant’s build.xml) are a more tough.

Since I am used to Maven, there are some tasks I want to perform, like:

- clean
- compile
- compile tests
- package

To start with. I have set up a little makefile that does this for me and for those who just want to get started, share the makefile with you. But what will you get? It won’t be exactly like Maven

It took a little while, and I bet it is far from perfect for real C++ developers who eat makefiles for breakfast. But I am happy with it for now.

The directory structure that needs to be in your project is like this (cpp vs mavenized):

CPP 					Mavenized
------------------------------------------
src\main 				src\main\java
src\main\resources 		src\main\resources
src\include\			none
src\test\ 				src\test\java
bin\main 				target\
bin\test 				target\test-classes
lib\ 					src\main\resources

When you run ‘make’ you will be doing all tasks. Meaning you will clean, compile everything (your ‘normal’ code and test code) and then copy any libraries, resources and binaries.

Caveats:
- I am compiling without using the -c flag, this simplifies a lot of stuff for me (it works). But, the larger your project the longer it will take to compile, since it will compile everything all the time. So even though you change one file, everything will be recompiled.
- You need to specify sub-dirs when you use them, when there are no files in those dirs the compilation fails (atleast using G++)

The makefile:

CC=g++
CFLAGS=-Wall

# MAIN properties
SRC=src/main
INCLUDE=src/include
BIN=bin/main
RESOURCES=src/main/resources
LIB=lib

# TEST properties
SRC_TEST=src/test
BIN_TEST=bin/test
RESOURCES_TEST=src/test/resources

all: clean compile compile-test copy-resources copy-libraries

bin: clean compile copy-resources copy-libraries

copy-libraries:
	cp $(LIB)/*.* $(BIN)

copy-resources:
	cp -R $(RESOURCES)/ $(BIN)

compile: clean-main prepare-main
	$(CC) $(SRC)/*.cpp $(SRC)/domain/*.cpp -I$(INCLUDE) -I$(INCLUDE)/domain -o $(BIN)/d2tm -lmingw32 -lSDLmain -lSDL $(CFLAGS)

compile-test: clean-test prepare-test
	$(CC) $(SRC_TEST)/*.cpp -I$(INCLUDE) -o $(BIN_TEST)/tests $(CFLAGS)

clean:	clean-main	clean-test

clean-main:
	rm -rf bin\main

prepare-main:
	mkdir bin\main

clean-test:
	rm -rf bin\test

prepare-test:
	mkdir bin\test

Want to see how it is used in a project? Look here.

About these ads
Comments
  1. [...] In my previous post I have described a way to compile your project with a Maven style like project structure. Using that as basis I am busy rewriting my project Dune II – The Maker. This time I am using SDL. [...]

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 )

Connecting to %s