Here are some techniques which should help with it:
All the OO principles apply!
When you need custom functionality for your project i.e. custom make step – do not bloat the common files with conditional logic. Extract common stuff to macrodefs and create separate files and/or targets for custom functionality in local project directory. Basically all the OO principles apply!
Break it down and modularize
You wouldn’t like to have just one big class in your project – do the same with ant script, break it down and modularize
Stop writing generic ant targets parametrized by global properties
Replace them with macrodefs. See:
http://ant.apache.org/manual/CoreTasks/macrodef.html
Stop using global properties
Don’t use them, unless they are really global i.e. project.name, project.version. In general they are evil as global variables and singletons are. See:
http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx
http://www.cs.usfca.edu/~wolber/courses/110/lectures/globals.htm
Use convention over configuration design paradigm.
What does it mean? Basically this:
Instead of writing (unneccessary abstraction and complexity):
<property name="project.dir" value="${basedir}"/>
<property name="test.result.dir" value="${project.dir}/build/testresult"/>
<javadoc dest="${test.result.dir}>
...
We would write:
<javadoc dest="build/testresult">
...
Simpler and more readable!
See more here:
http://en.wikipedia.org/wiki/Convention_over_Configuration
Use maven-like project directory structure
This supports convention over configuration approach and simplifies your build scripts.
project
- src
+- main
+- java
+- config
+- scripts
+- ...
+- test
+- java
+- config
+- ...
- lib
+- compile
+- runtime
+- spring-2.0.jar
+- jakarta-commons
+- commons-io.jar
+- commons-???.jar
+- ...
+- test
- ant (contains common ant tasks - it should be symbolic link as this scripts should be shared)
+- ant-common.xml
+- ant-test.xml
+- ...
- target ( temporary directory, only RW area of the project, equivalent to build)
- modules (if the code contains modules build separately like c++)
+- SomeNativeLib
+- src
+- lib
+- ...
+- OtherJavaModule
+- src
+- lib
+- ...
- build.xml
Enjoy!
