9

I am having trouble creating an Ant build script for our production apps.

I have been reading a lot about Ant, and bb-ant-tools. I have followed many stackoverflow questions on Ant & BB (referenced below in comments to "link" the questions). I would like help with a script more complex than the usual "Hello World!" style apps. My current build process is run entirely in Eclipse, and done manually.

For this question, I would like to ask how to use Ant to build a project that uses 2 (or more) different library projects (which also need to be built), without using Eclipse at all?

I have Ant, bb-ant-tools installed. I have built & deployed on device a basic Hello World, using these tools following basic examples. I have created a build script, and some property files; but when I run the scripts, the end product does not run on the phone (phone UI freezes on the launch screen).


I have 3 build scripts, one for each library, and one for the main app. These are identical, except for the project name (and could be combined into one common imported script at some point). Each of the 3 java projects has an Ant properties file related to it. I also use 3 common properties files for defining constants, storing info on the JDE & the code signing password.

  • common.properties:

    jde.home=C:/development/tools/bb-jde/jde4.5/components
    sigtool.jde = ${jde.home} 
    sigtool.password = xxx_pass_xxx
    
  • project.properties (for SOAP library):

    output=MySOAP
    type=midlet
    
  • project.properties (for internal SDK library):

    output=MySDK
    type=midlet
    

Update 1: I have updated the library property files since initial post. Previously I set type=library (based on RIM documentation). Based on my research outlined in this post (BlackBerry - use own JAR file in own project), I tried changing to type=midlet. This gives better results (at least on my platform BB JDE 5.0).

  • project.properties (for my app):

    output=MyApp
    title=App
    type=cldc
    vendor=Richard
    version=1.0.7
    description=A nice app
    icon=icon.png
    
  • build.xml (all the same except for the name at the top, and the 2 library scripts do not have filesets declared inside import.jars):

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <project name="MyApp" default="build">
    
        <!-- BLACKBERRY ANT TOOLS -->
        <property name="bb-ant-tools.home" location="C:/development/tools/bb-ant-tools" />
        <taskdef resource="bb-ant-defs.xml" classpath="${bb-ant-tools.home}/bb-ant-tools.jar" />
    
        <!-- CONFIG FILES -->
        <property file="${common.basedir}/common.properties" />
        <property prefix="project" file="project.properties" />
    
        <!-- FOLDERS -->
        <property name="dest.dir" location="build" />
    
        <!-- this is empty in the library scripts -->
        <path id="import.jars">
            <fileset dir="../MySDK/build" includes="*.jar" />
            <fileset dir="../MySOAP/build" includes="*.jar" />
        </path>
    
        <path id="src.files">
            <fileset dir="src" includes="**/*" />
            <fileset dir="res" includes="**/*" />
        </path>
    
        <!-- TARGET ACTIONS -->
    
        <target name="build" depends="">
            <mkdir dir="${dest.dir}" />
    
            <!-- work around a bug requiring app icons to be in the output folder -->
            <copy file="${basedir}/res/icon.png" tofile="${dest.dir}/icon.png" />
    
            <rapc 
                    jdehome="${jde.home}"
                    output="${project.output}" 
                    destdir="${dest.dir}" >
    
                <import refid="import.jars" />
                <src refid="src.files" />
                <jdp file="${basedir}/project.properties" />
            </rapc>
        </target>
    
        <target name="sign" depends="build">
            <sigtool
                    codfile="${dest.dir}/${project.output}.cod" 
                    jdehome="${sigtool.jde}" 
                    password="${sigtool.password}" />
        </target>
    
        <target name="clean">
            <delete dir="${dest.dir}" />
        </target>
    
    </project>
    

Update 2: I have updated the build.xml since the initial post. Target build now copies the app icon into the build output folder (${dest.dir}) to work around a bug in bb-ant-tools / rapc.


So this is a very simple Ant script, except:

  1. I would like to know how to trigger the sub-builds off from the main app build (my answer below deals with that).
  2. The big one, is that the resulting output from this does not work.

FWIW I have found the following popular resources, and list them so that they need not be added as answers, and to help anyone in the future looking for info:

Community
  • 1
  • 1
Richard Le Mesurier
  • 27,993
  • 19
  • 127
  • 242
  • Related questions: http://stackoverflow.com/questions/6738216/ant-blackberry-build-fails http://stackoverflow.com/questions/2791635/blackberry-apps-importing-a-code-signed-jar-into-an-application-project http://stackoverflow.com/questions/7144609/how-to-make-ant-build-for-my-bbm-application-with-native-bb-jar – Richard Le Mesurier Jan 20 '12 at 13:37
  • http://stackoverflow.com/questions/7109336/fail-bb-ant-tools-build-when-jdp-referenced-file-is-missing http://stackoverflow.com/questions/6978504/ant-build-for-blackberry-when-startup-tier-is-6 http://stackoverflow.com/questions/5712590/different-cod-jad-files-created-using-blackberry-jde-and-ant http://stackoverflow.com/questions/3986739/blackberry-build-tool http://stackoverflow.com/questions/8365900/preprocessor-in-blackberry-through-bb-ant-tools – Richard Le Mesurier Jan 20 '12 at 13:39

5 Answers5

1

In order to maintain the resource structure instead of adding the 'res' folder as a source folder do the following:

  1. Create a temporary jar file of all the resources using the ANT 'jar' command:

    <jar destfile="temp/@{brand}/res.jar"
        basedir="../@{brand}/res"
        compress="false"
        filesonly="false"
        includes="**/*"/>
    
  2. Add the temporary jar as a source element inside the 'src' element of the rapc command:

    <fileset dir="temp/@{brand}" includes="res.jar"/>
    
Meanman
  • 1,363
  • 18
  • 16
1

This is what I'm using across multiple projects.

<macrodef name="compile">
    <attribute name="buildversion" />
    <attribute name="description" />
    <sequential>
        <mkdir dir="${build.dir}" />

        <rapc output="${cod.name}_bbminterface"  destdir="${build.dir}" verbose="false" quiet="true" nowarn="true">
            <src>
                <fileset dir="${bbminterface.src.dir}"/>
            </src>
            <import location="./lib/net_rim_bb_qm_platform.jar" />
            <jdp type="library" title="${app.name}_bbminterface" vendor="my vendor" version="@{buildversion}">
                <entry title="${app.name}_bbminterface" description=""/>    
            </jdp>
        </rapc>
        <rapc output="${cod.name}_bbmimpl" destdir="${build.dir}" verbose="false" quiet="true" nowarn="true">
            <src>
                <fileset dir="${bbmimpl.src.dir}"/>
            </src>
            <import location="./lib/net_rim_bb_qm_platform.jar" />
            <import location="${build.dir}/${cod.name}_bbminterface.jar" />
            <jdp type="library" title="${app.name}_bbmimpl" vendor="my vendor" version="@{buildversion}" runonstartup="true" startuptier="6">
                <entry title="${app.name}_bbmimpl" description="" runonstartup="true" startuptier="6"/> 
            </jdp>
        </rapc>

        <rapc output="${cod.name}" destdir="${build.dir}" verbose="false">

            <src>
                <fileset dir="${tmpsrc.dir}" />
            </src>
            <src>
                <fileset dir="${res.dir}" />
            </src>
            <src>

                <fileset file="${lib.dir}/paymentapi.jar" />
            </src>
            <import location="./lib/net_rim_bb_qm_platform.jar" />
            <import location="${build.dir}/${cod.name}_bbminterface.jar"/>

            <jdp type="cldc" title="${app.name}" vendor="my vendor" icon="../res/icon.png" version="@{buildversion}" description="@{description}" startuptier="7" ribbonposition="0">
                <entry title="${app.name}" icon="../res/icon.png" description="@{description}" runonstartup="true" arguments="boot" systemmodule="true" startuptier="7" ribbonposition="0" />
                <entry title="${app.name}" icon="../res/icon.png" description="@{description}" arguments="daemon" runonstartup="true" systemmodule="true" startuptier="7" ribbonposition="0" />
            </jdp>
        </rapc>
    </sequential>
</macrodef>

This is the compilation code. We're compiling a few libraries and then the application, linking the just created libraries.

Then for signing:

<target name="sign" description="Sign the cod file">
    <sigtool codfile="${build.dir}/${cod.name}_bbminterface.cod" password=""/>
    <sigtool codfile="${build.dir}/${cod.name}_bbmimpl.cod" password=""/>
    <sigtool codfile="${build.dir}/${cod.name}.cod" password="" />
</target>

And then uploading to our OTA server:

Joe
  • 73
  • 10
  • 1
    thx - the script works great on simple projects - I have a simple app with library installed & running on device. I still can't get a more complex one to build, so looking for other bugs I may have. – Richard Le Mesurier Jan 27 '12 at 11:43
  • 1
    I am using your bb ant tool and it's work fine. But can you help me about how to maintain resource directory structure in this tool For example i added all images in "res/img/" folder now when i generate .cod file it added all images in root folder i mean it did not maintain directory structure like this "res/img" – Dhiral Pandya Apr 12 '12 at 12:40
  • 1
    there are some posts around on the resources. I think that all the resources get put into the root of the JAR file, so you lose your folder structure. But I'm also stuck on that problem at the moment. – Richard Le Mesurier May 11 '12 at 05:42
1

To answer my question about triggering builds for included projects, from my main build file, the solution is to use the subant task, which is a standard Ant command.

For example, the below code (I forget where I copied it from, but its not mine, and it does work) will trigger the build.xml file in each of the folders supplied, and will run the export-all target within that build file.

    <subant target="export-all">
        <dirset dir="${basedir}/.." includes="${project.deps}" />
        <property name="export.dir" location="build/lib" />
    </subant>

It requires a property called project.deps to be declared as a comma-separated list of folders. The dirset is defined by looking back one folder from the main build.xml, and looking for each of the subfolders in project.deps.

Ant will then find the build.xml file in each of these folders, and run it, looking for the export-all target.

Within each of the new export-all subtasks, the property export.dir will have been set, which is how you can pass info from the main build.xml into the subtasks.

Richard Le Mesurier
  • 27,993
  • 19
  • 127
  • 242
0

I saw question about how to save resource directory structure in Dhiral's comment to Joe's answer. Some days ago I found workaround here (Blackberry Development with Ant & Eclipse) in comments to post:

yuri wrote:
I found a way 

You just need to copy the resources temporarily to the output folder, and delete them
after the build is over. The key is that the resources must be in the working folder
of the compiler.

Posted 18 Jan 2008 at 5:08 pm ¶
Community
  • 1
  • 1
Yuriy
  • 1,368
  • 1
  • 13
  • 30
0

I hope you don't forget to ship your library cods with your app cod to the end user. Because otherwise app won't work.

About triggering library building - I prefer build libraries only when it's necessary - code or dependency changed.

About solution for you I would just have bat file where I will trigger ant three times with different build.xml files and proper current files (because you ant scripts have relative directories). So it would be like:

cd librarydir1
ant
cd librarydir2
ant
cd appfolder
ant
Eugen Martynov
  • 18,698
  • 8
  • 53
  • 105
  • thx yes I do know to ship the library cods. Getting the final set of files together is another manual task at the moment, which is another reason I'm moving to Ant. I didn't include it in this question, because I already have the script to get that file manipulation, unzipping, updatejar etc working. – Richard Le Mesurier Jan 23 '12 at 05:36