mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	 80d8270d84
			
		
	
	
		80d8270d84
		
	
	
	
	
		
			
			Update compiler_builtins to 0.1.114 The `weak-intrinsics` feature was removed from compiler_builtins in https://github.com/rust-lang/compiler-builtins/pull/598, so dropped the `compiler-builtins-weak-intrinsics` feature from alloc/std/sysroot. In https://github.com/rust-lang/compiler-builtins/pull/593, some builtins for f16/f128 were added. These don't work for all compiler backends, so add a `compiler-builtins-no-f16-f128` feature and disable it for cranelift and gcc.
		
			
				
	
	
		
			248 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::collections::HashMap;
 | |
| use std::ffi::OsStr;
 | |
| use std::fs;
 | |
| use std::path::Path;
 | |
| 
 | |
| use crate::config::{Channel, ConfigInfo};
 | |
| use crate::utils::{
 | |
|     copy_file, create_dir, get_sysroot_dir, run_command, run_command_with_output_and_env, walk_dir,
 | |
| };
 | |
| 
 | |
| #[derive(Default)]
 | |
| struct BuildArg {
 | |
|     flags: Vec<String>,
 | |
|     config_info: ConfigInfo,
 | |
|     build_sysroot: bool,
 | |
| }
 | |
| 
 | |
| impl BuildArg {
 | |
|     /// Creates a new `BuildArg` instance by parsing command-line arguments.
 | |
|     fn new() -> Result<Option<Self>, String> {
 | |
|         let mut build_arg = Self::default();
 | |
|         // Skip binary name and the `build` command.
 | |
|         let mut args = std::env::args().skip(2);
 | |
| 
 | |
|         while let Some(arg) = args.next() {
 | |
|             match arg.as_str() {
 | |
|                 "--features" => {
 | |
|                     if let Some(arg) = args.next() {
 | |
|                         build_arg.flags.push("--features".to_string());
 | |
|                         build_arg.flags.push(arg.as_str().into());
 | |
|                     } else {
 | |
|                         return Err(
 | |
|                             "Expected a value after `--features`, found nothing".to_string()
 | |
|                         );
 | |
|                     }
 | |
|                 }
 | |
|                 "--sysroot" => {
 | |
|                     build_arg.build_sysroot = true;
 | |
|                 }
 | |
|                 "--help" => {
 | |
|                     Self::usage();
 | |
|                     return Ok(None);
 | |
|                 }
 | |
|                 arg => {
 | |
|                     if !build_arg.config_info.parse_argument(arg, &mut args)? {
 | |
|                         return Err(format!("Unknown argument `{}`", arg));
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         Ok(Some(build_arg))
 | |
|     }
 | |
| 
 | |
|     fn usage() {
 | |
|         println!(
 | |
|             r#"
 | |
| `build` command help:
 | |
| 
 | |
|     --features [arg]       : Add a new feature [arg]
 | |
|     --sysroot              : Build with sysroot"#
 | |
|         );
 | |
|         ConfigInfo::show_usage();
 | |
|         println!("    --help                 : Show this help");
 | |
|     }
 | |
| }
 | |
| 
 | |
| fn cleanup_sysroot_previous_build(start_dir: &Path) {
 | |
|     // Cleanup for previous run
 | |
|     // Clean target dir except for build scripts and incremental cache
 | |
|     let _ = walk_dir(
 | |
|         start_dir.join("target"),
 | |
|         &mut |dir: &Path| {
 | |
|             for top in &["debug", "release"] {
 | |
|                 let _ = fs::remove_dir_all(dir.join(top).join("build"));
 | |
|                 let _ = fs::remove_dir_all(dir.join(top).join("deps"));
 | |
|                 let _ = fs::remove_dir_all(dir.join(top).join("examples"));
 | |
|                 let _ = fs::remove_dir_all(dir.join(top).join("native"));
 | |
| 
 | |
|                 let _ = walk_dir(
 | |
|                     dir.join(top),
 | |
|                     &mut |sub_dir: &Path| {
 | |
|                         if sub_dir
 | |
|                             .file_name()
 | |
|                             .map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
 | |
|                             .unwrap_or(false)
 | |
|                         {
 | |
|                             let _ = fs::remove_dir_all(sub_dir);
 | |
|                         }
 | |
|                         Ok(())
 | |
|                     },
 | |
|                     &mut |file: &Path| {
 | |
|                         if file
 | |
|                             .file_name()
 | |
|                             .map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
 | |
|                             .unwrap_or(false)
 | |
|                         {
 | |
|                             let _ = fs::remove_file(file);
 | |
|                         }
 | |
|                         Ok(())
 | |
|                     },
 | |
|                     false,
 | |
|                 );
 | |
|             }
 | |
|             Ok(())
 | |
|         },
 | |
|         &mut |_| Ok(()),
 | |
|         false,
 | |
|     );
 | |
| 
 | |
|     let _ = fs::remove_file(start_dir.join("Cargo.lock"));
 | |
|     let _ = fs::remove_file(start_dir.join("test_target/Cargo.lock"));
 | |
|     let _ = fs::remove_dir_all(start_dir.join("sysroot"));
 | |
| }
 | |
| 
 | |
| pub fn create_build_sysroot_content(start_dir: &Path) -> Result<(), String> {
 | |
|     if !start_dir.is_dir() {
 | |
|         create_dir(start_dir)?;
 | |
|     }
 | |
|     copy_file("build_system/build_sysroot/Cargo.toml", &start_dir.join("Cargo.toml"))?;
 | |
|     copy_file("build_system/build_sysroot/Cargo.lock", &start_dir.join("Cargo.lock"))?;
 | |
| 
 | |
|     let src_dir = start_dir.join("src");
 | |
|     if !src_dir.is_dir() {
 | |
|         create_dir(&src_dir)?;
 | |
|     }
 | |
|     copy_file("build_system/build_sysroot/lib.rs", &start_dir.join("src/lib.rs"))
 | |
| }
 | |
| 
 | |
| pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Result<(), String> {
 | |
|     let start_dir = get_sysroot_dir();
 | |
| 
 | |
|     cleanup_sysroot_previous_build(&start_dir);
 | |
|     create_build_sysroot_content(&start_dir)?;
 | |
| 
 | |
|     // Builds libs
 | |
|     let mut rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default();
 | |
|     if config.sysroot_panic_abort {
 | |
|         rustflags.push_str(" -Cpanic=abort -Zpanic-abort-tests");
 | |
|     }
 | |
|     rustflags.push_str(" -Z force-unstable-if-unmarked");
 | |
|     if config.no_default_features {
 | |
|         rustflags.push_str(" -Csymbol-mangling-version=v0");
 | |
|     }
 | |
| 
 | |
|     let mut args: Vec<&dyn AsRef<OsStr>> = vec![
 | |
|         &"cargo",
 | |
|         &"build",
 | |
|         &"--target",
 | |
|         &config.target,
 | |
|         &"--features",
 | |
|         &"compiler-builtins-no-f16-f128",
 | |
|     ];
 | |
| 
 | |
|     if config.no_default_features {
 | |
|         rustflags.push_str(" -Csymbol-mangling-version=v0");
 | |
|         args.push(&"--no-default-features");
 | |
|     }
 | |
| 
 | |
|     let channel = if config.sysroot_release_channel {
 | |
|         rustflags.push_str(" -Zmir-opt-level=3");
 | |
|         args.push(&"--release");
 | |
|         "release"
 | |
|     } else {
 | |
|         "debug"
 | |
|     };
 | |
| 
 | |
|     if let Ok(cg_rustflags) = std::env::var("CG_RUSTFLAGS") {
 | |
|         rustflags.push(' ');
 | |
|         rustflags.push_str(&cg_rustflags);
 | |
|     }
 | |
| 
 | |
|     let mut env = env.clone();
 | |
|     env.insert("RUSTFLAGS".to_string(), rustflags);
 | |
|     run_command_with_output_and_env(&args, Some(&start_dir), Some(&env))?;
 | |
| 
 | |
|     // Copy files to sysroot
 | |
|     let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple));
 | |
|     create_dir(&sysroot_path)?;
 | |
|     let mut copier = |dir_to_copy: &Path| {
 | |
|         // FIXME: should not use shell command!
 | |
|         run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ())
 | |
|     };
 | |
|     walk_dir(
 | |
|         start_dir.join(&format!("target/{}/{}/deps", config.target_triple, channel)),
 | |
|         &mut copier.clone(),
 | |
|         &mut copier,
 | |
|         false,
 | |
|     )?;
 | |
| 
 | |
|     // Copy the source files to the sysroot (Rust for Linux needs this).
 | |
|     let sysroot_src_path = start_dir.join("sysroot/lib/rustlib/src/rust");
 | |
|     create_dir(&sysroot_src_path)?;
 | |
|     run_command(&[&"cp", &"-r", &start_dir.join("sysroot_src/library/"), &sysroot_src_path], None)?;
 | |
| 
 | |
|     Ok(())
 | |
| }
 | |
| 
 | |
| fn build_codegen(args: &mut BuildArg) -> Result<(), String> {
 | |
|     let mut env = HashMap::new();
 | |
| 
 | |
|     env.insert("LD_LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
 | |
|     env.insert("LIBRARY_PATH".to_string(), args.config_info.gcc_path.clone());
 | |
| 
 | |
|     if args.config_info.no_default_features {
 | |
|         env.insert("RUSTFLAGS".to_string(), "-Csymbol-mangling-version=v0".to_string());
 | |
|     }
 | |
| 
 | |
|     let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"rustc"];
 | |
|     if args.config_info.channel == Channel::Release {
 | |
|         command.push(&"--release");
 | |
|         env.insert("CHANNEL".to_string(), "release".to_string());
 | |
|         env.insert("CARGO_INCREMENTAL".to_string(), "1".to_string());
 | |
|     } else {
 | |
|         env.insert("CHANNEL".to_string(), "debug".to_string());
 | |
|     }
 | |
|     if args.config_info.no_default_features {
 | |
|         command.push(&"--no-default-features");
 | |
|     }
 | |
|     let flags = args.flags.iter().map(|s| s.as_str()).collect::<Vec<_>>();
 | |
|     for flag in &flags {
 | |
|         command.push(flag);
 | |
|     }
 | |
|     run_command_with_output_and_env(&command, None, Some(&env))?;
 | |
| 
 | |
|     args.config_info.setup(&mut env, false)?;
 | |
| 
 | |
|     // We voluntarily ignore the error.
 | |
|     let _ = fs::remove_dir_all("target/out");
 | |
|     let gccjit_target = "target/out/gccjit";
 | |
|     create_dir(gccjit_target)?;
 | |
|     if args.build_sysroot {
 | |
|         println!("[BUILD] sysroot");
 | |
|         build_sysroot(&env, &args.config_info)?;
 | |
|     }
 | |
|     Ok(())
 | |
| }
 | |
| 
 | |
| /// Executes the build process.
 | |
| pub fn run() -> Result<(), String> {
 | |
|     let mut args = match BuildArg::new()? {
 | |
|         Some(args) => args,
 | |
|         None => return Ok(()),
 | |
|     };
 | |
|     args.config_info.setup_gcc_path()?;
 | |
|     build_codegen(&mut args)?;
 | |
|     Ok(())
 | |
| }
 |