I’ve been reading Test Driven Development for Embedded C which recommends CppUTest as a unit test framework. The book describes how to write test cases for many different situations but it lacks information on how to setup and configure CppUTest. I was surprised since the author is a major contributing developer for CppUTest. This post describes how I got started.
My development environment is Windows XP Professional and Windows 7 Professional and this causes a lot of headaches trying to compile CppUTest. GCC is my compiler of choice and I use Microsoft Visual Studio Express as a debugger since I detest Eclipse + GDB. I used the MinGW distribution from Stephan Lavavej which is nice and lightweight. The problem is the that CppUTest build environment assumes a POSIX environment with just isn’t true with my setup and didn’t want to install Cygwin which I hate.
The first thing I did was to go to the CppUTest website to review the documentation to see how to install it. I didn’t find anything. Ditto for the book. Fortunately I found a readme file in the zip file download. This is the first program I’ve downloaded for a very long time that didn’t tell you how to get started using the tool. Or even what to expect. I almost gave up right away but decided to keep going. The instructions said to type “make” in the top level source directory directory for GCC. I did that and got errors right away. I hate editing Makefiles at the best of times, but the ones for CppUTest are the craziest and most complicated ones I’ve ever seen. I think they use every obscure Makefile feature possible.
The first step to figure out what was going on was to echo all of the make commands to the console since the Makefile silences them. That’s an easy 1 line edit in the Makefile and it’s even commented:
#Set this to @ to keep the makefile quiet<br> SILENCE = @
The make commands are echoed to the console once you comment out the SILENCE line like this:
#Set this to @ to keep the makefile quiet<br> #SILENCE = @
Once I did that it was obvious that the problem was with the mkdir command in Windows. It is not compatible with the POSIX version with the same name so some editing was required. The 2 key differences are that the Windows version will return an error if the directory already exists and it also expects backslashes instead of slashes for the path. Turns out that the MakefileWorker.mk file in the build subdirectory was issuing the offending commands. Every time a file was compiled or linked it would also try and create the directory at the same time which makes Windows mkdir unhappy. I spent a lot of time trying different methods, but the only one that worked was to tell make to ignore the error returned from mkdir if the directory already existed. So basically this
$(SILENCE)mkdir -p $(dir $@)
becomes this:
-$(SILENCE)mkdir $(subst /,\,$(dir $@))
The dash in the beginning of the line tells make to ignore any returned errors from mkdir. The -p option goes away because the Windows version doesn’t support it. Finally, the subst function call changes all of the slashed in the path to backslashes. Once all of the instances of mkdir are changed CppUTest will compile.
Once CppUTest is compiled the Makefile tries to execute the self tests, except that the tests won’t run because the Makefile also tries to delete all of the object files using rm which Windows doesn’t support. The easiest fix is to edit the all rule as follows:
all: $(TEST_TARGET) ./$(TEST_TARGET) $(CPPUTEST_EXE_FLAGS)
This will let the tests run and everything will finally be built and tested. The next step is to setup a project, but that’s a topic for another day.