8 messages in com.perforce.jammingSparse directory trees containing obj...| From | Sent On | Attachments |
|---|---|---|
| Jona...@persimmon.co.uk | 18 Jun 1997 04:29 | |
| Step...@PC-Plus.DE | 18 Jun 1997 05:21 | |
| Dian...@whistle.com | 18 Jun 1997 11:44 | |
| Laur...@sybase.com | 18 Jun 1997 13:15 | |
| Arch...@parallax.com | 18 Jun 1997 13:33 | |
| Dian...@whistle.com | 18 Jun 1997 14:05 | |
| Arch...@parallax.com | 18 Jun 1997 14:49 | |
| Step...@PC-Plus.DE | 19 Jun 1997 01:05 |
| Subject: | Sparse directory trees containing objects...![]() |
|---|---|
| From: | Laur...@sybase.com (Laur...@sybase.com) |
| Date: | 06/18/1997 01:15:42 PM |
| List: | com.perforce.jamming |
I think Jam is designed on the assumption that:
- Jamfiles indicate what gets built
- the state of the filesystem indicates what's out of date
In the sparse tree scenario, you are trying to use the filesystem to indicate what gets built.
That is, you would like the presence of foo.c and absence of bar.c to tell Jam to build foo.o but not bar.o.
But with Jam, if there's a bar.o target defined in your Jamfile, and no bar.o in bar.o's LOCATE directory, Jam will build bar.o.
Unfortunately, Jam does not yet have any way to determine the state of the filesystem during its parsing phase.
That being said, I'm sure there's a way to do roughly what you want, and I couldn't resist trying out an idea.
So, say your Jamfile contained:
----------------------------------------------------- SubDir TOP src ; ALL_SRC_FILES = foo.c bar.c ;
if ! $(MY_SRC_FILES) { Library libfoobar.a : $(ALL_SRC_FILES) ; } Main foobar : $(MY_SRC_FILES) ; LinkLibraries foobar : libfoobar.a ;
SEARCH on libfoobar.a = $(SEARCH_SOURCE) $(BOBS_TREE) ; -------------------------------------------------------
(This is a unix-specific example, I know.)
If you run jam without setting MY_SRC_FILES, it will expect you to have foo.c and bar.c in your directory, and it will compile them, archive them into libfoobar.a, and link foobar with libfoobar.a.
Or, you could run:
jam -sMY_SRC_FILES="foo.c"
and jam will compile your foo.c and link foobar with your foo.o and Bob's libfoobar.a. Your foo.o will eclipse the foo.o in Bob's libfoobar.a. But this is ugly because it's up to you to tell jam which files are in your directory.
So why not use jam to set MY_SRC_FILES on the fly? You have to use a two-pass approach: run jam once to get the list of existing source files, and again to do the build, with MY_SRC_FILES set to the output of the first pass.
So, say you have a jam wrapper script which contains:
jam -sFIRST_PASS=true jam $*
To support this, you need to change your Jamfile:
ALL_SRC_FILES = foo.c bar.c ; becomes: SetSrcFiles ALL_SRC_FILES : foo.c bar.c ;
and you need to add this stuff to your Jamrules file:
-------------------------------------------- SRC_LIST_FILE = mysrc.list ;
if $(FIRST_PASS) { rule SetSrcFiles { l = $(SRC_LIST_FILE:G=$(SOURCE_GRIST)) ; SEARCH on $(>) = $(SEARCH_SOURCE) ; WriteSrcListFile $(l) : $(>) ; LOCATE on $(l) = $(LOCATE_TARGET) ; DEPENDS all : $(l) ; ALWAYS $(l) ; } actions existing WriteSrcListFile { echo "MY_SRC_FILES = $(>:BS) ;" > $(<) }
rule Main { } rule Library { } rule LinkLibraries { } # etc. } else { rule SetSrcFiles { l = $(SRC_LIST_FILE:G=$(SOURCE_GRIST)) ; SEARCH on $(l) = $(SEARCH_SOURCE) ; include $(l) ; $(<) = $(>) ; } } ----------------------------------------------
So, in English, here's what happens:
jam -sFIRST_PASS=true
creates a mysrc.list file in every source directory within scope. That's *all* that happens when FIRST_PASS is set, because the other rules are explicitly nullified.
The mysrc.list files contain lines like:
MY_SRC_FILES = foo.c ;
Only the files that exist in your tree are listed; that's because the WriteSrcListFile action uses the "existing" qualifier to restrict the $(>) instances to existing targets.
The mysrc.list files are recreated every time you run jam with FIRST_PASS set. But nothing depends on them, so unless you add source files into your directory, you won't rebuild unecessarily.
The second pass is just normal jam. But the SetSrcFiles rule now 'includes' the current directory's mysrc.list file, and thus MY_SRC_FILES is set on the fly.
There are probably some oversights in this example, but it demonstrates the approach. And naturally you could use all kinds of tricks to make it elegant & streamlined. Like, your first-pass jam could actually be a separate executable with only SubDir and SubInclude rules compiled in, and all others nulled out. And you could modify the Library rule to subsume the "if ! $(MY_SRC_FILES)" test so it wouldn't have to be coded into every Jamfile.
Anyway, it's a thought...
---Laura
------------------------------------------------------------------------ Laura Wingerd Sybase, Inc. wing...@sybase.com (510)922-5232




