Showing posts with label Makefile. Show all posts
Showing posts with label Makefile. Show all posts

Saturday, August 22, 2009

Creating a shared library on various platforms

When applications get bigger and code needs to be shared among different applications, then shared libraries sound like a great idea. To get this done, a multi platform compilation sprint race begins.

Shared libraries are libraries that are loaded by programs when they start. When a shared library is installed properly, all programs that start afterwards automatically use the new shared library. It's actually much more flexible and sophisticated than this, because ... [read more]
The library had to be compiled for Linux, Windows, Mac OS X, AIX, HP-UX, Sun OS and Solaris. Internet search engines along with compiler man pages are the best tools for the job. By looking around, I found the following links useful:

Linux:
AIX:
Mac OS X:
Sun OS, Solaris
HP-UX:
Creation of the shared lib was done for a mid-sized project. The library's build process was based on gmake for Unix and gmake and nmake on Windows. The main application's build system also needed adjustments to use the new library. This is also described in the links above.

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.

Tuesday, March 11, 2008

Report compilation total time using GNU make


When working constantly on the same application, it is very useful to have an idea of the time it takes to compile. Having this information allows you to plan your work ahead, compare machines, developing environments, etc.

I have put together this Makefile, to print the total compilation time. It requires gmake and the UNIX shell utilities date, bc, echo and printf.


Makefile


# Time expressed as the seconds of the year. More portable than seconds since
# the epoch: `date +%s'
COMPILE_START_TIME := $(shell date +\(%j\*24\*60\*60+%H\*60\*60+%M\*60+%S\))
COMPILE_CURRENT_TIME = `date +\(%j\*24\*60\*60+%H\*60\*60+%M\*60+%S\)`


# Print the time difference between Tcurrent and Tstart. This function can be
# used after any target, as shown in the form: (see example)
# $(call print_timer,$(COMPILE_CURRENT_TIME),$(COMPILE_START_TIME))

# args: Tcurrent = $(1), Tstart = $(2)
define print_timer
@CT=$(1) && \
printf "Compilation total time: %.2d:%.2d (min:sec)\n" \
`echo "($$CT - $(2))/60" | bc` \
`echo "($$CT - $(2))%60" | bc`
endef


all: target

target:
@echo "Compiling for 2 seconds ..." && sleep 2 && echo Done
$(call print_timer,$(COMPILE_CURRENT_TIME),$(COMPILE_START_TIME))


Using this Makefile and running make, produces the following output:


Compiling for 2 seconds ...
Done
Compilation total time: 00:02 (min:sec)