[ I, II, and III, IV, V, VI. Make files are found here.]
The previous post showed the framework for creating a production program and its unit tests using a library.
The unit test and production program were both built together. The production program could be dependent on the unit test. If the unit test doesn't run, then why build the production program.
Let's run the unit test after its built.
# makefile18
LIB := lib
UNITEST := unitest
TARGET := target
MYLIBRARY := mylibrary
.PHONY: all clean
all:
clean:
$(MAKE) -C $(TARGET) -f makefile18target clean
$(MAKE) -C $(UNITEST) -f makefile18unitest clean
$(MAKE) -C $(LIB) -f makefile18lib clean LIBRARY=$(MYLIBRARY)
build_target: build_unitest
$(MAKE) -C $(TARGET) -f makefile18target LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB) LIB_INC_DIR=../lib/inc
build_unitest: build_lib
$(MAKE) -C $(UNITEST) -f makefile18unitest LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB) LIB_INC_DIR=../lib/inc
chmod +755 ./$(UNITEST)/target/unittest
./$(UNITEST)/target/unittest
build_lib:
$(MAKE) -C $(LIB) -f makefile18lib LIBRARY=$(MYLIBRARY)
Updates are 1) build_unittest is now a dependency of build_target, 2) the unit test is run after building, 3) to clean the library, the name of the library must be supplied, and 4) must supply path to lib include files for unit test and target.
makefile15a is used as the base for the makefiles makefile18lib, makefile18unitest, make18target.
makefile15a is used as the base for the makefiles makefile18lib, makefile18unitest, make18target.
Library Makefile
Add LIB_NAME to make file
# LIBRARY is a passed variable
LIB_NAME := lib$(LIBRARY).a
Change command for $(TARGET) to make libary
$(TARGET) : $(OBJS_C) $(OBJS_CXX)
ar rvf $(TARGET_DIR)/$(LIB_NAME) $(OBJS_C) $(OBJS_CXX)
Unitest Makefile
Add LIB_NAME to make file.
# Input variables: LIBRARY, LIBDIR, LIB_INC_DIR
LIB_NAME := lib$(LIBRARY).a
Change dependency and command for $(TARGET) to make unit test.
$(TARGET): $(OBJS_C) $(OBJS_CXX) $(LIBDIR)/$(LIB_NAME)
$(CXX) $^ -o $@ -L$(LIBDIR) -l$(LIBRARY)
Target Makefile
Same changes are make to target makefile as was make to unit test makefile.Unit Test Main
Add a source file, unittest.cpp, to the unit test src directory to build a unit test program and test that the unit test program runs and fails.
If a command make runs returns an error code >0, then make stops.
If a command make runs returns an error code >0, then make stops.
//! \file unittest.cpp
#include <iostream>
int main(void)
{
std::cout << "Unit test failed" << std::endl;
return 1;
}
Now there is a 'main()' to build a unit test.
The unit test reports failure.
Update the unit test to succeed.
//! \file unittest.cpp
#include <iostream>
int main(void)
{
return 0;
}
With the unit test passing, the target program is built.
This ends the tutorial. You should now have a good framework to build a program and unit test using a set of makefiles that do not need to be modified as the project progresses.
Fin.