Re: Cross-dependencies and output folders and more

Bram Moolenaar <[email protected]>
Newsgroups gmane.comp.tools.aap.user
Message-ID <[email protected]>
Dobes Vandermeer wrote:

> > How do these dependencies work exactly?  If it's a dependency on the
> > generated library itself it could be simple.  This also depends on
> > whether you want to be able to build each library separately, or just
> > build everything from the top.  Being able to build each part separately
> > is more complicated.
> 
> Seeing that chart again I realize its a little dumb -- really the
> dependency is only from the binaries to the libraries.  Currently I have
> a dependency for the library folders on the libraries they use because
> there are test programs inside the library folders which use the other
> libs.  Although some of the header files in the libraries are generated,
> currently this isn't integrated into the build system, so there isn't
> really a dependency there.

For a first implementation you could do a few things manually.  But I
like to keep in mind what should be supported eventually.  I can
understand that running tests for one library requires other parts of
the project to be build.  And using generated header files from other
sub-projects should also be possible without tricks.

> I think you described what I wanted to -- creating a full install tree
> "somewhere" as part of the build.  I just don't want to have to type
> "aap install" to get this effect.  I'd also want to be able to build
> specific targets by name, and have to output appear in this same temp
> install folder.

You could use "aap test" and have the test target invoke "install" after
setting the destination directory.  That should be a matter of:

	test:
		...
		# install in a temp dir for testing
		_top.PREFIX = tempdir
		:update install
		...

Provided that the install target respects $PREFIX, of course.

> Sorry, I think I've gotten myself a little confused because of these
> jam-isms.  Of course you could specify different targets by using a
> different path instead of using a different "grist".
> 
> I'll explain grist and what makes it useful, then you might have a peek
> into my twisted view: file targets can have a prefix of the form <grist>
> -- examples might be <installed>libz.a <built>libz.a, etc.  This allows
> you to distinguish between "different" files with the same name.  This
> is then combined with jam's LOCATE and SEARCH variables.  When jam
> expands variables in shell commands, it deletes the grist and inserts
> the full path to the file, based on either LOCATE or SEARCH for that
> target.  So, if you have to copy files around you give each copy its own
> "grist".  This feature is used for many purposes, such as distinguishing
> two source files with the same name, distinguishing multiple copies of
> the same file, and finding header files (using SEARCH).  Its handy
> because your rules can more easily predict the "grist" of a file than
> its path, and you can bind the actual locations late.
> 
> So, it never occurred to me until just now I could use the path to the
> target instead of a grist.  I don't really know whether grist is really
> worth it or not.

Thanks for the explanation.  I would summarize it with "a symbolic name
for the directory".  It could be useful.  For example, Aap already uses
the $BDIR variable for the directory of the object files.  You wouldn't
want to use its value on the Aap command line.  In Jam terms you would
have a target $BDIR/foo.o called <bdir>foo.o.

I'm not sure if we need a new mechanism for this.  Including $BDIR in
the target would be possible, so long as we can avoid the shell from
expanding it.  This would work on Unix:

	aap '$BDIR/foo.o'

That is, if Aap would expand the command line argument, which it
currently does not.  The expansion is easy to add.  What's more tricky
is that we then need a mechanism to avoid the expansion when we don't
want it (just in case someone has a target with a $ in the name...).
Oh wait, we can simply use the $($) mechanism, like it's already done.
Hmm, seems I already solved the problem.  Here is a patch to try out:

*** DoBuild.py~	Thu Oct 30 13:15:39 2003
--- DoBuild.py	Wed Nov  5 13:32:54 2003
***************
*** 1522,1529 ****
                  targets.append(work.get_node("fetch", ""))
                  targets.extend(default_targets(work, work.recdict))
              else:
                  # Find an existing Node or create a new one.
!                 targets.append(work.get_node(t))
      
      else:
          targets = default_targets(work, work.recdict)
--- 1522,1531 ----
                  targets.append(work.get_node("fetch", ""))
                  targets.extend(default_targets(work, work.recdict))
              else:
+                 # Expand variables in the target, e.g.: $BDIR/foo.o.
+                 et = expand(0, work.recdict, t, Expand(0, Expand.quote_aap))
                  # Find an existing Node or create a new one.
!                 targets.append(work.get_node(et))
      
      else:
          targets = default_targets(work, work.recdict)

> > If it's about making sure that files in the right place for testing then
> > the simplest solution is often to simply copy the files with ":cp".
> > Doing this with dependencies can be uneccessary complicated.
> 
> Yeah... I suppose you locate the source file using $BDIR and the output
> file using some variable of your choice?
> 
> Could I make a rule like ":cptobin" that would find the file and copy it
> to the correct "bin" folder?

Not literally ":cptobin", this sounds like you want to define an action
with ":action cptobin" and invoke it with ":do cptobin".

> > Although ":child ../expat" will work, this will cause
> > trouble when building everything.  Hmm, apparently Aap doesn't handle
> > this yet.  It would require a bit of Python:
> 
> OK.. well thats something for you to chew on I suppose!

And hopefully a few other people on aap-develop have an idea for a good
solution.

> > > Does aap have any kind of automatic tree detection?  It would be great
> > > if I could omit not only the :include ../../common.app, but also any
> > > lines for cross-tree dependencies (other than a line saying that this
> > > executable links with that library, or this library uses that library so
> > > link that one if you link this one).
> > 
> > Currently it only works if you build from the toplevel.  I agree it
> > would be nice to add support for building sub-projects and still use the
> > dependencies that were defined at the toplevel.
> 
> Perhaps instead of running aap I could write a script that hunts upwards
> for the top-level main.aap, and runs aap there with a computed target
> based on the path?  What if I specified a specific target when building
> in the subdirectory?

For now you could do it like that.  The workaround script could look for
a specific file, such as "top.aap".  When it's not there prepend the
last part of $cwd to the targets and change one directory upwards.
An exception needs to be made for targets "clean", "install", etc.

But this is a common request, it requires a common solution.  I'm
currently thinking that a specific command in the recipe to specify the
parent could be useful:

	:parent ../main.aap

Don't know how this would work exactly though...

> So:
> 
> :filetype
>         declare nsis_installer
> 
> :produce nsis_installer server-$version.exe : server.nsi
> 
> :action build nsis_installer
> 	:sys makensis $source etc.
> 
> is this the way this should be done?  That seems OK to me.

For the NSIS installer, don't you always use one script to specify the
rules?  The idea of ":produce" is that you give it the name of your
program and a list of source files to make it from.  Aap then figures
out how to turn each source file into an object file and link them
together.  In this case your source files are executables or libraries
and you only need to run NSIS to turn them into a program.  You are not
using the mechanism that ":produce" offers to turn sources into object
files.

Invoking the action directly with ":do" might be what you actually want.
You at least need to specify the files that are packed into the
resulting executable.  A Luxury version would obtain the list of files
from the script, something like:

	server-$version.exe build: server.nsi
		:syseval nsis-parser --get-files | :assing files
		:update $files
		:sys nsis $source

Then "aap build" would do everything that's needed.  You "just" need to
write the nsis-parser command :-).

> > > BTW, these might make good FAQ entries (even if they are in the
> > > documentation); I'm probably not the only one.
> > > 
> > > I'd like to use aap for my project, but I'm not a Python programmer
> > > (yet) so I can't really hack it up to add these features if they aren't
> > > there.
> > 
> > Your project sounds like a quite complicated one with specific demands.
> 
> Well, it doesn't seem that complicated -- really the main trouble is
> that the lib files are built in a different folder from the binaries
> that use them, and its not a sub-folder (because there are multiple
> binaries).  We managed to modify jam, at least, so that it allowed us to
> build in a folder and have it rebuild any outdated libs used by binaries
> in that folder.  Maybe thats too much -- I suppose I could try and live
> with having to build at the toplevel to update the libraries... or
> something.

These requests are not exotic.  I think Aap should be able to support
this.  And I don't see a reason why it couldn't, thus it is only a
matter of someone implementing this.  Actually, the implementation is
probably simple, the main work will be to decide how to specify a
project with sub-projects in a nice, simple and reliable way.

> > You probably run into a few things that have not been implemented yet.
> > First thing is then to find out what you actually wanted to do before
> > thinking of possible solutions.
> 
> Well, we already have a jam-based build system, so I'm hoping to clear
> out the few annoying quirks of jam, which are:
> 
> - Doesnt rebuild when the build commands change
> - Doesnt support using checksums

Aap already does this.

> - Doesnt support caching (pretty minor, though)

What kind of caching?  Aap's way of using checksums means that if you
change a comment in a source file it will compile the source file and
then find out the object file didn't change and the program doesn't need
to be linked again.

> - Uses the native shell to run commands, so you get command-line-length
> problems, backslash vs forward slash problems (aggravated by cygwin use,
> where you sometimes want both).

I'm afraid Aap doesn't solve this yet.  Using internal Aap commands is a
partial solution.  I know SCons has something to work around the command
line length limitation, we can probably use that in Aap.

> - Doesn't include platform-independent builtin commands (e.g. move,
> copy, zip, unzip, see aap command list) so you have to use
> platform-specific ones, with platform-specific flags.

That was one of the main reasons to make Aap work this way.  It's quite
annoying having to solve "cp" versus "copy" differences in a Makefile.

> - Has lots of little quirks, like:
>     - jam clean also cleans the sibling folders you depend on
>     - sometimes you want to build a specific target, but that target has
> a grist that is too annoying to type in.
> - Doesn't build java with dependencies (but nobody else does, either)

This depends on the Java compiler used, it seems.  I know SCons has
quite a bit of trouble getting it right.  Invoking the Java compiler for
each changed source file might work (with a bit of overhead).

> So far it seems like aap and SCons are the best -- but SCons' syntax is
> way too ugly and verbose.  Its starting to look like aap still has some
> maturing to do in the area of building large projects but its feature
> list is pretty cool.  I'm curious to experiment with this stuff where it
> downloads or cvs checkouts other projects and builds them so far ctags
> worked for me but subversion didn't.  Nevertheless it would be neat to
> be building my own project and have it connect to sourceforge and
> download new versions of the libs I use!

That sounds like a good summary of the current state.

Subversion didn't work for me either (I started working on Subversion
support one day and the first thing I ran into was that the FreeBSD port
of subversion didn't work.  Still didn't get over that...).

-- 
System administrators are just like women: You can't live with them and you
can't live without them.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///          Creator of Vim - Vi IMproved -- http://www.Vim.org          \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\  Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html  ///


-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive?  Does it
help you create better code?   SHARE THE LOVE, and help us help
YOU!  Click Here: http://sourceforge.net/donate/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.