(path: impl Into<PathBuf>)
| 91 | mangle_symbols: program.mangle_symbols, |
| 92 | } |
| 93 | } else { |
| 94 | ImportClosurePolicy::Disabled |
| 95 | }; |
| 96 | manifest.source_prelude = (!program.layout.is_empty()).then(|| program.layout.to_owned()); |
| 97 | manifest |
| 98 | } |
| 99 | |
| 100 | /// Defaults for a raw-assembly root: no stdlib (the hosted runtime glue would |
| 101 | /// collide on `_start`), no import closure, no HLL ABI exports. |
| 102 | pub fn apply_asm_root_defaults(&mut self) { |
| 103 | self.stdlib = StdlibPolicy::None; |
| 104 | self.import_closure = ImportClosurePolicy::Disabled; |
| 105 | self.abi_exports.clear(); |
| 106 | } |
| 107 | |
| 108 | pub fn from_file(path: impl Into<PathBuf>) -> Result<Self, BuildError> { |
| 109 | let path = path.into(); |
| 110 | let text = fs::read_to_string(&path).map_err(BuildError::Io)?; |
| 111 | let base_dir = path.parent().unwrap_or_else(|| std::path::Path::new(".")); |
| 112 | let values = build_manifest::parse(&text).map_err(|err| BuildError::Manifest(err.0))?; |
| 113 | |
| 114 | let root_path = values |
| 115 | .get("root") |
| 116 | .ok_or_else(|| BuildError::Manifest("build manifest missing `root`".to_owned()))?; |
| 117 | let root_path = resolve_manifest_path(base_dir, root_path); |
| 118 | let name = values.string("name").unwrap_or_else(|| { |
| 119 | root_path |
| 120 | .file_stem() |
| 121 | .and_then(|stem| stem.to_str()) |
| 122 | .unwrap_or("program") |
| 123 | .to_owned() |
| 124 | }); |
| 125 | let target = values |
| 126 | .get("target") |
| 127 | .map(parse_target_mode) |
| 128 | .transpose()? |
| 129 | .unwrap_or(TargetMode::Hosted); |
| 130 | |
| 131 | let mut manifest = match target { |
| 132 | TargetMode::Kernel => Self::kernel(name.clone(), ""), |
| 133 | TargetMode::Hosted | TargetMode::Freestanding => Self::hosted(name.clone(), ""), |
| 134 | }; |
| 135 | manifest.target = target; |
| 136 | manifest.name = name.clone(); |
| 137 | let asm_root = is_asm_path(&root_path.to_string_lossy()); |
| 138 | manifest.root = BuildSource::path(name, root_path); |
| 139 | if asm_root { |
| 140 | manifest.apply_asm_root_defaults(); |
| 141 | } |
| 142 | manifest.entry = values.string("entry"); |
| 143 | manifest.stdlib = values |
| 144 | .get("stdlib") |
| 145 | .map(|value| parse_stdlib_policy(value, target)) |
| 146 | .transpose()? |
| 147 | .unwrap_or(manifest.stdlib); |
| 148 | |
| 149 | if let Some(enabled) = values.bool("import_closure").map_err(manifest_error)? { |
| 150 | manifest.import_closure = if enabled { |
nothing calls this directly
no test coverage detected