Wednesday, September 11, 2019

Yet Another Make Tutorial - VII

Yet another chapter in the Yet Another Make Tutorial.

III, and IIIIV, 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: build_unitest build_target

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.

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.

//! \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)
{
  std::cout << "Unit test success" << std::endl;

  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.