-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Support newlines and carriage returns in variable bindings #2239
base: master
Are you sure you want to change the base?
Conversation
doc/manual.asciidoc
Outdated
@@ -821,6 +821,9 @@ behaviors: | |||
`$` followed by a newline:: escape the newline (continue the current line | |||
across a line break). | |||
|
|||
`$|`:: a newline. Can be used to put literal newlines into ninja variables |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this belongs between $:
and $$
below, rather than here. To be consistent with the other escapes, maybe something like:
`$|`:: a newline. (This becomes a literal newline in the variable assignment.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Currently, ninja variables cannot contain newlines because the syntax doesn't have any way to express them. It's reasonably common for build systems to want to write out files during the build. The easiest way to do that with ninja would be to make a rule that has an rspfile with the desired content, and then moves the rspfile to the destination location. However, currently, the rspfile can't contain newlines, and thus some form of escaping needs to be done, and the rspfile will need to be copied, doing the unescaping during the copy, instead of moved. This hurts build performance. An alternative implementation would be to use echo commands to write the file, but that can also have slight performance penalties due to needing to split up long command lines into multiple echo commands, and merge the resulting files afterwards. Using echo commands also requires more sophisticated shell escaping than just ninja escaping. Add a new escape sequence, $|, that will represent a literal newline.
To go along with the last commit on adding support for newlines for rules that write files, add support for using carriage returns in variables. Carriage returns don't need a special escape sequence like newlines do, because a single carriage return does not indicate the end of a line, only \r\n does. The lexer just had to be updated to accept them.
cd783ed
to
f99df9f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@jhasse Could you help merge this if it looks good to you? |
This PR adds a new escape sequence, $|, to represent a newline in a ninja variable binding. In addition, it also allows carriage returns in variable bindings, which previously gave a lexing error.
It's reasonably common for build systems to want to write out files during the build. The easiest way to do that with ninja would be to make a rule that has an rspfile with the desired content, and then moves the rspfile to the destination location. However, currently, the rspfile can't contain newlines, and thus some form of escaping needs to be done, and the rspfile will need to be copied, doing the unescaping during the copy, instead of moved. This hurts build performance. An alternative implementation would be to use echo commands to write the file, but that can also have slight performance penalties due to needing to split up long command lines into multiple echo commands, and merge the resulting files afterwards. Using echo commands also requires more sophisticated shell escaping than just ninja escaping.
After this PR, it's possible to use any byte except for a null (0) byte in a variable binding. Newlines and dollars must be escaped.