On Tuesday, July 8, 2014 2:47:10 PM UTC-4, [email protected] wrote: > > On Fri, Jun 27, 2014 at 5:24 PM, Quibbler <[email protected] > <javascript:>> wrote: > >> There are several issues related to the functioning of TUP_CWD. >> >> 1. The documentation is inadequate. Specifically, the examples. They >> are all trivial. Are there any examples of usage where the variable in >> used in a file to reference a file in a distinct sub-tree? For example, >> given top directory A, with sub-directories A1 and A2, and with >> sub-sub-directories A11, A12, A21, and A22, have a Tupfile in A11 refer to >> a tupfile in A22. >> > > Sorry - I will try to come up with a more complete example below. For this > particular case, you'd probably want something like: > > A/Tuprules.tup: > MYPROJ_ROOT = $(TUP_CWD) > > A/A1/A11/Tupfile: > include_rules > FILENAME = $(MYPROJ_ROOT)/A2/A22/thefile.txt > : |> cat $(FILENAME) |> > > >> >> 2. Variants appear to have a bad influence on TUP_CWD in that they >> introduce a skew in the directory trees. Each variant directory gets >> merged with the contents of the top-level directory, except for the variant >> directories. So a reference to a source file in A11 as above from within a >> source file in A22 would be "../../A1/A11/<filename>". But a reference to >> a source file in A11 from within a binary file in A22, which binary is one >> directory down from the source tree, would be "../../../A1/A11<filename>". >> > > Yeah, there are unfortunately cases where the variant approach doesn't > work here. In retrospect, it probably would have been better to introduce a > variant variable to handle variant support. I was trying to make it so you > could enable variants without having to make any changes to the rules, > since the directory merging would take care of running commands inside or > outside of a variant. Unfortunately when you then run things outside of > tup, the directories are no longer merged, so you hit things like this (or > with gdb, where paths no longer match). However, the directory merging > should make all of these things work *inside* tup seamlessly. If it > doesn't, that's probably a bug. > > >> >> 3. There does not appear to be a mechanism to unambiguously refer to the >> root of the project tree -- the source directory containing the .ini file. >> In a test project I have a tup file in src/include/tup. It contains a lot >> of standardized definitions and actions that are needed for the unit, >> specification, and acceptance testing directories. So the local Tupfile in >> each testing directory contains only "include_rules". The Tuprules.tup >> file a couple directories above the test directory contains a Tuprules.tup >> file with little more than an include statement of the form "include >> $(ROOT)/src/include/tup/std_test.tup". At the root of the project is >> another TupRules.tup file containing the definitions and actions need to >> build everything within the build, particularly "ROOT=$(TUP_CWD)", which, >> from the documentation, is required to "fix" the definition of ROOT so that >> the directory agility of TUP_CWD is discarded. >> > > The reason for manually specifying *_ROOT variables is that what you > consider to be the "root of the project" may be merely a subdirectory for > someone else. So, you can define your own root in a Tuprules.tup file, and > it won't matter if another person runs 'tup init' there or at some level > further up the tree. > > >> >> But the definition of ROOT does not work. It changes along with TUP_CWD, >> which contradicts the immediacy provisions stated in the documentation. >> >> And at build time I get an error of the form: >> >> "Unable to find directory for include file >> '../../../../../include/tup/std_test.tup' relative to 'bin/infra/errmsg/T'". >> >> The directory containing the Tupfile doing the including is not >> bin/infra/errmsg/T. It is src/infra/errmsg/T. Due to the unification of >> the source and binary directories the name of the directory under the >> project's root may be irrelevant. But the path int he error mesage has an >> extra "../" which makes the downward leg of the path start appear to start >> one directory above the root of the project. >> >> Replacing ROOT with TUP_CWD produces the same result. >> >> So how can I refer to the root of the project *without* using TUP_CWD? >> > > You shouldn't need to use TUP_CWD in this case - the 'include' statement > already knows where the current Tupfile is, and the include path is > relative to that. Your Tuprules.tup should have: > > include src/include/tup/std_test.tup > > Generally you would only need TUP_CWD for variables that end up in > :-rules. Here's a simple C program example that hopefully illustrates the > need for it: > > myproj/ > - include/ > - foo.h > - src/ > - main.c > - utils/ > - utils.c > > A first try might look like: > > myproj/src/Tupfile: > CFLAGS += -I../include > : foreach *.c |> gcc $(CFLAGS) -c %f -o %o |> %B.o > > myproj/src/utils/Tupfile: > CFLAGS += -I../../include > : foreach *.c |> gcc $(CFLAGS) -c %f -o %o |> %B.o > > As you know, to reduce the rule redundancy, we can make a macro in the > top-level Tuprules.tup: > > myproj/Tuprules.tup: > !cc = |> gcc $(CFLAGS) -c %f -o %o |> %B.o > > myproj/src/Tupfile: > include_rules > CFLAGS += -I../include > : foreach *.c |> !cc |> > > myproj/src/utils/Tupfile: > include_rules > CFLAGS += -I../../include > : foreach *.c |> !cc |> > > Now what if you want to reduce the CFLAGS redundancy? After all, every > directory is trying to point to the same myproj/include directory, so in > theory we should be able to specify it in one place, rather than in each > subdir with the right amount of '../' prefixed to it. Let's try a simple > case: > > myproj/Tuprules.tup: > CFLAGS += -Iinclude > !cc = |> gcc $(CFLAGS) -c %f -o %o |> %B.o > > myproj/src/Tupfile: > : foreach *.c |> !cc |> > > myproj/src/utils/Tupfile: > : foreach *.c |> !cc |> > > Expanding the string, we'd try to run 'gcc -Iinclude -c main.c -o main.o' > in the src/ directory, so it won't be looking at the right place for > myproj/include. If we changed the CFLAGS in Tuprules.tup to '-I../include', > then myproj/src would be correct, but myproj/src/utils would still be > wrong. Tup has no idea that this particular CFLAGS string should be > relative to the Tupfile being parsed, so you have to tell it to add the > relative path. You do this by using $(TUP_CWD) - > > myproj/Tuprules.tup: > CFLAGS += -I$(TUP_CWD)/include > !cc = |> gcc $(CFLAGS) -c %f -o %o |> %B.o > > Since this particular CFLAGS variable is used in a :-rule, and we want to > convert the included-file-relative path (ie: path relative to the > Tuprules.tup directory) to a Tupfile-relative path, then we use $(TUP_CWD). > > If we wanted our rules in a separate rule directory, we could have > Tuprules.tup look like this: > > myproj/Tuprules.tup: > MYPROJ_ROOT = $(TUP_CWD) > include tupstuff/myrules.tup > > myproj/tupstuff/myrules.tup: > CFLAGS += -I$(MYPROJ_ROOT)/include > # Or CFLAGS += -I$(TUP_CWD)/../include > !cc = ... > > We don't need the $(TUP_CWD) in the 'include' statement because it is just > relative to the file being parsed. We do need either TUP_CWD or a > TUP_CWD-based variable (like MYPROJ_ROOT) when specifying the CFLAGS, > because these common files have no idea how many '../'s will be necessary > until they are included from a primary Tupfile. > > Does that help at all? >
I do not know yet. I need to study what you have written and revisit the tests that I ran with the new information in mind. Thanks for the detailed response. However, while I am on the topic of my lack of comprehension, I have been unable to make sense of the the following message: "tup error: Explicitly named file '<path>/<file>.o' can't be listed as an input because it was generated from external directory '<path>/<subdir>' - try placing the file in a group instead and using the group as an input." As written the above message appears to be nonsense -- it is certainly possible for a rule in a tup file to produce a file that another rule in another tup file consumes. After all that is kind of the point of multi-directory build systems. So the message must mean something that I cannot fathom. Several definitions need to be inferred: -- Does the term "explicitly name file" suggest that an implicitly named file would be acceptable where an explicit file name would not? -- Does the term "external directory" mean something special other than "not the directory containing the offending rule and tup file"? -- How do I use a group as an input to the ar command? On this topic I am trying to figure out what is wrong with one tup file generating an output that is used an an input in a tup file in a different directory. What is the real problem here? What is it about groups what works where explicit file naming cannot work? Thanks for the help. -- -- tup-users mailing list email: [email protected] unsubscribe: [email protected] options: http://groups.google.com/group/tup-users?hl=en --- You received this message because you are subscribed to the Google Groups "tup-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
