ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Adam Murdoch" <>
Subject RE: C/C++ Compile Task - Another
Date Thu, 21 Jun 2001 00:52:32 GMT

> -----Original Message-----
> From: Mark A Russell []
> Sent: Thursday, 21 June 2001 12:38 AM
> To:
> Subject: RE: C/C++ Compile Task - Another
> <<SNIP>>
> >>Biggest difference is a single unified task vs. separate
> compile and link
> >>tasks.  The more I think about a unified task, the more I like
> it.  After
> >>all, it's the approach the compilers take.  It didn't even cross my mind
> >>that you would do this as a single step.  Too long writing crappy
> Makefiles,
> >>I guess :)
> >>
> >>The only concern I have about a unified task is that we may end
> up with a
> >>bloated interface for the task, with a whole bunch of
> attributes that have
> >>"ignored if not linking" or "required if linking, but only if not
> compiling"
> >>in their description.  But there's ways we can deal with this if it
> happens.
> >>So +1 for a single task.
> Even though mine is a single task I still do it in two steps.  Partly
> because
> I was trying to build it in such a way that it would never run
> into command
> line
> length limits.  Unfortunently this is what broke the static
> library building
> for
> the sun compiler.
> Usually when I make a static lib on the sun machine I use the
> -xar argument
> which
> insures that the templates get pulled in properly.  In my task code I was
> using ar
> and completely forgot about this.
> Yannick Menager (posted after your comments) had an interesting
> idea.  Maybe
> we do
> both.  We could have our main compile task that can both compile and link
> but
> also maybe add a seperate link task.  This would add some flexability for
> those who wanted/needed to do these tasks seperatly.

Sounds good to me.

> >>The name of the task is another issue.  I think the names I chose are
> pretty
> >>crap - I'd like something more descriptive, <cppcomp> is fine.  Maybe
> >><cppcompile> or <compilecpp> is better?
> compilecpp is fine by me, but one question that goes along with
> this.  Is it
> just
> a C++ task or is it also a C task?  If its both (really should be) then
> maybe C_CPPCompile?

Definitely should do both.

> <<SNIP>>
> >>* define/undefine.
> <<SNIP>>
> >>I'd also like to have shortcut 'define' and 'undefine'
> attributes, similar
> >>to what I have, which create an implicit defineset.
> Easy enough to add, I see no problems here.
> >>* additional compiler/linker arguments.
> >>
> >>We both use string attributes here.  Perhaps we should make
> these a bunch
> of
> >>nested elements instead, and make them CommandLine.Argument objects -
> maybe
> >>called <compilerarg> and <linkerarg>?
> I like that idea, should make the task easier to read when looking at a
> build file.
> +1 to this idea
> >>* include and library path
> >>
> >>We're the same here.  I have an additional sysincludepath,
> which is passed
> >>to the compiler, but not used in header file dependency checking.  The
> >>intention was to use this to cut down the amount of work the task has to
> do
> >>in parsing.  It's not really necessary.  (Just don't trust my parser, is
> all
> >>:)
> >>
> >>I'd like to have shortcut 'libpath', 'includepath' and 'sysincludepath'
> >>attributes as well.
> Wont these shortcuts get very very long? or are you thinking more
> along the
> lines
> of a refernce to a previously defined path?

Not necessarily.  Using an attribute or a nested path is not mutually
exclusive - you can use both in the same task.  So you can mix as
appropriate for your particular set up.

Having a libpath attribute is simply a shortcut for creating a nested
<libpath> element.  E.g.

<compilecpp libpath="somedir;anotherdir"/>

is short for:

  <libpath path="somedir;anotherdir"/>

Hmmm... seeing it written like that makes me think it's kinda pointless.  I
can live with adding  path= to my build files.  So lets drop the 'libpath',
'includepath' and 'sysincludepath' attributes.  Maybe do a similar thing
with <defineset> so that we can drop the 'define' and 'undefine' attributes
as well.

For example:

<defineset define="SOMEDEF, ANOTHERDEF" undefine="UNWANTEDDEF"/>

> >>* debug
> >>
> >>The behaviour differs slightly here.  When debug is set to false in my
> >>compile task, it switches on optimization.  It shouldn't really - I was
> >>being lazy.  We should add an 'optimize' attribute if we want to support
> >>optimization.
> The only reason I didn't define an optimize attribute originally
> is because
> I couldn't decide what level of optimization it should do.  Should it be a
> lvl
> thing like 1-5 and then each compiler adapter determines what flags that
> corresponds
> to? or just true/false where true means just the basic default
> optimization?
> >>* source file set
> >>
> >>A unified C++ task should support these cases:
> >>  - compile a set of source files, but do not link.
> >>  - link a bunch of object files and libraries, but do not compile.
> >>  - compile a set of source files, link in the resulting object
> files plus
> >>some libraries.
> >>  - compile a set of source files, link in the resulting object
> files plus
> >>some additional object files and libraries.
> Maybe this is where having a seperate link task might be useful.  We could
> still
> keep our unified task, but having that seperate link task would let others
> link
> when they wanted too.  Otherwise I think we'd have to add another
> attribute
> to the
> interface and I'd rather avoid that if possible.


> >>So, the input files for this task are a mix of source files,
> object files
> >>and library files.  And a set of library names (for libraries which need
> to
> >>be searched for in the lib path).
> >>
> >>Rather than pull these out into separate filesets for each type of file,
> I'd
> >>rather we just allow one or more filesets, each with a mix of
> file types,
> >>and use the file name to figure out which step to include them in.
> >>You've used <fileset>, I've used <source>.  I'd rather not use something
> as
> >>general as <fileset>, and <source> implies a set of C++ source
> files.  Bit
> >>stuck on a name here.
> Agreed.  Just one minor question though, what will we do when the
> task gets
> handed a
> filename that isn't c++?  Do we ignore it and continue or throw a build
> exception?
> Hmmm, actually this behavior could be determined by a failonerror
> attribute.

We should just skip files we don't recognise.  This is what <javac> does.
Perhaps we log the fact that we're skipping a file (using the verbose level,
of course).

> +1 to this idea, all except the libraries. See below
> >>* libraries.
> >>
> >>Given the above, I wonder if your <libraryset> datatype is
> necessary?  We
> do
> >>need the two different ways of referencing libraries that it
> provides: by
> >>file name, and by base name.  If we allow libraries to be
> included in the
> >>input file set - as above - then we're left with just a list of library
> base
> >>names.  Let's make this a 'libs' attribute and keep it simple.
> The reason I used the library set was to prevent people from adding a
> fileset
> that searched the entire filesystem looking for libraries.  My
> original code
> allowed
> for a file set, then I accidently had it search the entire
> filesystem and it
> took
> waaayy to long.  That's when it got replaced.

Not sure how <libraryset> solves this problem.  It can take a nested
<fileset> element.  This just pushes the problem down a level.

We're always going to have the problem of people using filesets badly.
Probably the way to deal with this problem is in FileSet itself (or
DirectoryScanner, I guess).  Haven't thought too much on this, but some

 - DirectoryScanner doesn't take into account the prefix of the include
patterns, it just starts recursing at the base directory.  E.g. for a
pattern like includes="some/fixed/dir/**/*.lib", the scan could start at
<rootdir>/some/fixed/dir".  Unless you're doing a slow scan (does anybody?).

 - Add the ability to add individual files and nested filesets to a fileset.
Then you don't need to set dir="/" on the outer fileset.

 - Maybe some warnings, say when dir="/" and a pattern starts with "**".  Or
maybe when dir is an absolute dir.

Anyway, probably out of scope here.

I think the way to deal with this in the C++ task is to allow more than one
input fileset.  E.g.

   <fileset dir="src"/>
   <fileset dir="build/libs"/>
   <fileset dir="../../someotherproject/build/libs"/>
   <fileset dir="/someexternallib/libs"/>


<compilecpp libs="someotherproject, someexternal">
   <libpath path="../../someotherproject/build/libs;/someexternallib/libs"/>
   <fileset dir="src"/>
   <fileset dir="build/libs"/>

> >>* intermediate dir
> >>
> >>My compile task preserves the relative directory structure from
> the source
> >>directory, under the output directory.  The plan here was that you could
> run
> >>compile once, but link several times using files from different
> >>subdirectories.
> >>A unified task makes this less useful, so let's just put the
> object files
> in
> >>one directory, as your task does.
> If we maintain a seperate link task it would be useful to preserve the
> directory
> structure.  So this really depends on what we decide in this respect.
> >>* output file name
> >>
> >>Not entirely clear on why you have separate 'execdestdir' and 'outfile'
> >>attributes.  Can we use a single 'outfile' attribute here?
> The plan for execdestdir was that it would be the located the library or
> executable got
> placed in when it was done, but your right I think we can just use an
> outfile attribute here
> and slightly simplify the interface.
> >>* choosing the compiler.
> >>
> >>You've called it 'compiler', I've called it 'suite'.  Let's use
> compiler.
> >>
> >>Your task requires a compiler be specified.  I'd rather we made it
> optional,
> >>and use a default compiler for the OS the task is running on.  Exactly
> what
> >>the default for a particular OS should be - that's another issue.
> >>
> >>One of my goals for the C++ support in ant is to make the task as
> >>cross-platform as possible, so that a build writer isn't forced to use
> >>different attribute values for each different platform the
> build runs on.
> >>Requiring the build writer to specify a compiler forces this.  Granted,
> any
> >>real project almost always needs platform specific properties (defines,
> >>libs, whatever) - but let's not force this on every project.
> Agreed.  Maybe we make GCC the default since a port of it exists on nearly
> every
> platform?  Would like comments from the group on this one.

Yep - GCC is a good default.

> The only further questions I have are about our handling of libraries.
> How will we handle libraries when the object file(s) are newer then those
> contained within the library we built?  Do we just update the library, or
> completely rebuild the library?

Incremental sounds good.  That's all I've ever done.

Possibly we're going to need a 'force' option at some stage.  Maybe we could
use that to decide when to rebuild the lib.

In the mean-time, people can simply delete the lib.

> We will also need to do some checks when we link executables.  I
> am thinking
> mostly in the case where the libraries we previously linked
> against are now
> newer
> then the executable.  Shouldn't be much of an issue, but something to keep
> in mind.


> I think once we get the details of this hammered out it shouldn't be
> difficult to
> get this implemented.  We already have two frameworks to work off
> of so its
> just a
> matter of getting the details pinned down.
> Again comments would be most welcome from the group
> Mark A Russell
> NextGen Software Engineer
> CSG Systems, Inc.
> E-Mail:

Do You Yahoo!?
Get your free address at

View raw message