I am just getting started with flex and am using the SDK (not Flex Builder). I was wondering what's the best way to compile a mxml file from an ant build script.
The Flex SDK ships with a set of ant tasks. More info at:
http://livedocs.adobe.com/flex/3/html/help.html?content=anttasks_1.html
Here is an example of compiling Flex SWCs with ant:
http://www.mikechambers.com/blog/2006/05/19/example-using-ant-with-compc-to-compile-swcs/
mike chambers
I would definitely go with the ant tasks that are included with Flex, they make your build script so much cleaner. Here is a sample build script that will compile and then run your flex project
<?xml version="1.0"?>
<project name="flexapptest" default="buildAndRun" basedir=".">
<!--
make sure this jar file is in the ant lib directory
classpath="${ANT_HOME}/lib/flexTasks.jar"
-->
<taskdef resource="flexTasks.tasks" />
<property name="appname" value="flexapptest"/>
<property name="appname_main" value="Flexapptest"/>
<property name="FLEX_HOME" value="/Applications/flex_sdk_3"/>
<property name="APP_ROOT" value="."/>
<property name="swfOut" value="dist/${appname}.swf" />
<!-- point this to your local copy of the flash player -->
<property name="flash.player" location="/Applications/Adobe Flash CS3/Players/Flash Player.app" />
<target name="compile">
<mxmlc file="${APP_ROOT}/src/${appname_main}.mxml"
output="${APP_ROOT}/${swfOut}"
keep-generated-actionscript="true">
<default-size width="800" height="600" />
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${APP_ROOT}/libs" append="true">
<include name="*.swc" />
</compiler.library-path>
</mxmlc>
</target>
<target name="buildAndRun" depends="compile">
<exec executable="open">
<arg line="-a '${flash.player}'"/>
<arg line="${APP_ROOT}/${swfOut}" />
</exec>
</target>
<target name="clean">
<delete dir="${APP_ROOT}/src/generated"/>
<delete file="${APP_ROOT}/${swfOut}"/>
</target>
</project>
There is another option - it's called Project Sprouts.
This is a system built with Ruby, RubyGems and Rake that provides many of the features found in Maven and ANT, but with a much cleaner syntax and simpler build scripts.
For example, the ANT script shown above would look like this in Sprouts:
require 'rubygems'
require 'sprout'
desc 'Compile and run the SWF'
flashplayer :run => 'bin/SomeProject.swf'
mxmlc 'bin/SomeProject.swf' do |t|
t.input = 'src/SomeProject.as'
t.default_size = '800 600'
t.default_background_color = '#ffffff'
t.keep_generated_actionscript = true
t.library_path << 'libs'
end
task :default => :run
After installing Ruby and RubyGems, you would simply call this script with:
rake
To remove generated files, run:
rake clean
To see available tasks:
rake -T
Another great benefit of Sprouts, once installed, is that it provides project, class and test generators that will get any development box ready to run with a couple simple command line actions.
# Generate a project and cd into it:
sprout -n mxml SomeProject
cd SomeProject
# Compile and run the main debug SWF:
rake
# Generate a new class, test case and test suite:
script/generate class utils.MathUtil
# Compile and run the test harness:
rake test
If you're open to Maven, try the flex-compiler-mojo plugin:
http://code.google.com/p/flex-mojos/
Christiaan
Related
This should be easy, but I can't find it. I want my .html and .swf files to be named something differently than the project name. Project name is foo, I want the outputs to be bar.html and bar.swf. Thanks.
Flextras was on the right track. You can't change the output filename (even using the "-output" compiler param) if you're compiling in Flash Builder. Not sure why.
The solution that has worked for me has been to use a bit of indirection:
use mxmlc to compile to ApplicationClass.swf
command line copy ApplicationClass.swf to YourCustomSwf.swf
command line run YourCustomSwf.swf
You can do this with either a simple (platform-dependent) build script, or with Flex Ant Tasks. I highly recommend the latter; it's easy to setup, integrates well with Flash Builder, and (as a mostly platform-independent solution) will work in a multi-team multi-OS environment. Here are the above steps as ant tasks that will perform the magic for you:
<project name="sample-build" default="run-your-swf">
<property file="${basedir}/your.properties.file"/>
<target name="compile-your-app">
<mxmlc file="${SOURCE_DIR}/ApplicationFile.mxml" compiler.debug="${IS_DEBUG}" incremental="true" failonerror="true">
<load-config filename="${DEFAULT_FLEX_CONFIG}"/>
<define name="CONFIG::DEBUG" value="${IS_DEBUG}"/>
<define name="CONFIG::FLASH_AUTHORING" value="${IS_FLASH_AUTHORING}"/>
<define name="CONFIG::IS_RELEASE" value="${IS_RELEASE}"/>
</mxmlc>
</target>
<target name="rename-your-swf" depends="compile-your-app">
<copy file="${OUTPUT_DIR}/feed/FeedComponent.swf" tofile="${OUTPUT_DIR}/YourNewSexyFilename.swf"/>
</target>
<target name="run-your-swf" depends="rename-your-swf">
<exec executable="${STANDALONE_FLASH_DEBUG_PLAYER}">
<arg line="${OUTPUT_DIR}/YourNewSexyFilename.swf"/>
</exec>
</target>
</project>
you need only define all ${VARIABLES} I've listed in "your.properties.file", like so:
FLASH_PLAYER_DEBUG=/Applications/Adobe Flash CS5/Players/Debug/Flash Player Debugger.app/Contents/MacOS/Flash Player Debugger
IS_DEBUG=true
(et cetera)
And anyway - what's in a name? A program by any other name, would be as awesome... B-)
i want to use Ant task to compile flex project(with many libraries, modules)
i use -dump-config build.xml compiler option in flash builder to extract build config
after i create this Ant task(for start, i try to compile only one mxml-module) :
<project name="My App Builderrrr" basedir="." default="main">
<property name="QA_PM_DEST" value="[my project dir]\src"/>
<property name="BIN_DEBUG" value="[my project dir]\bin-debug"/>
<property name="FLEX_HOME" value="C:/Program Files/Adobe/Adobe Flash Builder 4/sdks/4.0.0"/>
<property name="APP_ROOT" value="src"/>
<property name="DEPLOY_DIR" value="c:\output"/>
<taskdef resource="flexTasks.tasks" classpath="${basedir}/libs/flexTasks.jar"/>
<target name="main">
<mxmlc file="${QA_PM_DEST}/***.mxml"
output="${DEPLOY_DIR}/***.swf">
<load-config filename="***\build.xml"/>
</mxmlc>
</target>
and after
ant -buldfile mybuildfile.xml
but it generates very small swf file that runs with errors(67kb insted of 300kb in release build and 800kb in debug)
I think you need to load the following config, too:
<property name="flex.config" value="${FLEX_HOME}/frameworks/flex-config.xml"/>
<load-config filename="${flex.config}" />
(UPDATE 2010-08-19)
I also add incremental="false" to my mxmlc call and the libraries this way:
<library-path dir="${lib.dir}" append="true">
<include name="**.swc" />
</library-path>
An the following is also missing in your file:
<source-path path-element="${src.dir}"/>
I'm looking into using Ivy to manage dependencies but wow - that thing really likes to make multiple copies of jars! It spreads like the ivy in my back yard and is just as undesirable!
Is it possible to have Ivy simply define a classpath (for a specified profile) that references the resolved dependencies so my javac can reference them directly in the ivy repository (or cache?).
I've read the reference docs buy only see the option to set up symbolic links to the repository cache. I guess this will suffice, but it seems like a waste. Also, I'm not sure that a "war" task can build the war from symbolic links... but I guess I'll find out when I give it a try.
Any better suggestions?
Here's my standard Java build file that creates an executable jar.
The objective is to manage project specific stuff via a combination of ANT properties and an ivy.xml file for the 3rd-party dependencies.
<project xmlns:ivy="antlib:org.apache.ivy.ant" name="demo" default="build">
<property name="src.dir" location="src"/>
<property name="build.dir" location="build"/>
<property name="dist.dir" location="dist"/>
<property name="dist.jar" location="${dist.dir}/${ant.project.name}.jar"/>
<property name="dist.main.class" value="HelloWorld"/>
<target name="retrieve">
<ivy:resolve/>
<ivy:cachepath pathid="build.path" conf="build"/>
<ivy:cachepath pathid="runtime.path" conf="runtime"/>
</target>
<target name="compile" depends="retrieve">
<mkdir dir="${build.dir}/classes"/>
<javac srcdir="${src.dir}" destdir="${build.dir}/classes" classpathref="build.path"/>
</target>
<target name="build" depends="compile">
<ivy:retrieve pattern="${dist.dir}/lib/[artifact].[ext]"/>
<manifestclasspath property="jar.classpath" jarfile="${dist.jar}">
<classpath>
<fileset dir="${dist.dir}/lib" includes="*.jar"/>
</classpath>
</manifestclasspath>
<jar destfile="${dist.jar}" basedir="${build.dir}/classes">
<manifest>
<attribute name="Main-Class" value="${dist.main.class}"/>
<attribute name="Class-Path" value="${jar.classpath}"/>
</manifest>
</jar>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
<delete dir="${dist.dir}"/>
</target>
</project>
As you've discovered in the Ivy docu, the cachepath Ivy task is used to manage two ANT paths. One for the build dependencies the other for the run-time dependencies of the executable jar.
The real power of Ivy is in something called configurations. I found it difficult to grasp initially until I realised it was simple a logical grouping of jars that I can define for my project. This example has two configurations:
build
runtime
Here's the ivy file demonstrating how dependencies can be associated with configurations:
<ivy-module version="2.0">
<info organisation="com.myspotontheweb" module="demo"/>
<configurations>
<conf name="build" description="Libraries needed to for compilation"/>
<conf name="runtime" extends="build" description="Libraries that need to be included with project jar" />
</configurations>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0" conf="build->default"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0" conf="runtime->default"/>
</dependencies>
</ivy-module>
In conclusion I hope this example helps in understanding Ivy. I like the way it concentrates on only one thing, the management of 3rd-party dependencies.
After battling through the badly written Ivy documentation (sigh - what is wrong with these people? - did they not attend high-school literacy classes in any language?), I see there is a post-resolve task called cachepath that will construct an ant path to the resolved dependency artifacts instead of copying files to a lib directory. This might be just what I'm looking for!
Just to augment #Mark's answer.
Note that cachepath result can also be directly used in build without the need to copy jars with retrieve:
<target name="build" depends="compile">
<jar destfile="${dist.ear}">
<mappedresources>
<resources refid="runtime.path"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</mappedresources>
</jar>
</target>
I'm attempting to compile a Flex application from an ANT script, inside of Eclipse (CFBuilder, based on Eclipse), and I've run into this error:
Could not load definitions from resource flexTasks.tasks. It could not be found.
I haven't been able to find anything that gives directions on where this file (flexTasks.tasks) should be copied to, if it's needed at all. Some places indicate that it should be part of the flexTasks.jar file. I've tried two different things:
Copy the jar file into the ant/plugins/lib folder (and restart my CF Builder instance)
Specify the path to the jar in the classpath attribute, as suggested by the comment on this page
Neither helps me get past this error.
Here's my build script, for reference:
<project name="Tagging" default="compile-tagging" basedir=".">
<!-- setup flex compilation capability -->
<taskdef resource="flexTasks.tasks" />
<property name="flex.src" value="./src" />
<property name="flex.bin" value="./bin"/>
<target name="compile-tagging">
<mxmlc
file="${flex.src}/main.mxml"
output="${flex.bin}/main.swf"
keep-generated-actionscript="true">
<source-path path-element="${FLEX_HOME}/frameworks" />
</mxmlc>
</target>
</project>
Adam, I believe you need to tell taskdef where to look for the file. try keeping flextasks.jar in the same directory as your ant file (for now... you can move it later after you get it working).
then, you can do something like this:
<taskdef name="mxmlc" classname="WhateverTheTaskIsNamed" classpath="flexTAsks.jar" />
While not ideal, this code is working for me at the moment:
<project name="IOLTagging" default="go" basedir=".">
<!-- setup flex compilation capability -->
<property name="FLEX_HOME" value="C:/program files (x86)/Adobe/Adobe Flash Builder Beta 2/sdks/3.4.1/" />
<taskdef name="mxmlc" classname="flex.ant.MxmlcTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
<taskdef name="html-wrapper" classname="flex.ant.HtmlWrapperTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
<property name="flex.src" value="./src" />
<property name="flex.bin" value="./bin"/>
<property name="swf.name" value="main" />
<target name="go" depends="compile-flex" />
<target name="compile-flex">
<mxmlc
file="${flex.src}/main.mxml"
output="${flex.bin}/${swf.name}.swf"
debug="false"
keep-generated-actionscript="false">
<source-path path-element="${FLEX_HOME}/frameworks" />
<compiler.library-path dir="${basedir}/libs" append="true">
<include name="*.swc" />
</compiler.library-path>
</mxmlc>
</target>
</project>
I had the same problem, and the reason was in lack of permissions to acces $FLEX_HOME/ant.
You can also put the flexTasks.jar in ~/.ant/lib directory
If you run ant -diagnostics you should see the jar in USER_HOME/.ant/lib jar listing
I think you should have solved this problem. just trying flexmonkey today and also got the same problem.
"Could not load definitions from resource flexTasks.tasks. It could not be found."
solution is to make sure the flexTasks.jar is included in the dir lib of your project workplace.
when I copied flexTasks.jar from flashbuild folder \ant\lib and built it again. the problem is fixed.
How do I compile an ASP.Net MVC project using MSBuild? We use a Continuous Integration server to compile and deploy our applications. To keep things simple I created an MVC 1.0 project in VS2008. I immediately created an MSBuild script file to compile it. I did not change any code in the project. The MSBuild script contained the following target.
<AspNetCompiler
VirtualPath="/"
PhysicalPath="C:\Development\mvc1\"
TargetPath="c:\publish\xxx"
Force="true"
Debug="false"
Updateable="true"
The MVC project sln file is contained in the c:\development\mvc1\ directory. I am running XP/Pro.
I am receiving an error ASPCONFIG: it is an error to use a section registered as allowDefintion='MachineToApplication' beyond application level.. I removed the authenication mode, membership provider, etc. from the web config file until I finally saw a different error message. I am now receiving an error message saying that the file '/views/shared/site.master' does not exist.
What is going on? Thanks in advance for your help!
Am I using the wrong MSBuild command?
If you compile your sln-file (msbuild mysolution.sln) or
<MSBuild Projects="msbuild mysolution.sln" Targets="Rebuild" ContinueOnError="false"
StopOnFirstFailure="false" /><!-- -d -errorstack -->
and the sln-file has the ASP.NET MVC-project .csproj-file then the .csproj-file does have everything you need. Open the .csproj with notepad and look for:
1) This should be true:
<MvcBuildViews>false</MvcBuildViews>
2) Target Name="AfterBuildCompiler":
<Target Name="AfterBuildCompiler" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="SomeVirtualDir" PhysicalPath="C:\Development\mvc1\" TargetPath="c:\publish\xxx\" />
</Target>
I didn't do anything else and it worked. I actually made my config so that only release build deploy the application (by moving MvcBuildViews-property under PropertyGroups. Then I can use the same .csproj in the development (debug) and deployment (release).
This build script compiles an asp.net MVC 3 application. Since the entire internet appears to have forgotten the concept of "Build Script" this one does not require you to have Visual Studio installed on the target Machine or to "lol, you just have to edit your csproj file to get msbuild!!"
Moving on.
Make sure you have .NET 4 and MVC3 installed. By the way, my build scripts only work with msbuild 4, so make sure you're using the proper one.
The general process is as follows (thanks to many hints and answers I got here!)
1) Build the dependencies (you DLL's)
2) Build the DLL for your web application.
3) Call the asp.net compiler task.
4) Check the scripts for additional comments.
Note that this is called from an outside script that compiles other DLL's (Business, data access, etc.)
<Project ToolsVersion="4.0" DefaultTargets="build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDir>..\..\dist</BuildDir>
<Optimize>true</Optimize>
</PropertyGroup>
<ItemGroup >
<Reference Include="System.dll" />
<Reference Include="System.Core.dll" />
<Reference Include="System.Web.Abstractions.dll" />
<!-- add the remaining DLL's required. Check your References folder inside VS2010 and add the relevant entries here. It's a lot of references. I ommited them to make the post more compact.
For reasons that are beyond me, I only managed to get some DLL's referenced by full path. Go figure... -->
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.Helpers\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.Helpers.dll" />
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll" />
<Reference Include="C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages\v4.0_1.0.0.0__31bf3856ad364e35\System.Web.WebPages.dll" />
<!-- The "main build script" compiles the other DLL's from the project and places them on the BuildDir folder. Just reference it here-->
<Reference Include="$(BuildDir)\*.dll"></Reference>
</ItemGroup>
<!-- Build a DLL for the code file inside your web project (controllers, models, the lot...) place it together with the other DLL's
WARNING: Simple build command. Resource files are not included in this.
-->
<Target Name="BuildWebDll">
<ItemGroup>
<CodeFiles Include=".\**\*.cs" />
</ItemGroup>
<CSC Sources="#(CodeFiles)" TargetType="Library" References="#(Reference)" OutputAssembly="$(BuildDir)\cth.web.dll" >
</CSC>
</Target>
<!-- For reasons also unkown, but covered in a number os posts in this forum, the asp.net compiler requires the necessary DLL's to be placed on the BIN/ folder of your web project. That's why we're copying every DLL we need to said folder. For debugging, check the Bin folder on Visual Studio after you compile the project. You need to replicate that in your BIN/
-->
<Target Name="CopyDLLs">
<ItemGroup>
<DllFiles Include="$(BuildDir)/*.dll"/>
</ItemGroup>
<Copy SourceFiles="#(DllFiles)" DestinationFolder="Bin\"></Copy>
</Target>
<Target Name="build">
<CallTarget Targets="BuildWebDll"></CallTarget>
<CallTarget Targets="CopyDLLs"></CallTarget>
<!-- Call this from the webproject directory. PhysicalPath references ".". TargetPath can be everything you want -->
<AspNetCompiler Updateable="true" VirtualPath="/CTH.Web" PhysicalPath="./" TargetPath="$(BuildDir)/CTH.Web" Force="true" Debug="false" />
</Target>
Remember that you have to include resource files, do any web.config replacements, etc. I really hope this helps.
The easiest way I found was to add a WebDeployment project to your solution.
http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=0aa30ae8-c73b-4bdd-bb1b-fe697256c459&displaylang=en
You set the properties for the build in the WebDeployment project (like precompile ) . The Buildserver builds the wdprj.
In my environment I have to start by building the web first. After that I can start the wdprj.
Here is my nant - script. It should be easy to write the same in msbuild. It actually runs in TeamCity.
xml version="1.0"?>
<project name="GreatProjectWeb"
default="build" basedir="."
xmlns="http://nant.sf.net/release/0.85/nant.xsd">
<description>Build Script</description>
<!-- builds only the csproj, not the entire solution-->
<target name="build" description="Compile the project using Debug configuration for more verbose error descriptions">
<echo message="Building..."> </echo>
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" >
<arg value="GreatProjectWeb\GreatProjectWeb.csproj" />
<arg value="/t:Build" />
<arg value="/p:Configuration=Release" />
</exec>
<echo message="Building Projektfile finished. Starting WDP Project..."> </echo>
<exec program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe" >
<arg value="GreatProjectWeb_Build\GreatProjectWeb_Build.wdproj" />
<arg value="/t:Build" />
<arg value="/p:Configuration=Release" />
</exec>
<exec program="7z" >
<arg value="a" />
<arg value="GreatProjectWeb_Deploy\web_GreatProject.zip" />
<arg value="GreatProjectWeb_Deploy\*" />
</exec>
</target>
</project>
You could use NAnt which has a "msbuild" task in it that will just do it for you. NAnt is a great way to go for CI builds.
The NAnt home page
The NAnt Contrib home page
The MSBuild task reference from NAnt Contrib
...the contrib library adds some great functionality that the vanilla NAnt doesn't have. It is very simple. I've included a snippet of my .build file here so you can see how I've used it:
<property name="DeployDestination" value="\\MyTestServerName\DestinationFolder"/>
<property name="Solution.Configuration" value="Debug" overwrite="True" />
<property name="nant.settings.currentframework" value="net-3.5" />
<if test="${WebContentDestination=='Production'}">
<property name="DeployDestination" value="\\MyProductionServer\DestinationFolder"/>
</if>
...<snip>
<target name="Build">
<msbuild project="SolutionFileName.sln">
<arg value="/p:Configuration=${Solution.Configuration}" />
</msbuild>
</target>
<target name="Deploy">
<copy todir="${DeployDestination}" flatten="true" >
<fileset>All files to copy</fileset>
</copy>
</target>