]> git.proxmox.com Git - cargo.git/blob - src/cargo/core/manifest.rs
Auto merge of #6547 - Zoxc:dual-proc-macros, r=alexcrichton
[cargo.git] / src / cargo / core / manifest.rs
1 use std::collections::{BTreeMap, HashMap};
2 use std::fmt;
3 use std::hash::{Hash, Hasher};
4 use std::path::{Path, PathBuf};
5 use std::rc::Rc;
6
7 use semver::Version;
8 use serde::ser;
9 use serde::Serialize;
10 use url::Url;
11
12 use crate::core::interning::InternedString;
13 use crate::core::profiles::Profiles;
14 use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
15 use crate::core::{Edition, Feature, Features, WorkspaceConfig};
16 use crate::util::errors::*;
17 use crate::util::toml::TomlManifest;
18 use crate::util::{short_hash, Config, Filesystem};
19
20 pub enum EitherManifest {
21 Real(Manifest),
22 Virtual(VirtualManifest),
23 }
24
25 /// Contains all the information about a package, as loaded from a Cargo.toml.
26 #[derive(Clone, Debug)]
27 pub struct Manifest {
28 summary: Summary,
29 targets: Vec<Target>,
30 links: Option<String>,
31 warnings: Warnings,
32 exclude: Vec<String>,
33 include: Vec<String>,
34 metadata: ManifestMetadata,
35 custom_metadata: Option<toml::Value>,
36 profiles: Profiles,
37 publish: Option<Vec<String>>,
38 publish_lockfile: bool,
39 replace: Vec<(PackageIdSpec, Dependency)>,
40 patch: HashMap<Url, Vec<Dependency>>,
41 workspace: WorkspaceConfig,
42 original: Rc<TomlManifest>,
43 features: Features,
44 edition: Edition,
45 im_a_teapot: Option<bool>,
46 default_run: Option<String>,
47 metabuild: Option<Vec<String>>,
48 }
49
50 /// When parsing `Cargo.toml`, some warnings should silenced
51 /// if the manifest comes from a dependency. `ManifestWarning`
52 /// allows this delayed emission of warnings.
53 #[derive(Clone, Debug)]
54 pub struct DelayedWarning {
55 pub message: String,
56 pub is_critical: bool,
57 }
58
59 #[derive(Clone, Debug)]
60 pub struct Warnings(Vec<DelayedWarning>);
61
62 #[derive(Clone, Debug)]
63 pub struct VirtualManifest {
64 replace: Vec<(PackageIdSpec, Dependency)>,
65 patch: HashMap<Url, Vec<Dependency>>,
66 workspace: WorkspaceConfig,
67 profiles: Profiles,
68 warnings: Warnings,
69 }
70
71 /// General metadata about a package which is just blindly uploaded to the
72 /// registry.
73 ///
74 /// Note that many of these fields can contain invalid values such as the
75 /// homepage, repository, documentation, or license. These fields are not
76 /// validated by cargo itself, but rather it is up to the registry when uploaded
77 /// to validate these fields. Cargo will itself accept any valid TOML
78 /// specification for these values.
79 #[derive(PartialEq, Clone, Debug)]
80 pub struct ManifestMetadata {
81 pub authors: Vec<String>,
82 pub keywords: Vec<String>,
83 pub categories: Vec<String>,
84 pub license: Option<String>,
85 pub license_file: Option<String>,
86 pub description: Option<String>, // not markdown
87 pub readme: Option<String>, // file, not contents
88 pub homepage: Option<String>, // url
89 pub repository: Option<String>, // url
90 pub documentation: Option<String>, // url
91 pub badges: BTreeMap<String, BTreeMap<String, String>>,
92 pub links: Option<String>,
93 }
94
95 #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
96 pub enum LibKind {
97 Lib,
98 Rlib,
99 Dylib,
100 ProcMacro,
101 Other(String),
102 }
103
104 impl LibKind {
105 /// Returns the argument suitable for `--crate-type` to pass to rustc.
106 pub fn crate_type(&self) -> &str {
107 match *self {
108 LibKind::Lib => "lib",
109 LibKind::Rlib => "rlib",
110 LibKind::Dylib => "dylib",
111 LibKind::ProcMacro => "proc-macro",
112 LibKind::Other(ref s) => s,
113 }
114 }
115
116 pub fn linkable(&self) -> bool {
117 match *self {
118 LibKind::Lib | LibKind::Rlib | LibKind::Dylib | LibKind::ProcMacro => true,
119 LibKind::Other(..) => false,
120 }
121 }
122 }
123
124 impl fmt::Debug for LibKind {
125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126 self.crate_type().fmt(f)
127 }
128 }
129
130 impl<'a> From<&'a String> for LibKind {
131 fn from(string: &'a String) -> Self {
132 match string.as_ref() {
133 "lib" => LibKind::Lib,
134 "rlib" => LibKind::Rlib,
135 "dylib" => LibKind::Dylib,
136 "proc-macro" => LibKind::ProcMacro,
137 s => LibKind::Other(s.to_string()),
138 }
139 }
140 }
141
142 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
143 pub enum TargetKind {
144 Lib(Vec<LibKind>),
145 Bin,
146 Test,
147 Bench,
148 ExampleLib(Vec<LibKind>),
149 ExampleBin,
150 CustomBuild,
151 }
152
153 impl ser::Serialize for TargetKind {
154 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
155 where
156 S: ser::Serializer,
157 {
158 use self::TargetKind::*;
159 match *self {
160 Lib(ref kinds) => s.collect_seq(kinds.iter().map(LibKind::crate_type)),
161 Bin => ["bin"].serialize(s),
162 ExampleBin | ExampleLib(_) => ["example"].serialize(s),
163 Test => ["test"].serialize(s),
164 CustomBuild => ["custom-build"].serialize(s),
165 Bench => ["bench"].serialize(s),
166 }
167 }
168 }
169
170 impl fmt::Debug for TargetKind {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 use self::TargetKind::*;
173 match *self {
174 Lib(ref kinds) => kinds.fmt(f),
175 Bin => "bin".fmt(f),
176 ExampleBin | ExampleLib(_) => "example".fmt(f),
177 Test => "test".fmt(f),
178 CustomBuild => "custom-build".fmt(f),
179 Bench => "bench".fmt(f),
180 }
181 }
182 }
183
184 impl TargetKind {
185 pub fn description(&self) -> &'static str {
186 match self {
187 TargetKind::Lib(..) => "lib",
188 TargetKind::Bin => "bin",
189 TargetKind::Test => "integration-test",
190 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => "example",
191 TargetKind::Bench => "bench",
192 TargetKind::CustomBuild => "build-script",
193 }
194 }
195 }
196
197 /// Information about a binary, a library, an example, etc. that is part of the
198 /// package.
199 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
200 pub struct Target {
201 kind: TargetKind,
202 name: String,
203 // Note that the `src_path` here is excluded from the `Hash` implementation
204 // as it's absolute currently and is otherwise a little too brittle for
205 // causing rebuilds. Instead the hash for the path that we send to the
206 // compiler is handled elsewhere.
207 src_path: TargetSourcePath,
208 required_features: Option<Vec<String>>,
209 tested: bool,
210 benched: bool,
211 doc: bool,
212 doctest: bool,
213 harness: bool, // whether to use the test harness (--test)
214 for_host: bool,
215 proc_macro: bool,
216 edition: Edition,
217 }
218
219 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
220 pub enum TargetSourcePath {
221 Path(PathBuf),
222 Metabuild,
223 }
224
225 impl TargetSourcePath {
226 pub fn path(&self) -> Option<&Path> {
227 match self {
228 TargetSourcePath::Path(path) => Some(path.as_ref()),
229 TargetSourcePath::Metabuild => None,
230 }
231 }
232
233 pub fn is_path(&self) -> bool {
234 match self {
235 TargetSourcePath::Path(_) => true,
236 _ => false,
237 }
238 }
239 }
240
241 impl Hash for TargetSourcePath {
242 fn hash<H: Hasher>(&self, _: &mut H) {
243 // ...
244 }
245 }
246
247 impl fmt::Debug for TargetSourcePath {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 match self {
250 TargetSourcePath::Path(path) => path.fmt(f),
251 TargetSourcePath::Metabuild => "metabuild".fmt(f),
252 }
253 }
254 }
255
256 impl From<PathBuf> for TargetSourcePath {
257 fn from(path: PathBuf) -> Self {
258 assert!(path.is_absolute(), "`{}` is not absolute", path.display());
259 TargetSourcePath::Path(path)
260 }
261 }
262
263 #[derive(Serialize)]
264 struct SerializedTarget<'a> {
265 /// Is this a `--bin bin`, `--lib`, `--example ex`?
266 /// Serialized as a list of strings for historical reasons.
267 kind: &'a TargetKind,
268 /// Corresponds to `--crate-type` compiler attribute.
269 /// See https://doc.rust-lang.org/reference/linkage.html
270 crate_types: Vec<&'a str>,
271 name: &'a str,
272 src_path: Option<&'a PathBuf>,
273 edition: &'a str,
274 #[serde(rename = "required-features", skip_serializing_if = "Option::is_none")]
275 required_features: Option<Vec<&'a str>>,
276 }
277
278 impl ser::Serialize for Target {
279 fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
280 let src_path = match &self.src_path {
281 TargetSourcePath::Path(p) => Some(p),
282 // Unfortunately getting the correct path would require access to
283 // target_dir, which is not available here.
284 TargetSourcePath::Metabuild => None,
285 };
286 SerializedTarget {
287 kind: &self.kind,
288 crate_types: self.rustc_crate_types(),
289 name: &self.name,
290 src_path,
291 edition: &self.edition.to_string(),
292 required_features: self
293 .required_features
294 .as_ref()
295 .map(|rf| rf.iter().map(|s| &**s).collect()),
296 }
297 .serialize(s)
298 }
299 }
300
301 compact_debug! {
302 impl fmt::Debug for Target {
303 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304 let (default, default_name) = {
305 match &self.kind {
306 TargetKind::Lib(kinds) => {
307 (
308 Target::lib_target(
309 &self.name,
310 kinds.clone(),
311 self.src_path().path().unwrap().to_path_buf(),
312 self.edition,
313 ),
314 format!("lib_target({:?}, {:?}, {:?}, {:?})",
315 self.name, kinds, self.src_path, self.edition),
316 )
317 }
318 TargetKind::CustomBuild => {
319 match self.src_path {
320 TargetSourcePath::Path(ref path) => {
321 (
322 Target::custom_build_target(
323 &self.name,
324 path.to_path_buf(),
325 self.edition,
326 ),
327 format!("custom_build_target({:?}, {:?}, {:?})",
328 self.name, path, self.edition),
329 )
330 }
331 TargetSourcePath::Metabuild => {
332 (
333 Target::metabuild_target(&self.name),
334 format!("metabuild_target({:?})", self.name),
335 )
336 }
337 }
338 }
339 _ => (
340 Target::new(self.src_path.clone(), self.edition),
341 format!("with_path({:?}, {:?})", self.src_path, self.edition),
342 ),
343 }
344 };
345 [debug_the_fields(
346 kind
347 name
348 src_path
349 required_features
350 tested
351 benched
352 doc
353 doctest
354 harness
355 for_host
356 proc_macro
357 edition
358 )]
359 }
360 }
361 }
362
363 impl Manifest {
364 pub fn new(
365 summary: Summary,
366 targets: Vec<Target>,
367 exclude: Vec<String>,
368 include: Vec<String>,
369 links: Option<String>,
370 metadata: ManifestMetadata,
371 custom_metadata: Option<toml::Value>,
372 profiles: Profiles,
373 publish: Option<Vec<String>>,
374 publish_lockfile: bool,
375 replace: Vec<(PackageIdSpec, Dependency)>,
376 patch: HashMap<Url, Vec<Dependency>>,
377 workspace: WorkspaceConfig,
378 features: Features,
379 edition: Edition,
380 im_a_teapot: Option<bool>,
381 default_run: Option<String>,
382 original: Rc<TomlManifest>,
383 metabuild: Option<Vec<String>>,
384 ) -> Manifest {
385 Manifest {
386 summary,
387 targets,
388 warnings: Warnings::new(),
389 exclude,
390 include,
391 links,
392 metadata,
393 custom_metadata,
394 profiles,
395 publish,
396 replace,
397 patch,
398 workspace,
399 features,
400 edition,
401 original,
402 im_a_teapot,
403 default_run,
404 publish_lockfile,
405 metabuild,
406 }
407 }
408
409 pub fn dependencies(&self) -> &[Dependency] {
410 self.summary.dependencies()
411 }
412 pub fn exclude(&self) -> &[String] {
413 &self.exclude
414 }
415 pub fn include(&self) -> &[String] {
416 &self.include
417 }
418 pub fn metadata(&self) -> &ManifestMetadata {
419 &self.metadata
420 }
421 pub fn name(&self) -> InternedString {
422 self.package_id().name()
423 }
424 pub fn package_id(&self) -> PackageId {
425 self.summary.package_id()
426 }
427 pub fn summary(&self) -> &Summary {
428 &self.summary
429 }
430 pub fn targets(&self) -> &[Target] {
431 &self.targets
432 }
433 pub fn version(&self) -> &Version {
434 self.package_id().version()
435 }
436 pub fn warnings_mut(&mut self) -> &mut Warnings {
437 &mut self.warnings
438 }
439 pub fn warnings(&self) -> &Warnings {
440 &self.warnings
441 }
442 pub fn profiles(&self) -> &Profiles {
443 &self.profiles
444 }
445 pub fn publish(&self) -> &Option<Vec<String>> {
446 &self.publish
447 }
448 pub fn publish_lockfile(&self) -> bool {
449 self.publish_lockfile
450 }
451 pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] {
452 &self.replace
453 }
454 pub fn original(&self) -> &TomlManifest {
455 &self.original
456 }
457 pub fn patch(&self) -> &HashMap<Url, Vec<Dependency>> {
458 &self.patch
459 }
460 pub fn links(&self) -> Option<&str> {
461 self.links.as_ref().map(|s| &s[..])
462 }
463
464 pub fn workspace_config(&self) -> &WorkspaceConfig {
465 &self.workspace
466 }
467
468 pub fn features(&self) -> &Features {
469 &self.features
470 }
471
472 pub fn set_summary(&mut self, summary: Summary) {
473 self.summary = summary;
474 }
475
476 pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Manifest {
477 Manifest {
478 summary: self.summary.map_source(to_replace, replace_with),
479 ..self
480 }
481 }
482
483 pub fn feature_gate(&self) -> CargoResult<()> {
484 if self.im_a_teapot.is_some() {
485 self.features
486 .require(Feature::test_dummy_unstable())
487 .chain_err(|| {
488 failure::format_err!(
489 "the `im-a-teapot` manifest key is unstable and may \
490 not work properly in England"
491 )
492 })?;
493 }
494
495 if self.default_run.is_some() {
496 self.features
497 .require(Feature::default_run())
498 .chain_err(|| failure::format_err!("the `default-run` manifest key is unstable"))?;
499 }
500
501 Ok(())
502 }
503
504 // Just a helper function to test out `-Z` flags on Cargo
505 pub fn print_teapot(&self, config: &Config) {
506 if let Some(teapot) = self.im_a_teapot {
507 if config.cli_unstable().print_im_a_teapot {
508 println!("im-a-teapot = {}", teapot);
509 }
510 }
511 }
512
513 pub fn edition(&self) -> Edition {
514 self.edition
515 }
516
517 pub fn custom_metadata(&self) -> Option<&toml::Value> {
518 self.custom_metadata.as_ref()
519 }
520
521 pub fn default_run(&self) -> Option<&str> {
522 self.default_run.as_ref().map(|s| &s[..])
523 }
524
525 pub fn metabuild(&self) -> Option<&Vec<String>> {
526 self.metabuild.as_ref()
527 }
528
529 pub fn metabuild_path(&self, target_dir: Filesystem) -> PathBuf {
530 let hash = short_hash(&self.package_id());
531 target_dir
532 .into_path_unlocked()
533 .join(".metabuild")
534 .join(format!("metabuild-{}-{}.rs", self.name(), hash))
535 }
536 }
537
538 impl VirtualManifest {
539 pub fn new(
540 replace: Vec<(PackageIdSpec, Dependency)>,
541 patch: HashMap<Url, Vec<Dependency>>,
542 workspace: WorkspaceConfig,
543 profiles: Profiles,
544 ) -> VirtualManifest {
545 VirtualManifest {
546 replace,
547 patch,
548 workspace,
549 profiles,
550 warnings: Warnings::new(),
551 }
552 }
553
554 pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] {
555 &self.replace
556 }
557
558 pub fn patch(&self) -> &HashMap<Url, Vec<Dependency>> {
559 &self.patch
560 }
561
562 pub fn workspace_config(&self) -> &WorkspaceConfig {
563 &self.workspace
564 }
565
566 pub fn profiles(&self) -> &Profiles {
567 &self.profiles
568 }
569
570 pub fn warnings_mut(&mut self) -> &mut Warnings {
571 &mut self.warnings
572 }
573
574 pub fn warnings(&self) -> &Warnings {
575 &self.warnings
576 }
577 }
578
579 impl Target {
580 fn new(src_path: TargetSourcePath, edition: Edition) -> Target {
581 Target {
582 kind: TargetKind::Bin,
583 name: String::new(),
584 src_path,
585 required_features: None,
586 doc: false,
587 doctest: false,
588 harness: true,
589 for_host: false,
590 proc_macro: false,
591 edition,
592 tested: true,
593 benched: true,
594 }
595 }
596
597 fn with_path(src_path: PathBuf, edition: Edition) -> Target {
598 Target::new(TargetSourcePath::from(src_path), edition)
599 }
600
601 pub fn lib_target(
602 name: &str,
603 crate_targets: Vec<LibKind>,
604 src_path: PathBuf,
605 edition: Edition,
606 ) -> Target {
607 Target {
608 kind: TargetKind::Lib(crate_targets),
609 name: name.to_string(),
610 doctest: true,
611 doc: true,
612 ..Target::with_path(src_path, edition)
613 }
614 }
615
616 pub fn bin_target(
617 name: &str,
618 src_path: PathBuf,
619 required_features: Option<Vec<String>>,
620 edition: Edition,
621 ) -> Target {
622 Target {
623 kind: TargetKind::Bin,
624 name: name.to_string(),
625 required_features,
626 doc: true,
627 ..Target::with_path(src_path, edition)
628 }
629 }
630
631 /// Builds a `Target` corresponding to the `build = "build.rs"` entry.
632 pub fn custom_build_target(name: &str, src_path: PathBuf, edition: Edition) -> Target {
633 Target {
634 kind: TargetKind::CustomBuild,
635 name: name.to_string(),
636 for_host: true,
637 benched: false,
638 tested: false,
639 ..Target::with_path(src_path, edition)
640 }
641 }
642
643 pub fn metabuild_target(name: &str) -> Target {
644 Target {
645 kind: TargetKind::CustomBuild,
646 name: name.to_string(),
647 for_host: true,
648 benched: false,
649 tested: false,
650 ..Target::new(TargetSourcePath::Metabuild, Edition::Edition2018)
651 }
652 }
653
654 pub fn example_target(
655 name: &str,
656 crate_targets: Vec<LibKind>,
657 src_path: PathBuf,
658 required_features: Option<Vec<String>>,
659 edition: Edition,
660 ) -> Target {
661 let kind = if crate_targets.is_empty()
662 || crate_targets
663 .iter()
664 .all(|t| *t == LibKind::Other("bin".into()))
665 {
666 TargetKind::ExampleBin
667 } else {
668 TargetKind::ExampleLib(crate_targets)
669 };
670
671 Target {
672 kind,
673 name: name.to_string(),
674 required_features,
675 tested: false,
676 benched: false,
677 ..Target::with_path(src_path, edition)
678 }
679 }
680
681 pub fn test_target(
682 name: &str,
683 src_path: PathBuf,
684 required_features: Option<Vec<String>>,
685 edition: Edition,
686 ) -> Target {
687 Target {
688 kind: TargetKind::Test,
689 name: name.to_string(),
690 required_features,
691 benched: false,
692 ..Target::with_path(src_path, edition)
693 }
694 }
695
696 pub fn bench_target(
697 name: &str,
698 src_path: PathBuf,
699 required_features: Option<Vec<String>>,
700 edition: Edition,
701 ) -> Target {
702 Target {
703 kind: TargetKind::Bench,
704 name: name.to_string(),
705 required_features,
706 tested: false,
707 ..Target::with_path(src_path, edition)
708 }
709 }
710
711 pub fn name(&self) -> &str {
712 &self.name
713 }
714 pub fn crate_name(&self) -> String {
715 self.name.replace("-", "_")
716 }
717 pub fn src_path(&self) -> &TargetSourcePath {
718 &self.src_path
719 }
720 pub fn set_src_path(&mut self, src_path: TargetSourcePath) {
721 self.src_path = src_path;
722 }
723 pub fn required_features(&self) -> Option<&Vec<String>> {
724 self.required_features.as_ref()
725 }
726 pub fn kind(&self) -> &TargetKind {
727 &self.kind
728 }
729 pub fn tested(&self) -> bool {
730 self.tested
731 }
732 pub fn harness(&self) -> bool {
733 self.harness
734 }
735 pub fn documented(&self) -> bool {
736 self.doc
737 }
738 pub fn for_host(&self) -> bool {
739 self.for_host
740 }
741 pub fn proc_macro(&self) -> bool {
742 self.proc_macro
743 }
744 pub fn edition(&self) -> Edition {
745 self.edition
746 }
747 pub fn benched(&self) -> bool {
748 self.benched
749 }
750 pub fn doctested(&self) -> bool {
751 self.doctest
752 }
753
754 pub fn doctestable(&self) -> bool {
755 match self.kind {
756 TargetKind::Lib(ref kinds) => kinds
757 .iter()
758 .any(|k| *k == LibKind::Rlib || *k == LibKind::Lib || *k == LibKind::ProcMacro),
759 _ => false,
760 }
761 }
762
763 pub fn allows_underscores(&self) -> bool {
764 self.is_bin() || self.is_example() || self.is_custom_build()
765 }
766
767 pub fn is_lib(&self) -> bool {
768 match self.kind {
769 TargetKind::Lib(_) => true,
770 _ => false,
771 }
772 }
773
774 pub fn is_dylib(&self) -> bool {
775 match self.kind {
776 TargetKind::Lib(ref libs) => libs.iter().any(|l| *l == LibKind::Dylib),
777 _ => false,
778 }
779 }
780
781 pub fn is_cdylib(&self) -> bool {
782 let libs = match self.kind {
783 TargetKind::Lib(ref libs) => libs,
784 _ => return false,
785 };
786 libs.iter().any(|l| match *l {
787 LibKind::Other(ref s) => s == "cdylib",
788 _ => false,
789 })
790 }
791
792 pub fn linkable(&self) -> bool {
793 match self.kind {
794 TargetKind::Lib(ref kinds) => kinds.iter().any(|k| k.linkable()),
795 _ => false,
796 }
797 }
798
799 pub fn is_bin(&self) -> bool {
800 self.kind == TargetKind::Bin
801 }
802
803 pub fn is_example(&self) -> bool {
804 match self.kind {
805 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => true,
806 _ => false,
807 }
808 }
809
810 pub fn is_bin_example(&self) -> bool {
811 // Needed for --all-examples in contexts where only runnable examples make sense
812 match self.kind {
813 TargetKind::ExampleBin => true,
814 _ => false,
815 }
816 }
817
818 pub fn is_test(&self) -> bool {
819 self.kind == TargetKind::Test
820 }
821 pub fn is_bench(&self) -> bool {
822 self.kind == TargetKind::Bench
823 }
824 pub fn is_custom_build(&self) -> bool {
825 self.kind == TargetKind::CustomBuild
826 }
827
828 /// Returns the arguments suitable for `--crate-type` to pass to rustc.
829 pub fn rustc_crate_types(&self) -> Vec<&str> {
830 match self.kind {
831 TargetKind::Lib(ref kinds) | TargetKind::ExampleLib(ref kinds) => {
832 kinds.iter().map(LibKind::crate_type).collect()
833 }
834 TargetKind::CustomBuild
835 | TargetKind::Bench
836 | TargetKind::Test
837 | TargetKind::ExampleBin
838 | TargetKind::Bin => vec!["bin"],
839 }
840 }
841
842 pub fn can_lto(&self) -> bool {
843 match self.kind {
844 TargetKind::Lib(ref v) => {
845 !v.contains(&LibKind::Rlib)
846 && !v.contains(&LibKind::Dylib)
847 && !v.contains(&LibKind::Lib)
848 }
849 _ => true,
850 }
851 }
852
853 pub fn set_tested(&mut self, tested: bool) -> &mut Target {
854 self.tested = tested;
855 self
856 }
857 pub fn set_benched(&mut self, benched: bool) -> &mut Target {
858 self.benched = benched;
859 self
860 }
861 pub fn set_doctest(&mut self, doctest: bool) -> &mut Target {
862 self.doctest = doctest;
863 self
864 }
865 pub fn set_for_host(&mut self, for_host: bool) -> &mut Target {
866 self.for_host = for_host;
867 self
868 }
869 pub fn set_proc_macro(&mut self, proc_macro: bool) -> &mut Target {
870 self.proc_macro = proc_macro;
871 self
872 }
873 pub fn set_edition(&mut self, edition: Edition) -> &mut Target {
874 self.edition = edition;
875 self
876 }
877 pub fn set_harness(&mut self, harness: bool) -> &mut Target {
878 self.harness = harness;
879 self
880 }
881 pub fn set_doc(&mut self, doc: bool) -> &mut Target {
882 self.doc = doc;
883 self
884 }
885 }
886
887 impl fmt::Display for Target {
888 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
889 match self.kind {
890 TargetKind::Lib(..) => write!(f, "Target(lib)"),
891 TargetKind::Bin => write!(f, "Target(bin: {})", self.name),
892 TargetKind::Test => write!(f, "Target(test: {})", self.name),
893 TargetKind::Bench => write!(f, "Target(bench: {})", self.name),
894 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => {
895 write!(f, "Target(example: {})", self.name)
896 }
897 TargetKind::CustomBuild => write!(f, "Target(script)"),
898 }
899 }
900 }
901
902 impl Warnings {
903 fn new() -> Warnings {
904 Warnings(Vec::new())
905 }
906
907 pub fn add_warning(&mut self, s: String) {
908 self.0.push(DelayedWarning {
909 message: s,
910 is_critical: false,
911 })
912 }
913
914 pub fn add_critical_warning(&mut self, s: String) {
915 self.0.push(DelayedWarning {
916 message: s,
917 is_critical: true,
918 })
919 }
920
921 pub fn warnings(&self) -> &[DelayedWarning] {
922 &self.0
923 }
924 }