Search code examples
androidantcompilationmultiple-projectssubant

Building multiple android projects via a master ANT build file


I have a master build file that I use to build a series of Android projects. Each of these Android projects reference the same Android library project (I'll call it CoreLibrary). The following is my subant task.

 <target name="build" description="Builds (only) all applications">
    <subant>
        <target name="debug" />
        <fileset refid="all-applications" />
    </subant>
</target>

Question: Is there something I can do to prevent CoreLibrary from being re-built for each Android project in the all-applications fileset of my subant task? This would significantly speed up my build-time so I am hoping there is something I can do.


Solution

  • Actually, I just recently figured out a way to solve this problem. The basic idea is that, my ANT file finds all library projects, builds them first, and then builds the remainder of my projects with the nodeps target. This effectively prevents the situation where CoreLibrary is constantly re-compiled.

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="MasterBuild">
    
     <!-- A property for the name of the file that contains 'android.library=true' (which is how we find library projects) -->
    <property name="library.setting.file.name" value="project.properties" />
    
    <filelist id="normal-projects" dir=".">
        <!-- You want to add your own projects here -->
        <file name="./MyProject/build.xml" />
        <file name="./MyProject2/build.xml" />
        <file name="./MyProject3/build.xml" />
    </filelist>
    
    <fileset id="all-libraries-properties" dir=".">
        <include name="*/${library.setting.file.name}" />
        <contains casesensitive="true" text="android.library=true" />
    </fileset>
    
    <pathconvert property="all-libraries" refid="all-libraries-properties">
        <globmapper from="*${library.setting.file.name}" to="*build.xml" />
    </pathconvert>    
    
    <target name="-set-debug-mode">
        <property name="build.target" value="debug" />
        <property name="install.target" value="installd" />
    </target>
    
    <target name="-set-release-mode">
        <property name="build.target" value="release" />
        <property name="install.target" value="installr" />
    </target>
    
    <target name="-build-dependencies" unless="built.dependencies">
        <property name="built.dependencies" value="true" />
        <subant buildpath="${all-libraries}" target="${build.target}" inheritall="false" />
    </target>
    
    <target name="-build-normal-projects" depends="-build-dependencies">
        <subant inheritall="false">
            <target name="nodeps" />
            <target name="${build.target}" />
            <resources refid="normal-projects" />
        </subant>
    </target>
    
    <target name="-install-normal-projects">
        <subant inheritall="false">
            <target name="${install.target}" />
            <resources refid="normal-projects" />
        </subant>
    </target>
    
    <target name="debug" depends="-set-debug-mode, -build-normal-projects" description="Builds (only) a debug-key signed application" />
    <target name="release" depends="-set-release-mode, -build-normal-projects" description="Builds (only) a release-key signed application" />
    
    <target name="installd" depends="-set-debug-mode, -install-normal-projects" description="Installs (only) a debug-key signed application" />
    <target name="installr" depends="-set-release-mode, -install-normal-projects" description="Installs (only) a release-key signed application" />
    
    </project>
    

    Note This solution could be improved if I wrote a task that actually found the library dependency order so I could build libraries with the nodeps target. Additionally, there is probably a way to automatically detect "normal projects", but I haven't needed that yet. Finally, I unrolled quite a few things from my normal ANT file to bring this here so hopefully I didn't miss anything. The concept, however, is present.