Skip to content

Commit c82ea31

Browse files
authored
Split impl Build (#1382)
1 parent a49184e commit c82ea31

File tree

1 file changed

+142
-138
lines changed

1 file changed

+142
-138
lines changed

src/lib.rs

+142-138
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ impl Object {
410410
}
411411
}
412412

413+
/// Configure the builder.
413414
impl Build {
414415
/// Construct a new instance of a blank set of configuration.
415416
///
@@ -612,144 +613,6 @@ impl Build {
612613
self
613614
}
614615

615-
fn ensure_check_file(&self) -> Result<PathBuf, Error> {
616-
let out_dir = self.get_out_dir()?;
617-
let src = if self.cuda {
618-
assert!(self.cpp);
619-
out_dir.join("flag_check.cu")
620-
} else if self.cpp {
621-
out_dir.join("flag_check.cpp")
622-
} else {
623-
out_dir.join("flag_check.c")
624-
};
625-
626-
if !src.exists() {
627-
let mut f = fs::File::create(&src)?;
628-
write!(f, "int main(void) {{ return 0; }}")?;
629-
}
630-
631-
Ok(src)
632-
}
633-
634-
/// Run the compiler to test if it accepts the given flag.
635-
///
636-
/// For a convenience method for setting flags conditionally,
637-
/// see `flag_if_supported()`.
638-
///
639-
/// It may return error if it's unable to run the compiler with a test file
640-
/// (e.g. the compiler is missing or a write to the `out_dir` failed).
641-
///
642-
/// Note: Once computed, the result of this call is stored in the
643-
/// `known_flag_support` field. If `is_flag_supported(flag)`
644-
/// is called again, the result will be read from the hash table.
645-
pub fn is_flag_supported(&self, flag: impl AsRef<OsStr>) -> Result<bool, Error> {
646-
self.is_flag_supported_inner(
647-
flag.as_ref(),
648-
&self.get_base_compiler()?,
649-
&self.get_target()?,
650-
)
651-
}
652-
653-
fn is_flag_supported_inner(
654-
&self,
655-
flag: &OsStr,
656-
tool: &Tool,
657-
target: &TargetInfo<'_>,
658-
) -> Result<bool, Error> {
659-
let compiler_flag = CompilerFlag {
660-
compiler: tool.path().into(),
661-
flag: flag.into(),
662-
};
663-
664-
if let Some(is_supported) = self
665-
.build_cache
666-
.known_flag_support_status_cache
667-
.read()
668-
.unwrap()
669-
.get(&compiler_flag)
670-
.cloned()
671-
{
672-
return Ok(is_supported);
673-
}
674-
675-
let out_dir = self.get_out_dir()?;
676-
let src = self.ensure_check_file()?;
677-
let obj = out_dir.join("flag_check");
678-
679-
let mut compiler = {
680-
let mut cfg = Build::new();
681-
cfg.flag(flag)
682-
.compiler(tool.path())
683-
.cargo_metadata(self.cargo_output.metadata)
684-
.opt_level(0)
685-
.debug(false)
686-
.cpp(self.cpp)
687-
.cuda(self.cuda)
688-
.inherit_rustflags(false)
689-
.emit_rerun_if_env_changed(self.emit_rerun_if_env_changed);
690-
if let Some(target) = &self.target {
691-
cfg.target(target);
692-
}
693-
if let Some(host) = &self.host {
694-
cfg.host(host);
695-
}
696-
cfg.try_get_compiler()?
697-
};
698-
699-
// Clang uses stderr for verbose output, which yields a false positive
700-
// result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
701-
if compiler.family.verbose_stderr() {
702-
compiler.remove_arg("-v".into());
703-
}
704-
if compiler.is_like_clang() {
705-
// Avoid reporting that the arg is unsupported just because the
706-
// compiler complains that it wasn't used.
707-
compiler.push_cc_arg("-Wno-unused-command-line-argument".into());
708-
}
709-
710-
let mut cmd = compiler.to_command();
711-
let is_arm = matches!(target.arch, "aarch64" | "arm");
712-
let clang = compiler.is_like_clang();
713-
let gnu = compiler.family == ToolFamily::Gnu;
714-
command_add_output_file(
715-
&mut cmd,
716-
&obj,
717-
CmdAddOutputFileArgs {
718-
cuda: self.cuda,
719-
is_assembler_msvc: false,
720-
msvc: compiler.is_like_msvc(),
721-
clang,
722-
gnu,
723-
is_asm: false,
724-
is_arm,
725-
},
726-
);
727-
728-
if compiler.supports_path_delimiter() {
729-
cmd.arg("--");
730-
}
731-
732-
cmd.arg(&src);
733-
734-
// On MSVC skip the CRT by setting the entry point to `main`.
735-
// This way we don't need to add the default library paths.
736-
if compiler.is_like_msvc() {
737-
// Flags from _LINK_ are appended to the linker arguments.
738-
cmd.env("_LINK_", "-entry:main");
739-
}
740-
741-
let output = cmd.output()?;
742-
let is_supported = output.status.success() && output.stderr.is_empty();
743-
744-
self.build_cache
745-
.known_flag_support_status_cache
746-
.write()
747-
.unwrap()
748-
.insert(compiler_flag, is_supported);
749-
750-
Ok(is_supported)
751-
}
752-
753616
/// Add an arbitrary flag to the invocation of the compiler if it supports it
754617
///
755618
/// # Example
@@ -1368,6 +1231,147 @@ impl Build {
13681231
self.env.push((a.as_ref().into(), b.as_ref().into()));
13691232
self
13701233
}
1234+
}
1235+
1236+
/// Invoke or fetch the compiler or archiver.
1237+
impl Build {
1238+
/// Run the compiler to test if it accepts the given flag.
1239+
///
1240+
/// For a convenience method for setting flags conditionally,
1241+
/// see `flag_if_supported()`.
1242+
///
1243+
/// It may return error if it's unable to run the compiler with a test file
1244+
/// (e.g. the compiler is missing or a write to the `out_dir` failed).
1245+
///
1246+
/// Note: Once computed, the result of this call is stored in the
1247+
/// `known_flag_support` field. If `is_flag_supported(flag)`
1248+
/// is called again, the result will be read from the hash table.
1249+
pub fn is_flag_supported(&self, flag: impl AsRef<OsStr>) -> Result<bool, Error> {
1250+
self.is_flag_supported_inner(
1251+
flag.as_ref(),
1252+
&self.get_base_compiler()?,
1253+
&self.get_target()?,
1254+
)
1255+
}
1256+
1257+
fn ensure_check_file(&self) -> Result<PathBuf, Error> {
1258+
let out_dir = self.get_out_dir()?;
1259+
let src = if self.cuda {
1260+
assert!(self.cpp);
1261+
out_dir.join("flag_check.cu")
1262+
} else if self.cpp {
1263+
out_dir.join("flag_check.cpp")
1264+
} else {
1265+
out_dir.join("flag_check.c")
1266+
};
1267+
1268+
if !src.exists() {
1269+
let mut f = fs::File::create(&src)?;
1270+
write!(f, "int main(void) {{ return 0; }}")?;
1271+
}
1272+
1273+
Ok(src)
1274+
}
1275+
1276+
fn is_flag_supported_inner(
1277+
&self,
1278+
flag: &OsStr,
1279+
tool: &Tool,
1280+
target: &TargetInfo<'_>,
1281+
) -> Result<bool, Error> {
1282+
let compiler_flag = CompilerFlag {
1283+
compiler: tool.path().into(),
1284+
flag: flag.into(),
1285+
};
1286+
1287+
if let Some(is_supported) = self
1288+
.build_cache
1289+
.known_flag_support_status_cache
1290+
.read()
1291+
.unwrap()
1292+
.get(&compiler_flag)
1293+
.cloned()
1294+
{
1295+
return Ok(is_supported);
1296+
}
1297+
1298+
let out_dir = self.get_out_dir()?;
1299+
let src = self.ensure_check_file()?;
1300+
let obj = out_dir.join("flag_check");
1301+
1302+
let mut compiler = {
1303+
let mut cfg = Build::new();
1304+
cfg.flag(flag)
1305+
.compiler(tool.path())
1306+
.cargo_metadata(self.cargo_output.metadata)
1307+
.opt_level(0)
1308+
.debug(false)
1309+
.cpp(self.cpp)
1310+
.cuda(self.cuda)
1311+
.inherit_rustflags(false)
1312+
.emit_rerun_if_env_changed(self.emit_rerun_if_env_changed);
1313+
if let Some(target) = &self.target {
1314+
cfg.target(target);
1315+
}
1316+
if let Some(host) = &self.host {
1317+
cfg.host(host);
1318+
}
1319+
cfg.try_get_compiler()?
1320+
};
1321+
1322+
// Clang uses stderr for verbose output, which yields a false positive
1323+
// result if the CFLAGS/CXXFLAGS include -v to aid in debugging.
1324+
if compiler.family.verbose_stderr() {
1325+
compiler.remove_arg("-v".into());
1326+
}
1327+
if compiler.is_like_clang() {
1328+
// Avoid reporting that the arg is unsupported just because the
1329+
// compiler complains that it wasn't used.
1330+
compiler.push_cc_arg("-Wno-unused-command-line-argument".into());
1331+
}
1332+
1333+
let mut cmd = compiler.to_command();
1334+
let is_arm = matches!(target.arch, "aarch64" | "arm");
1335+
let clang = compiler.is_like_clang();
1336+
let gnu = compiler.family == ToolFamily::Gnu;
1337+
command_add_output_file(
1338+
&mut cmd,
1339+
&obj,
1340+
CmdAddOutputFileArgs {
1341+
cuda: self.cuda,
1342+
is_assembler_msvc: false,
1343+
msvc: compiler.is_like_msvc(),
1344+
clang,
1345+
gnu,
1346+
is_asm: false,
1347+
is_arm,
1348+
},
1349+
);
1350+
1351+
if compiler.supports_path_delimiter() {
1352+
cmd.arg("--");
1353+
}
1354+
1355+
cmd.arg(&src);
1356+
1357+
// On MSVC skip the CRT by setting the entry point to `main`.
1358+
// This way we don't need to add the default library paths.
1359+
if compiler.is_like_msvc() {
1360+
// Flags from _LINK_ are appended to the linker arguments.
1361+
cmd.env("_LINK_", "-entry:main");
1362+
}
1363+
1364+
let output = cmd.output()?;
1365+
let is_supported = output.status.success() && output.stderr.is_empty();
1366+
1367+
self.build_cache
1368+
.known_flag_support_status_cache
1369+
.write()
1370+
.unwrap()
1371+
.insert(compiler_flag, is_supported);
1372+
1373+
Ok(is_supported)
1374+
}
13711375

13721376
/// Run the compiler, generating the file `output`
13731377
///

0 commit comments

Comments
 (0)