Thursday, May 01, 2008

Remove obsolete objects form a library archive using GNU make


The build system of an application I work on, stores each compilation object in a library archive (using GNU ar). With every project build, the contents of this archive are updated with new objects from the compilation. This is achieved by running ar -cru library.a $(OBJECTS)

Moreover, the archive needs also to be updated when files (and thus their objects) are removed from the project. The most convenient phase for this to happen is during the build.

The required archive updating, can be performed with the following part in the Makefile (consider this a template, since it cannot be used as is)

Makefile


obj: $(OBJECTS)
ifneq (,$(filter-out $(OBJECTS),$(wildcard $(OBJECT_DIR)*.o)))
$(warning "Deleting unused object files...")
ifeq (ar,$(firstword $(AR)))
-$(firstword $(AR)) -d $(LIBRARY) $(filter-out $(OBJECTS),$(wildcard $(OBJECT_DIR).o))
else
$(warning $(LIBRARY) may contain obsolete objects: $(filter-out $(OBJECTS),$(wildcard $(OBJECT_DIR)*.o)))
endif
rm -f $(filter-out $(OBJECTS),$(wildcard $(OBJECT_DIR)*.o))
rm -f $(filter-out $(OBJECTS:.o=.d),$(wildcard $(OBJECT_DIR)*.d))
endif


The above assumes that you are using GNU make and GNU ar. Also, dependencies are stored per source file, along with the objects and removed with them.

With the auto removal of objects, manual update or full rebuild of the archive is unnecessary. Also, headaches and hard to track errors, coming from doubly defined functions in the archive and obsolete code being used, are avoided.