On Fri, Jun 27, 2014 at 5:24 PM, Quibbler <[email protected]> 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?
-Mike
--
--
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.