Build Management
Diomidis Spinellis
Department of Management Science and Technology
Athens University of Economics and Business
Athens, Greece
dds@aueb.gr
The Build Process
Typical Project Dependencies
Example: Apache Project Dependencies
Makefiles
- Tools like ant and make allow the automatic processing of dependencies
- Dependencies are specified in a special file
- Elements of a Makefile may include
- Variable definitions
- Rules for suffixes
- Dependencies
- Target build instructions
- Pseudo-targets
- Auto-generated dependencies
- Procedural specifications
Part of an Apache Makefile
OBJS= \
modules.o \
$(MODULES) \
main/libmain.a \
$(OSDIR)/libos.a \
ap/libap.a
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $<
.SUFFIXES: .def
.def.a:
emximp -o $@ $<
$(TARGET): $(EXTRA_DEPS) $(SUBTARGET)
lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o
$(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c
[...]
target_static: subdirs modules.o
$(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c
$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \
-o $(TARGET) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LIBS)
clean:
-rm -f $(TARGET) lib$(TARGET).* *.o
@for i in $(SUBDIRS); do \
echo "===> $(SDP)$$i"; \
( cd $$i && $(MAKE) $(MFLAGS_STATIC) SDP='$(SDP)' $@ ) || exit 1; \
echo "<=== $(SDP)$$i"; \
done
#Dependencies
$(OBJS): Makefile subdirs
# DO NOT REMOVE
buildmark.o: buildmark.c include/ap_config.h include/ap_mmn.h \
include/ap_config_auto.h os/unix/os.h include/ap_ctype.h \
include/hsregex.h include/httpd.h include/ap_alloc.h include/buff.h \
include/ap.h include/util_uri.h
modules.o: modules.c include/httpd.h include/ap_config.h \
include/ap_mmn.h include/ap_config_auto.h os/unix/os.h \
include/ap_ctype.h include/hsregex.h include/ap_alloc.h include/buff.h \
include/ap.h include/util_uri.h include/http_config.h
Make Problems and Solutions
- Complexity
-
- Dry run with make -n
- Debug mode: print variables
- Before lunch: make -k
- Portability
-
The Ant Approach
- Build instructions written in XML
- File typically named build . xml
- Variable definitions (named properties)
- Targets and dependencies
- By default, the target specified in the default attribute of the project tag is built
- Tasks are part of ant, typically not external programs
Some ant tasks
Examples of ant built-in tasks:
- mkdir
- copy
- cvs
- delete
- javac
- jar
Example Ant Build File
<project name="Jasper" default="deploy" basedir=".">
<!-- ===================== Initialize Property Values =================== -->
<!-- See "build.properties.sample" in the top level directory for all -->
<!-- property values you must customize for successful building!!! -->
<property file="build.properties"/>
<property file="../build.properties"/>
<property file="${user.home}/build.properties"/>
<!-- Build Defaults -->
<property name="build.compiler" value="classic"/>
<property name="copy.crimson.jar" value="../lib/crimson.jar"/>
<!-- =================== BUILD: Create Directories ====================== -->
<target name="build-prepare">
<available classname="junit.framework.TestCase" property="junit.present" />
<mkdir dir="${jasper.build}"/>
<mkdir dir="${jasper.build}/jasper"/>
<mkdir dir="${jasper.build}/lib"/>
</target>
<!-- =================== BUILD: Copy Static Files ======================= -->
<target name="build-static" depends="build-prepare">
<!-- Executable Commands -->
<copy todir="${jasper.build}/bin">
<fileset dir="src/bin" />
</copy>
<fixcrlf srcdir="${jasper.build}/bin" includes="*.sh" eol="lf"/>
<fixcrlf srcdir="${jasper.build}/bin" includes="*.bat" eol="crlf"/>
<chmod perm="+x" file="${jasper.build}/bin/jasper.sh"/>
<chmod perm="+x" file="${jasper.build}/bin/jspc.sh"/>
<!-- Common Extensions -->
<copy todir="${jasper.build}/jasper" file="${copy.crimson.jar}"/>
<copy todir="${jasper.build}/jasper" file="${copy.jaxp.jar}"/>
</target>
<!-- ================= BUILD: Compile Server Components ================= -->
<target name="build-main" depends="build-static">
<!-- Compile internal server components -->
<javac srcdir="src/share" destdir="${jasper.build}/classes"
debug="${compile.debug}" deprecation="${compile.deprecation}"
optimize="${compile.optimize}"
excludes="**/CVS/**">
<classpath refid="jasper.classpath" />
</javac>
</project>
Best Practices
- Put all the project's elements under the build system
- Minimize work through dependency analysis
- Modularize the build into several targets
- Common include files
- Explore parallel builds to reduce build times
- Provide a way to build from scratch
- Create a tinderbox build
Best Practices (Variables)
Use variables for varying elements:
- Directories
- Tool options
- Web sites
- Version strings
- OS dependencies