Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables don't work in order-only dependency list #720

Open
mathstuf opened this issue Mar 10, 2014 · 5 comments
Open

Variables don't work in order-only dependency list #720

mathstuf opened this issue Mar 10, 2014 · 5 comments

Comments

@mathstuf
Copy link
Contributor

This fails to build: is this intended?

% cat build.ninja
rule TOUCH
    command = touch $out
multi = in1 in2
build out : TOUCH || $multi
build in1 : TOUCH
build in2 : TOUCH
% ninja
ninja: error: 'in1 in2', needed by 'out', missing and no known rule to make it
@mathstuf
Copy link
Contributor Author

I guess a work-around would be to have a phony target gather the dependencies and then depend on the phony target, but this corner case should be documented, IMO.

@cdyson37
Copy link

cdyson37 commented May 4, 2018

I guess a work-around would be to have a phony target gather the dependencies and then depend on the phony target

I ended up doing exactly that. In my case I have many targets that depend on many exported header files.

Without this trick, the generator has to repeat the very long list over and over again. So much so, this actually produces a slowdown in ninja_syntax.py trying to word-wrap the lists, and makes the ninja file massive (workaround: have very long lines!)

The manual says that variables are "shorter reusable names for strings" (i.e. not lists-of-strings), so I guess the behaviour isn't surprising. Perhaps we need arrays? That's a pretty big change though!

@cdyson37
Copy link

Unfortunately the "use a phony target as an alias" doesn't quite work as you lose some transitivity:

$ cat build.ninja 
rule touch
  command = touch $out

build alias: phony file1 file2

rule output
  command = echo "Building thing"; touch output

build output: output alias

$ touch file1 file2

$ ninja
echo "Building thing"; touch output
Building thing

$ touch file1 file2

$ ninja
ninja: no work to do.

You get the same problem if file1 and file2 are themselves generated, possibly from another file. Note that they get built correctly the first time round:

$ cat build.ninja
rule touch
  command = touch $out

build file1: touch
build file2: touch

build alias: phony file1 file2

rule output
  command = echo "Building thing"; touch output

build output: output alias


$ ninja
Building thing

$ touch file1

$ ninja
ninja: no work to do.

I think the problem is that alias isn't considered dirty if no work needed to be done on file1 or file2.

If you change the alias rule to be touch then you get the desired behaviour. i.e. you have to use a special file to indicate that the files it refers to are up-to-date.

@mathstuf
Copy link
Contributor Author

That's as to be expected I think. This issue specifically mentioned order-only dependencies for a reason (though I understand that the reasoning there was not readily specified).

@kyleedwardsny
Copy link

kyleedwardsny commented Nov 19, 2019

Perhaps we need arrays? That's a pretty big change though!

What about Perl-like array prefixes? Something like this:

# "f 3.txt" has a space
@myfiles = f1.txt f2.txt f$ 3.txt

# Expands to f1.txt f2.txt "f 3.txt" f4.txt
@myfiles2 = $@myfiles f4.txt

# Expands to an empty string, as strings cannot contain arrays
# Strings and arrays may have the same name
# Alternative array reference syntax $@{array}
myfiles = $@{myfiles}

rule touch
  command = touch $out

build $@myfiles: touch

All uses of @ and $@ above are currently a syntax error (the $ prefix is needed to make this so, otherwise the @ would be a literal @.) Thus, this design would be backwards-compatible.

The inputs and outputs of a build line can evaluate as arrays rather than strings. Anywhere where things have to be evaluated as strings, array references can just expand to nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants