I'm attempting to optimize our build procedure for our applications we have here. I'd like to skip the compilation of our backend .dll file should the file timestamp not have change using Netbeans Ant scripts.
I've been using Incremental and fast build using Ant and Advanced Free-form project configuration as a reference point but it seems to require 2 build targets to create the .timestamp comparison in the first link.
Is there a way to circumvent the need for 2 targets and check the timestamp of the .dll file instead? or do I simply need to add another tag inside of my call to make the comparison, or is what I'm trying to do not feasible?
Any help would be greatly appreciated or if better methods of doing this are known I am open to listening to it.
We use Netbeans to compile our projects, and uses Ant by default. I've included a snippit of my build.xml Ant script so far.
Thanks in advance!
<target name="init-skip-dll" description="initializes the skip property for the Ada dll">
<uptodate srcfile="create-ada-dll.timestamp" targetfile="ada-dll.timestamp" property="ada-dll.skip" value="true" />
</target>
<target name="-build-dll" description="builds the Ada dll if needed" depends="init-skip-dll">
<exec executable="gprbuild.exe">
<arg value="-P"/>
<arg file="..\DLL\ifccs_dll.gpr"/>
</exec>
<touch file="create-ada-dll.timestamp"/>
</target>
I don’t use Ant, but the same problem exists with Make; the Ada dependency rules are complex, and best handled by unconditionally letting gprbuild do whatever it needs to to bring the DLL up-to-date. Gprbuild will do nothing besides checking dependencies if the DLL is actually up-to-date.
In Make, this involves a phony target: e.g. for a real target testbed,
testbed: force
gprbuild -p -P testbed
.PHONY: force
or for an already-phony target
all:
gprbuild -p -P build_runtime.gpr
.PHONY: all
By the way, note the -p, which says to create needed directories, e.g. an object directory.
I am adding more than 20 files to a fileset with various includes and excludes file. This takes a bit so the dependent task on Ant fileset is skipped by Ant. It wont run the dependent operation at all. This is inefficient. Does anyone know a better way to make the fileset to add files and then perform dependent instead of skipping it?
A way to do that is to use sleep https://ant.apache.org/manual/Tasks/sleep.html. I cannot use waitfor.
Example:
<fileset id="scr" dir="dir1/*" casesensitive="yes"
includes="bin/*, lib/* excludes="dir1/*.py />
<foreach param="file" in="scr">
<echo message="${file}"/>
</foreach>
</fileset>
The above example will skip printing the file name completely since Ant is still adding files to fileset.
The foreach task is not part of ANT, it is a 3rd party extension and I'm not entirely certain it's designed to work the way you think.
Instead could I suggest you print your fileset contents as follows:
<apply executable="echo">
<fileset dir="dir1/*" casesensitive="yes" includes="bin/*, lib/* excludes="dir1/*.py />
</apply>
Or like this if you want to use a fileset reference:
<fileset id="scr" dir="dir1/*" casesensitive="yes" includes="bin/*, lib/* excludes="dir1/*.py />
<apply executable="echo">
<fileset refid="scr"/>
</apply>
Note:
Ant is not a programming language so looping is not fun. If you need complex logic I highly recommend embedding a scripting language. I don't recommend ant-contrib
I'm looking for information on how to perform Acceleo source generation with an Ant script. I've done some Googleing, but I haven't really found any straightforward way to do that. I'm looking first to do it in Eclipse, but a headless (is that the right word?) script would also be nice for semi-automatic builds.
Can anyone offer any help? Or are my expectations of what Acceleo can do unreasonable?
I believe all you need to do is to use a ant task to call your generation class.
The generation class is the one generated along your mtl file that contains an "#main" annotation.
Beware though, the generation will run in standalone mode, so don't use services that rely on eclipse API!
The ant task should look like this:
<java classname="your.generation.class.GenerateJava"
classpathref="your.classpath.defined.in.ant">
<arg value="your/input/model/example.uml"/>
<arg value="your/target/folder" />
</java>
Hope this will help...
Admitted, this doesn't sound like a best practice altogether, but let me explain. During the build, we need to paste the build number and the system version into a class whose sole purpose is to contain these values and make them accessible.
Our first idea was to use system properties, but due to the volatility of the deployment environment (an other way of saying "the sysadmins are doing weird unholy creepy things") we would like to have them hard-coded.
Essentially I see 4 possibilities to achieve it in ant :
use <replace> on a token in the class
The problem with this approach is that the file is changed, so you have to replace the token back after compilation with a <replaceregexp>...sooo ugly, I don't want to touch source code with regex. Plus temporal dependencies.
copy the file, make replace on the copy, compile copy, delete copy
One one has to mind the sequence - the original class has to be compiled first in order to be overwritten by the copy. Temporal dependencies are ugly too.
copy the file, replace the token on the original, compile, replace the stained original with the copy
Same temporal dependency issue unless embedded in the compile target. Which is ugly too, because all our build files use the same imported compile target.
create the file from scratch in the build script / store the file outside the source path
Is an improvement over the first three as there are no temporal dependencies, but the compiler/IDE is very unhappy as it is oblivious of the class. The red markers are disturbingly ugly.
What are your thoughts on the alternatives?
Are there any best practices for this?
I sure hope I have missed a perfectly sane approach.
Thank you
EDIT
We ended up using the manifest to store the build number and system version in the Implementation-Version attribute, unsing MyClass.class.getPackage().getImplementationVersion(). I have found this solution was one of the answers to this thread, which was posted in the comment by andersoj
I think a simpler approach would be to have your Version.java class read from a simple .properties file included in the JAR, and just generate this .properties file at build-time in the Ant build. For example just generate:
build.number = 142
build.timestamp = 5/12/2011 12:31
The built-in <buildnumber> task in Ant does half of this already (see the second example).
#2 is generally the way I've seen it done, except that your not-ready-to-compile sources should be in a separate place from you ready-to-compile sources. This avoids the temporal issues you talk about as it should only be compiled once.
This is a common pattern that shows up all the time in software build processes.
The pattern being:
Generate source from some resource and then compile it.
This applies to many things from filtering sources before compilation to generating interface stubs for RMI, CORBA, Web Services, etc...
Copy the source to a designated 'generated sources' location and do the token replacement on the copies files to generate sources, then compile the generated sources to your compiled classes destination.
The order of compilation will depend on whether or not your other sources depend on the generated sources.
My solution would be to:
use on a token in the class:
<replace dir="${source.dir}" includes="**/BuildInfo.*" summary="yes">
<replacefilter token="{{BUILD}}" value="${build}" />
<replacefilter token="{{BUILDDATE}}" value="${builddate}" />
</replace>
This replacement should only take place in the build steps performed by your build system, never within a compile/debug session inside an IDE.
The build system setup should not submit changed source code back to the source repository anyway, so the problem of changed code does not exist with this approach.
In my experience it does not help when you place the build information in a property file, as administrators tend to keep property files while upgrading - replacing the property file that came out of the install. (Build information in a property file is informational to us. It gives an opportunity to check during startup if the property file is in synch with the code version.)
I remember we used the 4th approach in a little different way. You can pass release number to the ant script while creating a release.Ant script should include that in the release(config/properties file) and your class should read it from there may be using properties file or config file.
I always recommend to create some sort of directory and put all built code there. Don't touch the directories you checked out. I usually create a target directory and place all files modified and built there.
If there aren't too many *.java files (or *.cpp files), copy them to target/source' and compile there. You can use thetask with a` to modify this file one file with the build number as you copy it.
<javac srcdir="${target.dir}/source"
destdir="${target.dir}/classes"
[yadda, yadda, yadda]
</java>
This way, you're making no modification in the checked out source directory, so no one will accidentally check in the changes. Plus, you can do a clean by simply deleting the target directory.
If there are thousands, if not millions of *.java files, then you can copy the templates to target/source and then compile the source in both {$basedir}/source and target/source. That way, you're still not mucking up the checked out code and leaving a chance that someone will accidentally check in a modified version. And, you can still do a clean by simply removing target.
I was looking for a solution to the same problem, reading this link: http://ant.apache.org/manual/Tasks/propertyfile.html I was able to findout the solution.
I work with netbeans, so I just need to add this piece of code to my build.xml
<target name="-post-init">
<property name="header" value="##Generated file - do not modify!"/>
<propertyfile file="${src.dir}/version.prop" comment="${header}">
<entry key="product.build.major" type="int" value="1" />
<entry key="product.build.minor" type="int" default="0" operation="+" />
<entry key="product.build.date" type="date" value="now" />
</propertyfile>
</target>
This will increment the minor version each time yo compile the project with clean and build. So you are save to run the project any time that the minor version will stay still.
And I just need to read the file in Runtime. I hope this help.
It doesnt seem that when you combine these Fileset attribute like below:
eg:
<fileset dir="src">
<include name="gov/nasa/arc/mas/selenium/tests/*.java" />
<excludesfile name="${test.suite}.exclude" />
</fileset>
that it has the expected behavior which is to include all *.java under src but exclude all the file specified on the excludefile.
Is it possible to combine include and excludesfile or do you need to user a corresponding includesfile??
Its a shame that these things are not documented and its hard to find explanations on google.
Actually, I think the Ant Manual is pretty clear about these types of things.
What isn't clear to me is what it is that you want to do. Do you want to use external files for both your "includes" and your "excludes"? Or are you looking to have one override the other?
It is documented and should work: http://ant.apache.org/manual/Types/fileset.html
Note that in the excludesfile, "each line of this file is taken to be an exclude pattern." What does your excludesfile look like?