Build Management

Diomidis Spinellis
Department of Management Science and Technology
Athens University of Economics and Business
Athens, Greece
dds@aueb.gr

The Build Process

Diagram of the build process

Typical Project Dependencies

Typical project dependencies

Example: Apache Project Dependencies

Apache dependencies

Makefiles

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
Portability

The Ant Approach

Some ant tasks

Examples of ant built-in tasks:

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

Best Practices (Variables)

Use variables for varying elements: