I'm currently managing approximately 50 build files (and counting). IMO 2 of
the biggest limitations of Nant are related to how it launches other build
files, the child build file doesn't know what settings have been already set
by the parent build file nor it doesn't know which dependent targets have
been already executed so they're executed again.
For example: Say you're trying to execute have 3 build files from a main
file, where each of child build file have some common dependencies among
them.
main.build:
        <target name="common">
                <nant buildfile="${common.dir}\common.build"
target="${main.target}"/>
        </target>
        <target name="environment">
                <nant buildfile="${environment.dir}\environment.build"
target="${main.target}"/>
        </target>
        <target name="framework">
                <nant buildfile="${framework.dir}\framework.build"
target="${main.target}"/>
        </target>

Once you establish your dependencies inside the each of the child build
files, i.e.: environment depends on common; framework depends on common and
environment, you'll get the following build sequence in the console:
  common:
        common succeeded.
  environment:
        common:
                common succeeded.    (again!!)
        environment succeeded.  
   framework:   
                common: 
                        common succeeded. (again!!!)
                environment:
                        environment succeeded.  (again!!)
``              framework succeeded.`   

As you can see "common" was executed 3 times and "environment" 2 times. Now
try adding 40 more projects into the main build file! :), your console
output will become some cluttered that it will be really hard to read.

So the approach I took in order to have each project individually buildable
as well as coexisting with the main build file, I had to add some extra
logic on the dependent targets so they don't run when called from the main
build file. i.e. <nant unless="${master.build}"
buildfile="${common.dir}\common.build" target="${build.target}" />

BTW. If you're going to be dealing with 100+ subprojects, you might want to
consider Refactoring all your common tasks and properties (such as release,
debug, test, etc.) into a common.build file and reference it from within
each subproject, that way you only make your changes in a single location
and developers will only have to worry about adding/removing sources and
references into their assigned build files.

I can send you some sample nant files if you'd like to. 
       
Jorge
-----Original Message-----
From: Ben Lowery [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, September 10, 2002 8:12 PM
To: [EMAIL PROTECTED]
Subject: Re: [nant-dev] patch to support resolving properties from
environment vars


yay, i started conversation on this!  perfect...  code first / ask questions
later appears to be the way to go. :)

alright, so some commentary on the options presented and why i chose to go
for env vars.  this is going to be long, consider this a warning. :)

first, the options using xml config files don't suit me.  by using
environment variables that map to properties, i can easily isolate the
different command windows from each other.  one of the interesting things
about the SET command in dos is that the new variables apply to *that
instance only* and don't leak over into my other command windows.  if i were
doing config using an xml file, i don't get this benefit.  everyone has to
share the config file...  now, maybe i could just have one env var that
points to the config file, and that would make things a bit simpler.. food
for thought.

anyway, the real reason for doing this is a bit more complicated.  i'm
trying to come up with a build environment that manages many different
projects (100+).  for my first crack at this, i had a master.build that
looked like:

<project>
  <property name="build.config" value="debug"/>
  <property name="debug" value="true"/>
  <property name="build.dir" value="..."/>
  <target name="release">
    <!-- change relevant stuff -->
  <target name="foo">
    <nant buildfile="foo/foo.build"/>
  </target>
  <target name="bar" depends="foo">
    <nant buildfile="bar/bar.build"/>
  </target>
  <target name="zapata" depends="bar">
    <nant buildfile="zapata/zapata.build"/>
  </target>
</project>

this manages the dependencies between all the projects.  if i do a
  nant zapata
everything gets built and i'm happy.  if i want to build everything in
release mode, i just do a
  nant release zapata
the actual instructions for each subproject build are contained in the
linked build file, and maintaining that guy is up to the developers on that
subproject.

why not just put everything in one build file?  the primary reason is that
the company with the number of projects i'm dealing with, i think a giant
build file with everything in it will just get too unweildy.  so, i'm trying
to find a good way to break down the projects...

anyway, with the scheme above, everything seems ok.  i can build everything,
or i can build a subset, depending on what i target.  the problem is, real
sub-projects have more than one build target...  for instance, i may have
build, test & package inside zapata.  how do i run those targets?  so far, i
don't have a way to pass down the desired target from master.

my first (and current) solution is to allow people to build each subproject
directly.
  nant -buildfile foo.build
this allows the developer to do whatever they want with build targets.  to
facilitate building the world, the master.build will call the default build
target on each subproject.  this default target should do everything for the
subproject (build / test / package).

now the problem is, how to i make the subproject autonomous?  before, it's
inheriting all the interesting values (debug or release, where to put
output) from the master.build.  the thought of putting code into every
subproject build file that did a <if propertyexists="${build.dir}"/> task to
check for parenting seems really nasty.  so instead, i decided that you
would *never* define the basic properties in your subproject build file,
instead they get pulled from the environment.  then you just muck with the
environment to get the build you want.  otoh, master.build can define these
properties and pass them on to the other projects through the nant task.  i
have this notion working now.

does this make sense?

another idea that has popped into my head is capturing the target(s) that
were passed to master.build:
  nant -buildfile:master.build release build
master.build would then pass those onto the subprojects.  so it would look
something like:

<project>
<property name="build.config" value="debug"/>
<property name="debug" value="true"/>
<property name="build.dir" value="..."/>
<target name="release">
  <!-- change relevant stuff -->
<target name="foo">
  <nant buildfile="foo/foo.build" target="{nant.targets}"/>
</target>
<target name="bar" depends="foo">
  <nant buildfile="bar/bar.build" target="{nant.targets}"/>
</target>
<target name="zapata" depends="bar">
  <nant buildfile="zapata/zapata.build" target="{nant.targets}"/>
</target>
</project>

this just occured to me, so i havn't tried it out yet...  this doesn't
address the notion of needing the subprojects to be individually buildable,
but if i had this ability, maybe i wouldn't need the ability to build
subprojects.

anyway, this is my dilemma.  :)

is anyone else trying to manage a large number of projects using nant?  how
are others doing it?

--b





-------------------------------------------------------
In remembrance
www.osdn.com/911/
_______________________________________________
Nant-developers mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nant-developers


-------------------------------------------------------
In remembrance
www.osdn.com/911/
_______________________________________________
Nant-developers mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/nant-developers

Reply via email to