diff --git a/sdk/cargo-build-sbf/src/main.rs b/sdk/cargo-build-sbf/src/main.rs index fa9fd92420..70f1f1796a 100644 --- a/sdk/cargo-build-sbf/src/main.rs +++ b/sdk/cargo-build-sbf/src/main.rs @@ -6,6 +6,7 @@ use { solana_download_utils::download_file, solana_sdk::signature::{write_keypair_file, Keypair}, std::{ + borrow::Cow, collections::{HashMap, HashSet}, env, ffi::OsStr, @@ -30,6 +31,7 @@ struct Config<'a> { no_default_features: bool, offline: bool, remap_cwd: bool, + debug: bool, verbose: bool, workspace: bool, jobs: Option, @@ -55,6 +57,7 @@ impl Default for Config<'_> { no_default_features: false, offline: false, remap_cwd: true, + debug: false, verbose: false, workspace: false, jobs: None, @@ -562,10 +565,16 @@ fn build_sbf_package(config: &Config, target_directory: &Path, package: &cargo_m env::set_var("OBJCOPY", llvm_bin.join("llvm-objcopy")); let rustflags = env::var("RUSTFLAGS").ok(); - let rustflags = rustflags.as_deref().unwrap_or_default(); + let mut rustflags = Cow::Borrowed(rustflags.as_deref().unwrap_or_default()); if config.remap_cwd { - let rustflags = format!("{} -Zremap-cwd-prefix=", &rustflags); - env::set_var("RUSTFLAGS", &rustflags); + rustflags = Cow::Owned(format!("{} -Zremap-cwd-prefix=", &rustflags)); + } + if config.debug { + // Replace with -Zsplit-debuginfo=packed when stabilized. + rustflags = Cow::Owned(format!("{} -g", &rustflags)); + } + if let Cow::Owned(flags) = rustflags { + env::set_var("RUSTFLAGS", &flags); } if config.verbose { debug!( @@ -649,6 +658,7 @@ fn build_sbf_package(config: &Config, target_directory: &Path, package: &cargo_m let program_unstripped_so = target_build_directory.join(&format!("{}.so", program_name)); let program_dump = sbf_out_dir.join(&format!("{}-dump.txt", program_name)); let program_so = sbf_out_dir.join(&format!("{}.so", program_name)); + let program_debug = sbf_out_dir.join(&format!("{}.debug", program_name)); let program_keypair = sbf_out_dir.join(&format!("{}-keypair.json", program_name)); fn file_older_or_missing(prerequisite_file: &Path, target_file: &Path) -> bool { @@ -728,6 +738,26 @@ fn build_sbf_package(config: &Config, target_directory: &Path, package: &cargo_m postprocess_dump(&program_dump); } + if config.debug && file_older_or_missing(&program_unstripped_so, &program_debug) { + #[cfg(windows)] + let llvm_objcopy = &llvm_bin.join("llvm-objcopy"); + #[cfg(not(windows))] + let llvm_objcopy = &config.sbf_sdk.join("scripts").join("objcopy.sh"); + + let output = spawn( + llvm_objcopy, + &[ + "--only-keep-debug".as_ref(), + program_unstripped_so.as_os_str(), + program_debug.as_os_str(), + ], + config.generate_child_script_on_failure, + ); + if config.verbose { + debug!("{}", output); + } + } + check_undefined_symbols(config, &program_so); info!("To deploy this program:"); @@ -831,6 +861,12 @@ fn main() { .takes_value(false) .help("Disable remap of cwd prefix and preserve full path strings in binaries"), ) + .arg( + Arg::new("debug") + .long("debug") + .takes_value(false) + .help("Enable debug symbols"), + ) .arg( Arg::new("dump") .long("dump") @@ -933,6 +969,7 @@ fn main() { generate_child_script_on_failure: matches.is_present("generate_child_script_on_failure"), no_default_features: matches.is_present("no_default_features"), remap_cwd: !matches.is_present("remap_cwd"), + debug: matches.is_present("debug"), offline: matches.is_present("offline"), verbose: matches.is_present("verbose"), workspace: matches.is_present("workspace"),