Skip to content

Commit cedfb1a

Browse files
committed
Extend the build directive syntax with cargo::metadata=
1 parent c9b89c6 commit cedfb1a

File tree

1 file changed

+83
-12
lines changed

1 file changed

+83
-12
lines changed

src/cargo/core/compiler/custom_build.rs

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -643,26 +643,97 @@ impl BuildOutput {
643643
Ok(line) => line.trim(),
644644
Err(..) => continue,
645645
};
646-
let mut iter = line.splitn(2, ':');
646+
let mut new_syntax = true;
647+
let mut iter = line.splitn(2, "::");
647648
if iter.next() != Some("cargo") {
648-
// skip this line since it doesn't start with "cargo:"
649-
continue;
649+
// For backwards compatibility, we also accept lines that start with "cargo:".
650+
new_syntax = false;
651+
iter = line.splitn(2, ":");
652+
if iter.next() != Some("cargo") {
653+
// skip this line since it doesn't start with "cargo:" or "cargo::".
654+
continue;
655+
}
650656
}
651657
let data = match iter.next() {
652658
Some(val) => val,
653659
None => continue,
654660
};
655661

656-
// getting the `key=value` part of the line
657-
let mut iter = data.splitn(2, '=');
658-
let key = iter.next();
659-
let value = iter.next();
660-
let (key, value) = match (key, value) {
661-
(Some(a), Some(b)) => (a, b.trim_end()),
662-
// Line started with `cargo:` but didn't match `key=value`.
662+
// Old syntax:
663+
// cargo:rustc-flags=VALUE
664+
// cargo:KEY=VALUE (for other unreserved keys)
665+
// New syntax:
666+
// cargo::rustc-flags=VALUE
667+
// cargo::metadata=KEY=VALUE (for other unreserved keys)
668+
const RESERVED_KEYS: &[&str] = &[
669+
"rustc-flags",
670+
"rustc-link-lib",
671+
"rustc-link-search",
672+
"rustc-link-arg-cdylib",
673+
"rustc-link-arg-bins",
674+
"rustc-link-arg-bin",
675+
"rustc-link-arg-tests",
676+
"rustc-link-arg-benches",
677+
"rustc-link-arg-examples",
678+
"rustc-link-arg",
679+
"rustc-cfg",
680+
"rustc-check-cfg",
681+
"rustc-env",
682+
"warning",
683+
"rerun-if-changed",
684+
"rerun-if-env-changed",
685+
];
686+
let mut iter = data.splitn(3, '=');
687+
let part1 = iter.next();
688+
let part2 = iter.next();
689+
let part3 = iter.next();
690+
let (key, value) = match (part1, part2, part3) {
691+
(Some("metadata"), Some(a), Some(b)) => {
692+
// `cargo::metadata=` should only be used with the new syntax.
693+
if !new_syntax {
694+
bail!("invalid output in {}: `{}`\n\
695+
Expected a line with `cargo::metadata=KEY=VALUE`, but found `cargo:metadata=KEY=VALUE`.\n\
696+
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
697+
for more information about build script outputs.", whence, line,
698+
)
699+
}
700+
// Reserved keys should not be used with the `cargo::metadata` syntax.
701+
if new_syntax && RESERVED_KEYS.contains(&a) {
702+
bail!("invalid output in {}: `{}`\n\
703+
The reserved key `{}` cannot be used in a `cargo::metadata` line. Please use `cargo::{}=VAlUE` instead.\n\
704+
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
705+
for more information about build script outputs.", whence, line, a, a
706+
)
707+
}
708+
(a, b.trim_end().to_owned())
709+
},
710+
(Some(a), Some(b), None) => {
711+
// Only reserved keys should be used with the `cargo::` syntax.
712+
// Otherwise, it should be `cargo::metadata=KEY=VALUE`.
713+
if new_syntax && !RESERVED_KEYS.contains(&a) {
714+
bail!("invalid output in {}: `{}`\n\
715+
Expected a line with `cargo::metadata=KEY=VALUE` but it did not have the `metadata=` part.\n\
716+
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
717+
for more information about build script outputs.", whence, line
718+
)
719+
}
720+
(a, b.trim_end().to_owned())
721+
},
722+
(Some(a),Some(b),Some(c)) => {
723+
// Only reserved keys should be used with the `cargo::` syntax.
724+
// Otherwise, it should be `cargo::metadata=KEY=VALUE`.
725+
if new_syntax && !RESERVED_KEYS.contains(&a) {
726+
bail!("invalid output in {}: `{}`\n\
727+
Expected a line with `cargo::metadata=KEY=VALUE` but it did not have the `metadata=` part.\n\
728+
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
729+
for more information about build script outputs.", whence, line
730+
)
731+
}
732+
// For instance, `cargo:rustc-link-search=[KIND=]PATH` or `cargo::rustc-link-search=[KIND=]PATH`.
733+
(a, format!("{}={}", b, c).trim_end().to_owned())
734+
}
735+
// Line started with `cargo:` or `cargo::` but didn't match any of the above.
663736
_ => bail!("invalid output in {}: `{}`\n\
664-
Expected a line with `cargo:key=value` with an `=` character, \
665-
but none was found.\n\
666737
See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script \
667738
for more information about build script outputs.", whence, line),
668739
};

0 commit comments

Comments
 (0)