Thread: [A-A-P-develop] More than one matching rule?
Brought to you by:
vimboss
From: George B. <go...@fl...> - 2003-01-15 14:46:59
|
Hi, is this my fault or AAP's? Goga [goga@sys9 ~/src/tmp]$ cat main.aap :child sub/main.aap qq$EXESUF: qq.c sub/$*SUB_OBJS :do build $source bdir: :print $BDIR [goga@sys9 ~/src/tmp]$ cat sub/main.aap SUB_SRCS = tt.c SUB_OBJS = `src2obj (SUB_SRCS)` :export SUB_OBJS [goga@sys9 ~/src/tmp]$ aap -v qq Options: verbose: 1 Values: Targets: qq Aap: Reading recipe "/usr/local/lib/aap/Exec-0.116/default.aap" Aap: Finished reading recipe "/usr/local/lib/aap/Exec-0.116/default.aap" Aap: Reading recipe "main.aap" Aap: Entering directory "/d2/home/goga/src/tmp/sub" Aap: Reading recipe "main.aap" Aap: Finished reading recipe "main.aap" Aap: Entering directory "/d2/home/goga/src/tmp" Aap: Finished reading recipe "main.aap" Aap: Building targets specified on command line Aap: 1 - updating target "qq" Aap: 2 - Using dependency "qq : qq.c sub/build-Linux2_2_17_4/tt.o" Aap: 3 - updating target "qq.c" Aap: 3 - Target has no build commands and exists: "qq.c" Aap: 3 - Using depend c for source "qq.c" Aap: 3 - Target "build-Linux2_2_17_4/qq.c.aap" is up-to-date Aap: 4 - updating target "sub/tt.h" Aap: 4 - Target has no build commands and exists: "sub/tt.h" Aap: 3 - updating target "sub/build-Linux2_2_17_4/tt.o" Aap: More than one matching build rule for "sub/build-Linux2_2_17_4/tt.o" |
From: Bram M. <Br...@mo...> - 2003-01-15 17:14:18
|
George Bronnikov wrote: > is this my fault or AAP's? [...] > Aap: 3 - updating target "sub/build-Linux2_2_17_4/tt.o" > Aap: More than one matching build rule for "sub/build-Linux2_2_17_4/tt.o" Looks like a bug. I can reproduce it. I'll try to find out what is wrong (unless someone beats me to it!). Thanks for the clear description of the problem! -- SOLDIER: Where did you get the coconuts? ARTHUR: Through ... We found them. SOLDIER: Found them? In Mercea. The coconut's tropical! "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Br...@mo... -- 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 /// \\\ Lord Of The Rings helps Uganda - http://iccf-holland.org/lotr.html /// |
From: George B. <go...@fl...> - 2003-01-21 18:10:53
|
On Wed, 15 Jan 2003, Bram Moolenaar wrote: > > Aap: 3 - updating target "sub/build-Linux2_2_17_4/tt.o" > > Aap: More than one matching build rule for "sub/build-Linux2_2_17_4/tt.o" > Looks like a bug. I can reproduce it. I'll try to find out what is > wrong (unless someone beats me to it!). I tried to look at it, here's what I found. [Disclaimer: I am not familiar with the sources yet, I just looked at small chunks of code. Heck, I don't even know Python!] Aap should figure out that sub/build-Linux2_2_17_4/tt.o can be produced by compiling sub/tt.c. In the process it must strip the build... part from the pathname, presumably in DoBuild.py:remove_bdir(). However, remove_bdir only looks for $BDIR at the beginning of the path given to it. Therefore, aap assumes it can get sub/build.../tt.o from either sub/build.../tt.c or sub/build.../tt.cpp. Since neither of these exists, aap does not know which path it should follow and gives up with the weird message. So what's wrong? 1. The diagnostics could definitely be clearer. At a minimum, I would like a verbosity flag which would list all the alternatives aap considers (like gmake -d). 2. The real dependency should have been found. I can see two ways to achieve that: a. Make remove_bdir() cleverer, possibly trying to remove $BDIR from the penultimate component of the path. b. Make implicit dependency in sub/main.aap produce $BDIR/sub/tt.o instead of sub/$BDIR/tt.o. This can probably be done by changing src2obj(). Goga |
From: Bram M. <Br...@mo...> - 2003-01-23 09:45:37
|
George Bronnikov wrote: > On Wed, 15 Jan 2003, Bram Moolenaar wrote: > > > > Aap: 3 - updating target "sub/build-Linux2_2_17_4/tt.o" > > > Aap: More than one matching build rule for "sub/build-Linux2_2_17_4/tt.o" > > Looks like a bug. I can reproduce it. I'll try to find out what is > > wrong (unless someone beats me to it!). Sorry, I still haven't had time to look into this. > I tried to look at it, here's what I found. [Disclaimer: I am not > familiar with the sources yet, I just looked at small chunks of code. > Heck, I don't even know Python!] > > Aap should figure out that sub/build-Linux2_2_17_4/tt.o can be produced by > compiling sub/tt.c. In the process it must strip the build... part from > the pathname, presumably in DoBuild.py:remove_bdir(). However, > remove_bdir only looks for $BDIR at the beginning of the path given to it. That's right. It does work for build-Linux2_2_17_4/sub/tt.o but not when "sub" comes first. I have done this intentionally, but now that I see your example I wonder if it was a good choice. > Therefore, aap assumes it can get sub/build.../tt.o from either > sub/build.../tt.c or sub/build.../tt.cpp. Since neither of these exists, > aap does not know which path it should follow and gives up with the weird > message. Glad you could figure this out. > So what's wrong? > > 1. The diagnostics could definitely be clearer. At a minimum, I would > like a verbosity flag which would list all the alternatives aap considers > (like gmake -d). True. The matching rules could be mentioned (at least the first two) and the remark that the intended source files don't exist. > 2. The real dependency should have been found. I can see two ways to > achieve that: > > a. Make remove_bdir() cleverer, possibly trying to remove $BDIR from > the penultimate component of the path. But that's actually a different build directory. And it would take much more time to try all possible ways $BDIR could be found somewhere in the path. This would also need to be done to be able to give a warning if there are multiple matches. Still, the build directory may exist in a subdirectory. Especially when using a child recipe that can be invoked by itself. And a variant may change $BDIR, that makes it complicated... > b. Make implicit dependency in sub/main.aap produce $BDIR/sub/tt.o > instead of sub/$BDIR/tt.o. This can probably be done by changing > src2obj(). That should be done. First change to the directory of the top recipe before prepending $BDIR. I'll look into this (check if there are any undesired side effects). I'm not sure when I will have time to take a better look into this, feel free to suggest a good solution. -- How To Keep A Healthy Level Of Insanity: 9. As often as possible, skip rather than walk. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-01-24 19:20:00
|
On Tue, 21 Jan 2003, Bram Moolenaar wrote: > > 2. The real dependency should have been found. I can see two ways to > > achieve that: > > > > a. Make remove_bdir() cleverer, possibly trying to remove $BDIR from > > the penultimate component of the path. > But that's actually a different build directory. And it would take much > more time to try all possible ways $BDIR could be found somewhere in the > path. This would also need to be done to be able to give a warning if > there are multiple matches. > > Still, the build directory may exist in a subdirectory. Especially when > using a child recipe that can be invoked by itself. And a variant may > change $BDIR, that makes it complicated... > > > b. Make implicit dependency in sub/main.aap produce $BDIR/sub/tt.o > > instead of sub/$BDIR/tt.o. This can probably be done by changing > > src2obj(). > > That should be done. First change to the directory of the top recipe > before prepending $BDIR. I'll look into this (check if there are any > undesired side effects). > > I'm not sure when I will have time to take a better look into this, feel > free to suggest a good solution. > > So the basic idea is that BDIR only exists in the top directory -- I did not figure it out by myself. This means that in a situation like this: main/sub$ aap main$ aap the objfiles will not be shared, even if the build variants are the same. (I am not sure whether it's right or wrong: toplevel main.aap might set variables differently.) Another problem is that you will need some clean way to set destination for other generated files besides .o -- like libraries. Simple things like $BDIR/libxx.a: a.o b.o c.o :sys rm -f $target :sys $AR qc $target $sources won't work in subdirs. Another option I had in mind was to have a separate $BDIR in every subdirectory -- so that objfile for sub/tt.c goes to sub/build.../tt.o. This has its drawbacks too -- it's harder to do installation and cleanup. Still another option is to somehow set the 'topdir' inside the .aap file. You might require it to be one of the upper directories. Goga |
From: Bram M. <Br...@mo...> - 2003-01-24 21:08:03
|
George Bronnikov wrote: > So the basic idea is that BDIR only exists in the top directory -- I did > not figure it out by myself. > > This means that in a situation like this: > > main/sub$ aap > main$ aap > > the objfiles will not be shared, even if the build variants are the same. > (I am not sure whether it's right or wrong: toplevel main.aap might set > variables differently.) That is how it currently works. Since Aap changes directory to where the recipe is, mostly this works just fine. But there is a problem with files in subdirectories if they are also build from another recipe. > Another problem is that you will need some clean way to set > destination for other generated files besides .o -- like > libraries. Simple things like > > $BDIR/libxx.a: a.o b.o c.o > :sys rm -f $target > :sys $AR qc $target $sources > > won't work in subdirs. Why would this not work? > Another option I had in mind was to have a separate $BDIR in every > subdirectory -- so that objfile for sub/tt.c goes to sub/build.../tt.o. > This has its drawbacks too -- it's harder to do installation and cleanup. I have thought about this as well. I don't recall the reason not to do it, I'm afraid I didn't make a design decision out of it. I might have to do that now, otherwise this discussion will come back later. > Still another option is to somehow set the 'topdir' inside the .aap file. > You might require it to be one of the upper directories. It's not very nice if a recipe in a subdirectory is aware of another recipe invoking it. But it should be possible to mark a recipe as being a "toplevel" recipe, one that can be used by itself. The build directory should be relative to that recipe then. -- He who laughs last, thinks slowest. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-01-26 19:42:01
|
On Fri, 24 Jan 2003, Bram Moolenaar wrote: > > Another problem is that you will need some clean way to set > > destination for other generated files besides .o -- like > > libraries. Simple things like > > > > $BDIR/libxx.a: a.o b.o c.o > > :sys rm -f $target > > :sys $AR qc $target $sources > > > > won't work in subdirs. > > Why would this not work? Let this recipe sit in main/sub. Invoking this rule from the main directory will produce main/sub/build.../libxx.a if BDIR is relative (as it is now) or main/build.../libxx.a if it's absolute. It should produce main/build.../sub/libxx.a. Goga |
From: Bram M. <Br...@mo...> - 2003-01-26 22:00:39
|
George Bronnikov wrote: > On Fri, 24 Jan 2003, Bram Moolenaar wrote: > > > Another problem is that you will need some clean way to set > > > destination for other generated files besides .o -- like > > > libraries. Simple things like > > > > > > $BDIR/libxx.a: a.o b.o c.o > > > :sys rm -f $target > > > :sys $AR qc $target $sources > > > > > > won't work in subdirs. > > > > Why would this not work? > > Let this recipe sit in main/sub. Invoking this rule from the main > directory will produce main/sub/build.../libxx.a if BDIR is relative (as > it is now) or main/build.../libxx.a if it's absolute. It should produce > main/build.../sub/libxx.a. I assume you have a recipe "main/one.aap" that has a child "main/sub/two.aap" that includes the lines above. Then the $BDIR in two.aap is "main/sub/build-something". The reason for this is that it would be possible to execute "two.aap" separately. It would have no knowledge of the "main" directory or any build directory in it. Let's assume the build directory is in the right place. The problem then becomes: How can a parent recipe obtain a result of a child recipe? When it has been produced in its build directory that is quite difficult, since the parent recipe doesn't know what the $BDIR is in the child. It's possible to pass back the name of the resulting file to the parent recipe. I think the result of a child recipe should not be put in the build directory, since it is exported to other recipes. Would it be a problem to remove $BDIR in the example you gave? -- It was recently discovered that research causes cancer in rats. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-01-27 15:05:26
|
On Sun, 26 Jan 2003, Bram Moolenaar wrote: [parts of your post rearranged] > I think the result of a child recipe should not be put in the build > directory, since it is exported to other recipes. Would it be a problem > to remove $BDIR in the example you gave? Well I assume the whole point of $BDIRs is to separate builds for different architectures/flag combinations from each other. This concern is as valid for subdirs as for the main directory. (And no, this is not a major concern in my specific situation.) > I assume you have a recipe "main/one.aap" that has a child > "main/sub/two.aap" that includes the lines above. Then the $BDIR in > two.aap is "main/sub/build-something". > > The reason for this is that it would be possible to execute "two.aap" > separately. It would have no knowledge of the "main" directory or any > build directory in it. > > Let's assume the build directory is in the right place. The problem > then becomes: How can a parent recipe obtain a result of a child recipe? > When it has been produced in its build directory that is quite > difficult, since the parent recipe doesn't know what the $BDIR is in the > child. It's possible to pass back the name of the resulting file to the > parent recipe. OK, if the results of sub/two.aap should remain inside sub/, then it seems that the most simple and general rule is one mentioned in one of the previous posts: Files produced from sources in dir/ go to dir/$BDIR/. Then all get_bdir() needs to do is try and strip BDIR from the last directory component. Another idea: do we need BDIR as a directory? Why not put the build information inside the filename? Do we need to care about systems with heavy restrictions on filename length? Goga |
From: Bram M. <Br...@mo...> - 2003-01-27 16:04:20
|
George Bronnikov wrote: > > I think the result of a child recipe should not be put in the build > > directory, since it is exported to other recipes. Would it be a problem > > to remove $BDIR in the example you gave? > > Well I assume the whole point of $BDIRs is to separate builds for > different architectures/flag combinations from each other. This concern > is as valid for subdirs as for the main directory. (And no, this is not a > major concern in my specific situation.) If you are building variants or building for different platforms, you could produce the result in the build directory. But the problem then is that you need to find it there. For a program you would usually include the variant or platform in the name of the executable. For example "foo" for the release version and "foo_debug" for the debug version. For intermediate results (e.g., libraries) the choice is not so simple. Including the variant in the file name makes it complicated, expecially if there are several variants. I think we need to leave this up to the user, since it also depends on what you do with the intermediate results (install them or throw them away?). But the default needs to be to use the build directory, since the file names need to be selected by the user. > > I assume you have a recipe "main/one.aap" that has a child > > "main/sub/two.aap" that includes the lines above. Then the $BDIR in > > two.aap is "main/sub/build-something". > > > > The reason for this is that it would be possible to execute "two.aap" > > separately. It would have no knowledge of the "main" directory or any > > build directory in it. > > > > Let's assume the build directory is in the right place. The problem > > then becomes: How can a parent recipe obtain a result of a child recipe? > > When it has been produced in its build directory that is quite > > difficult, since the parent recipe doesn't know what the $BDIR is in the > > child. It's possible to pass back the name of the resulting file to the > > parent recipe. > > OK, if the results of sub/two.aap should remain inside sub/, then it seems > that the most simple and general rule is one mentioned in one of the > previous posts: > > Files produced from sources in dir/ go to dir/$BDIR/. > > Then all get_bdir() needs to do is try and strip BDIR from the last > directory component. That does sound like the simplest solution. I think it should be done by remembering the absolute path for "dir/$BDIR". Thus there will be a list of build directories. Not sure if this always works, a file may be found in several build directories, might need some more clever mechanism (use the $BDIR from the recipe where the build commands are?). > Another idea: do we need BDIR as a directory? Why not put the build > information inside the filename? Do we need to care about systems with > heavy restrictions on filename length? The advantage of using a directory name is that it's impossible that a file with the same name exists. E.g., when compiling "foo.c" to "foo_freebsd.o", there might be a "foo_freebsd.c" as well. -- Light travels faster than sound. This is why some people appear bright until you hear them speak /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-01-27 19:50:12
|
On Mon, 27 Jan 2003, Bram Moolenaar wrote: > > OK, if the results of sub/two.aap should remain inside sub/, then it seems > > that the most simple and general rule is one mentioned in one of the > > previous posts: > > > > Files produced from sources in dir/ go to dir/$BDIR/. > > > > Then all get_bdir() needs to do is try and strip BDIR from the last > > directory component. > > That does sound like the simplest solution. I think it should be done > by remembering the absolute path for "dir/$BDIR". Thus there will be a > list of build directories. Not sure if this always works, a file may be > found in several build directories, might need some more clever > mechanism (use the $BDIR from the recipe where the build commands are?). Just to clarify: so that $BDIR reflects the variants mentioned in the recipe which contains the build commands? I would prefer to also reflect variants in upper level recipes: suppose I want a debug version and a release version. I don't want to mention this in every subproject. Goga |
From: Bram M. <Br...@mo...> - 2003-01-27 21:10:39
|
George Bronnikov wrote: > Just to clarify: so that $BDIR reflects the variants mentioned in the > recipe which contains the build commands? I would prefer to also reflect > variants in upper level recipes: suppose I want a debug version and a > release version. I don't want to mention this in every subproject. Yes, the child recipe would use the same variants as the parent. Hmm, there is a problem when the child recipe must also be able to be executed by itself. You can move the lines that define the variants to a separate recipe that can be included from both the parent and the child: parent.aap: :include common.aap :child sub/child.aap ... sub/child.aap: :include ../common.aap ... common.aap: :variant BUILD release CFLAGS = -O4 debug CFLAGS = -g But when executing "parent.aap" the common recipe is included twice, that's not what we want. I don't immediately see a simple solution for this. -- hundred-and-one symptoms of being an internet addict: 55. You ask your doctor to implant a gig in your brain. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-01-28 17:08:32
|
On Mon, 27 Jan 2003, Bram Moolenaar wrote: > But when executing "parent.aap" the common recipe is included twice, > that's not what we want. I don't immediately see a simple solution for > this. What about Objective C-like "import" (include, but only once)? Goga |
From: Bram M. <Br...@mo...> - 2003-01-28 19:02:59
|
George Bronnikov wrote: > On Mon, 27 Jan 2003, Bram Moolenaar wrote: > > > But when executing "parent.aap" the common recipe is included twice, > > that's not what we want. I don't immediately see a simple solution for > > this. > > What about Objective C-like "import" (include, but only once)? Yes, that would be a comfortable solution. The only disadvantage I can think of is that a user might get confused by all the commands that read another recipe: :include :child :import :execute I think that can be solved with proper documentation. -- hundred-and-one symptoms of being an internet addict: 60. As your car crashes through the guardrail on a mountain road, your first instinct is to search for the "back" button. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-03-20 20:19:20
|
Hello, Here's a patch that makes BDIRs reside inside every subdirectory. Not tested extensively, but at least it passes the internal tests and a couple of my own. Goga Index: DoBuild.py =================================================================== RCS file: /cvsroot/a-a-p/Exec/DoBuild.py,v retrieving revision 1.52 diff -u -r1.52 DoBuild.py --- DoBuild.py 23 Jan 2003 16:59:23 -0000 1.52 +++ DoBuild.py 20 Mar 2003 20:11:20 -0000 @@ -112,7 +112,7 @@ def get_bdir(recdict): """Get the value of $BDIR as an absolute path and ending in '/'.""" - bd = os.path.abspath(get_var_val(0, recdict, "BDIR")) + bd = get_var_val(0, recdict, "BDIR") if bd[-1] != '/' and bd[-1] != '\\': bd = bd + os.sep return bd @@ -128,18 +128,24 @@ bd = get_bdir(recdict) bd = fname_fold(bd) + if bd[-1] == '/': + bd = bd[:-1] + + # Rip out the part that should be $BDIR -- the penultimate component of the pathname. + dname, lname = os.path.split (name) + dname, bname = os.path.split (dname) + # Compare with $BDIR and then remove each "-variant" part. The last - # compare will be against "build/". + # compare will be against "build". while 1: - i = len(bd) - if len(name) > i and name[:i] == bd: - if remove: - return name[i:] - return bd + if bname == bd: + if remove: + return os.path.join (dname, lname) + return bd + os.sep i = string.rfind(bd, '-') if i < 0: break - bd = bd[:i] + os.sep + bd = bd[:i] return None Index: Util.py =================================================================== RCS file: /cvsroot/a-a-p/Exec/Util.py,v retrieving revision 1.48 diff -u -r1.48 Util.py --- Util.py 10 Mar 2003 19:06:50 -0000 1.48 +++ Util.py 20 Mar 2003 20:11:22 -0000 @@ -618,7 +618,9 @@ bdir = node.attributes.get("var_OBJSUF") else: objsuf = get_var_val(0, recdict, "OBJSUF") - name = os.path.join(bdir, name) + + dname, bname = os.path.split(name) + name = os.path.join(dname, bdir, bname) i = string.rfind(name, '.') if i > 0 and i > string.rfind(name, '/') and i > string.rfind(name, '\\'): |
From: Bram M. <Br...@mo...> - 2003-03-20 22:11:36
|
George Bronnikov wrote: > Here's a patch that makes BDIRs reside inside every subdirectory. Not > tested extensively, but at least it passes the internal tests and a couple > of my own. Can you explain your motivation for chosing this solution? Where to create the build directory is not an obvious choice: - In the directory of the recipe that is executed - In the directory of the source file - In the toplevel directory of the project I think we need to make a design decision out of this. That requires looking into the arguments for each alternative. -- hundred-and-one symptoms of being an internet addict: 157. You fum through a magazine, you first check to see if it has a web address. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: Wichert A. <wi...@wi...> - 2003-03-20 22:39:46
|
Previously Bram Moolenaar wrote: > Can you explain your motivation for chosing this solution? > > Where to create the build directory is not an obvious choice: > - In the directory of the recipe that is executed > - In the directory of the source file > - In the toplevel directory of the project - have it configurable I might have the sources on a read-only medium and build elsewhere. Wichert. -- Wichert Akkerman <wi...@wi...> http://www.wiggy.net/ A random hacker |
From: George B. <go...@fl...> - 2003-03-21 14:56:11
|
On Thu, 20 Mar 2003, Bram Moolenaar wrote: > > George Bronnikov wrote: > > > Here's a patch that makes BDIRs reside inside every subdirectory. Not > > tested extensively, but at least it passes the internal tests and a couple > > of my own. > > Can you explain your motivation for chosing this solution? > > Where to create the build directory is not an obvious choice: > - A In the directory of the recipe that is executed > - B In the directory of the source file > - C In the toplevel directory of the project (I added labels so I can refer to the variants) Wichert Ackerman wrote: > - have it configurable > > I might have the sources on a read-only medium and build elsewhere. I'll try to list my considerations for the choice. Source files in different directories may have the same name (we could in fact forbid this as bad style, but I assume we don't). Therefore, full pathnames of objfiles have to encode full pathnames of sources. This can be done by using long filenames, but spreading them across directories seems more natural. The next natural choice: Objfile for /a/b/c.../y/z.c should be in /a/b/c/.../BDIR/.../y/z.o This won't work with variant A if the source is not C-commanded by the recipe (i.e not in a subdir of the recipe's dir) -- again, that could be prohibited as bad style. Of the remaining two variants (B and C) B seems simpler (does not use the notion of toplevel directory). Moreover, as BDIR is relative, rules like $BDIR/lib.a: ../a/$BDIR/a.o ../b/$BDIR/b.o :sys ar qc $target $source work in a straightforward manner (not sure how to reproduce them with A or C). On the other side, with B you cannot distinguish between objfiles from variants with the same name but different toplevel dirs -- these might be different. And, of course, this does not work with Wichert's scenario -- read-only source directory. For that, I think you would need a function, something like OBJNAME(source). Goga |
From: Bram M. <Br...@mo...> - 2003-03-21 15:58:10
|
George Bronnikov wrote: > > > Here's a patch that makes BDIRs reside inside every subdirectory. > > > Not tested extensively, but at least it passes the internal tests > > > and a couple of my own. > > > > Can you explain your motivation for chosing this solution? > > > > Where to create the build directory is not an obvious choice: > > - A In the directory of the recipe that is executed > > - B In the directory of the source file > > - C In the toplevel directory of the project > > (I added labels so I can refer to the variants) > > Wichert Ackerman wrote: > > - have it configurable > > > > I might have the sources on a read-only medium and build elsewhere. > > I'll try to list my considerations for the choice. > > Source files in different directories may have the same > name (we could in fact forbid this as bad style, but I assume we don't). I don't think it is bad style. We must be prepared for the same source file name appearing in multiple directories. > Therefore, full pathnames of objfiles have to encode full pathnames of > sources. This can be done by using long filenames, but spreading them > across directories seems more natural. The only relevant difference is that directories need to be created, while "munged" filenames scan be thrown in one directory. My experience is that creating directories is easy, while creating a good munging scheme is complicated. > The next natural choice: > > Objfile for /a/b/c.../y/z.c should be in /a/b/c/.../BDIR/.../y/z.o > > This won't work with variant A if the source is not C-commanded by the > recipe (i.e not in a subdir of the recipe's dir) -- again, that could be > prohibited as bad style. I'm not sure if I understand this remark. Do you mean that the recipe could build "../file.c"? That is strange, and it looks like all the schemes have a problem with this, except B (unless the directory is read-only). > Of the remaining two variants (B and C) B seems simpler (does not use the > notion of toplevel directory). Moreover, as BDIR is relative, rules > like > > $BDIR/lib.a: ../a/$BDIR/a.o ../b/$BDIR/b.o > :sys ar qc $target $source > > work in a straightforward manner (not sure how to reproduce them with A or > C). $BDIR is currently used as an absolute path, this is required in several situations. Using $BSUBDIR would be possible though. > On the other side, with B you cannot distinguish between objfiles from > variants with the same name but different toplevel dirs -- these might be > different. When the user creates two recipes that build the same files with different properties, he may have to specify a different build directory for all schemes. For B it needs to be specified always, for A only when the recipes are in the same directory, for C when the toplevel directory is the same. > And, of course, this does not work with Wichert's scenario -- read-only > source directory. For that, I think you would need a function, something > like OBJNAME(source). For sources in a read-only directory you would have to make a local copy. You can use a "fetch" attribute for that. The directory of the recipe should be writable, this is your build directory (AAPDIR is created here, for example). I think the C scheme (using the toplevel directory of the project) has the disadvantage that it's not always clear what that toplevel directory is. Especially when you can build a program by itself or you can build the program as part of a package. So let's discard this alternative. I can't say I have heard a clear advantage for A or B. When a recipe only builds files that exist in the same directory, A and B are equal. Thus we should look into the situation that a recipe builds source files in sub-directories and/or directories starting with "../". Making a few examples should reveal what the consequences are for the A and B schemes. -- hundred-and-one symptoms of being an internet addict: 165. You have a web page burned into your glasses /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-03-21 16:57:49
|
On Fri, 21 Mar 2003, Bram Moolenaar wrote: > > Source files in different directories may have the same > > name (we could in fact forbid this as bad style, but I assume we don't). > I don't think it is bad style. We must be prepared for the same source > file name appearing in multiple directories. OK > > Therefore, full pathnames of objfiles have to encode full pathnames of > > sources. This can be done by using long filenames, but spreading them > > across directories seems more natural. > The only relevant difference is that directories need to be created, > while "munged" filenames scan be thrown in one directory. My experience > is that creating directories is easy, while creating a good munging > scheme is complicated. OK, I was just trying to consider all the possible alternatives. > > The next natural choice: > > > > Objfile for /a/b/c.../y/z.c should be in /a/b/c/.../BDIR/.../y/z.o > > > > This won't work with variant A if the source is not C-commanded by the > > recipe (i.e not in a subdir of the recipe's dir) -- again, that could be > > prohibited as bad style. > > I'm not sure if I understand this remark. Do you mean that the recipe > could build "../file.c"? That is strange, and it looks like all the > schemes have a problem with this, except B (unless the directory is > read-only). The recipe could want to build an object form ../somedir/file.c. If the present recipe lies in a subproject, that might make sense. In this case, C would work as well. > > Of the remaining two variants (B and C) B seems simpler (does not use the > > notion of toplevel directory). Moreover, as BDIR is relative, rules > > like > > > > $BDIR/lib.a: ../a/$BDIR/a.o ../b/$BDIR/b.o > > :sys ar qc $target $source (*) > > > > work in a straightforward manner (not sure how to reproduce them with A or > > C). > $BDIR is currently used as an absolute path, this is required in > several situations. Using $BSUBDIR would be possible though. My patch, by the way, makes BDIR relative (I have not noticed the places where it needs to be absolute). Moreover, with B, you don't have one $BDIR; every subdirectory of the project has its own. BSUBDIR does not seem to exist in the current sources. > > On the other side, with B you cannot distinguish between objfiles from > > variants with the same name but different toplevel dirs -- these might be > > different. > When the user creates two recipes that build the same files with > different properties, he may have to specify a different build directory > for all schemes. For B it needs to be specified always, for A only when > the recipes are in the same directory, for C when the toplevel directory > is the same. Yes, but with B, the confilct is harder to notice. > > And, of course, this does not work with Wichert's scenario -- read-only > > source directory. For that, I think you would need a function, something > > like OBJNAME(source). > > For sources in a read-only directory you would have to make a local > copy. You can use a "fetch" attribute for that. The directory of the > recipe should be writable, this is your build directory (AAPDIR is > created here, for example). > > I think the C scheme (using the toplevel directory of the project) has > the disadvantage that it's not always clear what that toplevel directory > is. Especially when you can build a program by itself or you can build > the program as part of a package. So let's discard this alternative. Agreed. > I can't say I have heard a clear advantage for A or B. > > When a recipe only builds files that exist in the same directory, A and > B are equal. Thus we should look into the situation that a recipe > builds source files in sub-directories and/or directories starting with > "../". Making a few examples should reveal what the consequences are > for the A and B schemes. OK, let's take the example that started the thread: .../proj: main.aap qq.c .../proj/sub: main.aap tt.c With A, we get .../proj/build-.../: qq.o .../proj/build-.../sub/: tt.o The objfiles are all neatly contained within .../proj/build-.../. Moreover, if you start aap in .../proj/sub, you get another tt.o in .../proj/sub/build-.../ (which may or may not be an advantage). With B, we get .../proj/build-.../: qq.o .../proj/sub/build-.../: tt.o Tt.o is shared, irrespective of where we start aap. Consider now situation like that shown in my library example: .../proj/ main.aap .../proj/a main.aap a.c .../proj/b main.aap b.c .../proj/lib main.aap The intention is for main.aap in .../proj/lib to specify building a library from objects corresponding to a.c and b.c. With B, we get .../proj/a/build-.../a.o, .../proj/b/build-.../b.o, and .../proj/lib/build-.../lib.a. The rule is the one given above (*) With A, we should get .../proj/build-.../a/a.o, .../proj/build-.../b/b.o, and, presumably, .../proj/build-.../lib/lib.a. I don't see a clear way to write lib's recipe for that. Goga |
From: Bram M. <Br...@mo...> - 2003-03-21 18:54:22
|
George Bronnikov wrote: > > $BDIR is currently used as an absolute path, this is required in > > several situations. Using $BSUBDIR would be possible though. > > My patch, by the way, makes BDIR relative (I have not noticed the places > where it needs to be absolute). Moreover, with B, you don't have one > $BDIR; every subdirectory of the project has its own. > > BSUBDIR does not seem to exist in the current sources. No, it would need to be added. I'll probably do that anyway, because it can be useful and there is no easy way to get the "build-..." part out of $BDIR. > > I can't say I have heard a clear advantage for A or B. > > > > When a recipe only builds files that exist in the same directory, A and > > B are equal. Thus we should look into the situation that a recipe > > builds source files in sub-directories and/or directories starting with > > "../". Making a few examples should reveal what the consequences are > > for the A and B schemes. > > OK, let's take the example that started the thread: > > .../proj: > main.aap > qq.c > > .../proj/sub: > main.aap > tt.c > > With A, we get > > .../proj/build-.../: > qq.o > > .../proj/build-.../sub/: > tt.o > > The objfiles are all neatly contained within .../proj/build-.../. > Moreover, if you start aap in .../proj/sub, you get another tt.o in > .../proj/sub/build-.../ (which may or may not be an advantage). If the proj/sub/main.aap recipe compiles tt.c, then the result would be in proj/sub/build-.../tt.o. With A the build directory is relative to the recipe that contains the build commands. > With B, we get > > .../proj/build-.../: > qq.o > > .../proj/sub/build-.../: > tt.o > > Tt.o is shared, irrespective of where we start aap. Same for A. You would get a difference when compiling "sub/tt.c" from a recipe proj/other.aap. > Consider now situation like that shown in my library example: I'll add simplistic recipes to show how I would do this. > .../proj/ > main.aap OBJ = # start with empty $OBJ :child a/main.aap # adds it object files to $OBJ :child b/main.aap # adds it object files to $OBJ :child lib/main.aap all: lib prog prog : $OBJ :do build $source > .../proj/a > main.aap > a.c SRC = a.c # could be extended with other files OBJ = `src2obj(SRC)` _parent.OBJ += $OBJ # add .o files to list of the parent all: $OBJ # do this when executing this recipe alone > .../proj/b > main.aap > b.c SRC = b.c # could be extended with other files OBJ = `src2obj(SRC)` _parent.OBJ += $OBJ # add .o files to list of the parent all: $OBJ # do this when executing this recipe alone > .../proj/lib > main.aap lib: $_parent.OBJ :do makelib $source > The intention is for main.aap in .../proj/lib to specify building a > library from objects corresponding to a.c and b.c. > > With B, we get .../proj/a/build-.../a.o, .../proj/b/build-.../b.o, and > .../proj/lib/build-.../lib.a. The rule is the one given above (*) > > With A, we should get .../proj/build-.../a/a.o, .../proj/build-.../b/b.o, > and, presumably, .../proj/build-.../lib/lib.a. As mentioned above, both methods produce the same files. > I don't see a clear way to write lib's recipe for that. I have given an idea above. Essential is that only the subprojects "a" and "b" know what files they contain and pass this on to other recipes with $OBJ. This uses the new scope implementation (it's almost ready, just need to do some more testing). Unfortunately, this example doesn't show a difference between A and B. Another one? It would at least have to use a source file in a subdirectory of the directory where the recipe is. -- hundred-and-one symptoms of being an internet addict: 166. You have been on your computer soo long that you didn't realize you had grandchildren. /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-03-24 14:54:29
|
Sorry for the delay. On Fri, 21 Mar 2003, Bram Moolenaar wrote: > > With B, we get > > > > .../proj/build-.../: > > qq.o > > > > .../proj/sub/build-.../: > > tt.o > > > > Tt.o is shared, irrespective of where we start aap. > Same for A. You would get a difference when compiling "sub/tt.c" from a > recipe proj/other.aap. OK. This means I misunderstood what you meant by A. My understanding was (call it A') that BDIR is created under the place where the toplevel main.aap is invoked (this, of course, does not have to be the toplevel directory of the project). > > Consider now situation like that shown in my library example: > > I'll add simplistic recipes to show how I would do this. > > > .../proj/ > > main.aap > > OBJ = # start with empty $OBJ > :child a/main.aap # adds it object files to $OBJ > :child b/main.aap # adds it object files to $OBJ > > :child lib/main.aap > > all: lib prog > > prog : $OBJ > :do build $source > > > .../proj/a > > main.aap > > a.c > > SRC = a.c # could be extended with other files > OBJ = `src2obj(SRC)` > _parent.OBJ += $OBJ # add .o files to list of the parent > all: $OBJ # do this when executing this recipe alone > > > .../proj/b > > main.aap > > b.c > > SRC = b.c # could be extended with other files > OBJ = `src2obj(SRC)` > _parent.OBJ += $OBJ # add .o files to list of the parent > all: $OBJ # do this when executing this recipe alone > > > .../proj/lib > > main.aap > > lib: $_parent.OBJ > :do makelib $source This is roughly how I solved the problem in my own project. > Unfortunately, this example doesn't show a difference between A and B. > Another one? It would at least have to use a source file in a > subdirectory of the directory where the recipe is. OK. So here is an example that shows the difference: .../proj: main.aap a.c .../proj/sub: b.c The toplevel (and only) main.aap: SRC = a.c sub/b.c OBJ = `src2obj(SRC)` prog: $OBJ :do build {target=$target} $source With A, you'll get .../proj/build-.../a.o and .../proj/build-.../sub/b.o. With B, .../proj/build-.../a.o and .../proj/sub/build-.../b.o An argument for B: you know where to search the object for b.c without looking at the recipe (well, of course, you need to know which variant you compile). Src2obj does not need to know the recipe's position, either. An argument for A: with B, you don't have BDIR at all. With A, the variable is local to the recipe, but at least it exists. I'm not sure any of these arguments is compelling enough to choose one variant over another. Goga |
From: Bram M. <Br...@mo...> - 2003-03-24 15:43:06
|
George Bronnikov wrote: > OK. This means I misunderstood what you meant by A. My understanding was > (call it A') that BDIR is created under the place where the toplevel > main.aap is invoked (this, of course, does not have to be the toplevel > directory of the project). I suppose we actually have four possibilities then, for creating the build directory: A. In the directory of the recipe that contains the build commands B. In the directory of the source file C. In the toplevel directory of the project D. In the directory of the current toplevel recipe Of these four only the last one uses a different build directory for a source file depending on which recipe you execute. The first one can have the problem that a default rule is used, thus it's not clear which recipe triggers the file to be build and therefore it is not clear which build directory to use. This may result in "D" to be used for targets without explicit build commands. > > Unfortunately, this example doesn't show a difference between A and B. > > Another one? It would at least have to use a source file in a > > subdirectory of the directory where the recipe is. > > OK. So here is an example that shows the difference: > > .../proj: > main.aap > a.c > > .../proj/sub: > b.c > > The toplevel (and only) main.aap: > > SRC = a.c sub/b.c > OBJ = `src2obj(SRC)` > > prog: $OBJ > :do build {target=$target} $source > > With A, you'll get .../proj/build-.../a.o and .../proj/build-.../sub/b.o. > With B, .../proj/build-.../a.o and .../proj/sub/build-.../b.o > > An argument for B: you know where to search the object for b.c without > looking at the recipe (well, of course, you need to know which variant you > compile). Src2obj does not need to know the recipe's position, either. > > An argument for A: with B, you don't have BDIR at all. With A, the > variable is local to the recipe, but at least it exists. > > I'm not sure any of these arguments is compelling enough to choose one > variant over another. It seems this quickly turns into a list of less important arguments, such as whether it's nice to have everything below one build directory or have a build directory that doesn't contain subdirectories. I can at least say that "D" is not nice, since the build directory would depend on what sub-project of a larger project you are building. If you have a package with several programs, building the whole package would use a different build directory than building each program in a subdirectory. A disadvantage of "C" is that you need to specify what the toplevel directory is. It's an extra choice to make when writing the recipe. And you probably need some default mechanism for when the toplevel isn't specified. A disadvantage I see for "A" is that the directory is unclear for targets that are build by default rules instead of explicit dependencies. This unpredictability is not nice. The disadvantage of "B" is that it doesn't work for read-only directories. You need to work around that by explicitly specifying a different build directory. This would not happen very often, and manually specifying a directory is not that much of a problem. Or you can make a copy of the source files with the "fetch" mechanism. An advantage of "B" is that you could also build a source file in a directory level upwards without much trouble. E.g., "../common/file.c". With "A" this is difficult to take care of, because "$BDIR/../common/file.o" is not what you want. Thus I tend to prefer "B" at the moment: create a build directory where the source file is. What would be the remaining problems to be solved? - If the source file is build in different ways, this requires different build directories. When using variants this is done automatically. When the user writes two recipes he has to take care that the build directories used are different. - $BDIR cannot be a full path to which the object file name is appended. This requires using "sub/$BSUBDIR/file.o" for "sub/file.c". Can anyone think of an example where "B" does not work well? -- hundred-and-one symptoms of being an internet addict: 193. You ask your girlfriend to drive home so you can sit back with your PDA and download the information to your laptop /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |
From: George B. <go...@fl...> - 2003-03-24 15:59:35
|
On Mon, 24 Mar 2003, Bram Moolenaar wrote: ... > B. In the directory of the source file ... > The disadvantage of "B" is that it doesn't work for read-only > directories. You need to work around that by explicitly specifying a > different build directory. How would you do that for multi-directory projects? Goga |
From: Bram M. <Br...@mo...> - 2003-03-24 18:33:38
|
George Bronnikov wrote: > On Mon, 24 Mar 2003, Bram Moolenaar wrote: > > ... > > B. In the directory of the source file > ... > > > The disadvantage of "B" is that it doesn't work for read-only > > directories. You need to work around that by explicitly specifying a > > different build directory. > > How would you do that for multi-directory projects? You would need to specify the build directory for each object file. If we make $BSUBDIR available, it would be something like: SRC = /usr/src/path/file.c OBJ = $BSUBDIR/file.o $OBJ : $SRC :do compile $source prog : $OBJ :do build $source But we could add something to make it easier. Perhaps: BDIR = $BSUBDIR Thus setting $BDIR explicitly would mean the automatic mechanism is disabled. But that only works when all object files can be put in one directory (no duplicate file names). Or we could use an attribute: SRC = /usr/src/path/file.c {builddir = $BSUBDIR} That's nicer. Just specifying the source files and the final target, without mentioning the object files, is often preferred. This attribute allows doing that. And you can use a different attribute if there are duplicate source file names: SRC = /usr/src/path/file.c {builddir = $BSUBDIR} SRC = /usr/src/otherpath/file.c {builddir = $BSUBDIR-other} -- % cat /usr/include/sys/errno.h #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ [...] #define EMACS 666 /* Too many macros */ % /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 at Amazon -- http://ICCF.nl/click1.html /// |