Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cargo-c for openSUSE:Factory checked in at 2021-04-08 21:02:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cargo-c (Old) and /work/SRC/openSUSE:Factory/.cargo-c.new.2401 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cargo-c" Thu Apr 8 21:02:06 2021 rev:8 rq:883123 version:0.8.0 Changes: -------- --- /work/SRC/openSUSE:Factory/cargo-c/cargo-c.changes 2021-01-18 11:30:12.688331722 +0100 +++ /work/SRC/openSUSE:Factory/.cargo-c.new.2401/cargo-c.changes 2021-04-08 21:02:27.169919256 +0200 @@ -1,0 +2,14 @@ +Tue Apr 6 02:21:28 UTC 2021 - William Brown <william.br...@suse.com> + +- Add README.suse-maint to fix OBS warning. + +------------------------------------------------------------------- +Mon Apr 5 07:52:23 UTC 2021 - Antonio Larrosa <alarr...@suse.com> + +- Update to version 0.8.0 + * cbindgen 0.18 + * provide a cli option to have fully static builds. + * cargo cinstall and cargo capi install now imply --release + to match the behavior of cargo install. + +------------------------------------------------------------------- Old: ---- cargo-c-0.7.0.tar.gz New: ---- README.suse-maint cargo-c-0.8.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cargo-c.spec ++++++ --- /var/tmp/diff_new_pack.Kseaa2/_old 2021-04-08 21:02:28.425920613 +0200 +++ /var/tmp/diff_new_pack.Kseaa2/_new 2021-04-08 21:02:28.429920617 +0200 @@ -18,7 +18,7 @@ Name: cargo-c -Version: 0.7.0 +Version: 0.8.0 Release: 0 Summary: Helper to build and install c-like libraries from Rust License: MIT @@ -29,6 +29,7 @@ Source0: https://github.com/lu-zero/cargo-c/archive/v%{version}/%{name}-%{version}.tar.gz Source1: vendor.tar.xz # +Source1000: README.suse-maint BuildRequires: rust-packaging BuildRequires: pkgconfig(openssl) ++++++ README.suse-maint ++++++ # How to update the cargo-c package ## Prerequisites: You need the download_files and cargo_vendor obs services installed: zypper in obs-service-download_files obs-service-cargo_vendor ## Updating to a new version from upstream Edit the spec file and update the version variable. Download the new source file by running: osc service ra download_files Uncompress the cargo-c-%{version}.tar.gz file: tar xvfz cargo-c-%{version}.tar.gz This will create a cargo-c-%{version} directory Edit the _service file and set the srcdir param to the extracted directory. Run the cargo_vendor service with: osc service disabledrun Update the changelog file with the upstream release notes. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Kseaa2/_old 2021-04-08 21:02:28.513920708 +0200 +++ /var/tmp/diff_new_pack.Kseaa2/_new 2021-04-08 21:02:28.517920712 +0200 @@ -1,4 +1,5 @@ <services> <service name="cargo_vendor" mode="disabled"> + <param name="srcdir">cargo-c-0.8.0</param> </service> </services> ++++++ cargo-c-0.7.0.tar.gz -> cargo-c-0.8.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/.github/actions-rs/grcov.yml new/cargo-c-0.8.0/.github/actions-rs/grcov.yml --- old/cargo-c-0.7.0/.github/actions-rs/grcov.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/cargo-c-0.8.0/.github/actions-rs/grcov.yml 2021-04-02 15:52:04.000000000 +0200 @@ -0,0 +1,4 @@ +ignore-not-existing: true +ignore: + - "/*" + - "../*" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/.github/workflows/example-project.yml new/cargo-c-0.8.0/.github/workflows/example-project.yml --- old/cargo-c-0.7.0/.github/workflows/example-project.yml 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/.github/workflows/example-project.yml 2021-04-02 15:52:04.000000000 +0200 @@ -36,13 +36,6 @@ run: | cargo install --path . - - name: Set MSVC binaries path - if: matrix.toolchain-suffix == '-msvc' - run: | - $BinGlob = "VC\Tools\MSVC\*\bin\Hostx64\x64" - $BinPath = vswhere -latest -products * -find "$BinGlob" | Select-Object -Last 1 - echo "$BinPath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Test example project working-directory: example-project run: | diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/.github/workflows/rust.yml new/cargo-c-0.8.0/.github/workflows/rust.yml --- old/cargo-c-0.7.0/.github/workflows/rust.yml 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/.github/workflows/rust.yml 2021-04-02 15:52:04.000000000 +0200 @@ -46,7 +46,7 @@ - name: Install grcov env: LINK: https://github.com/mozilla/grcov/releases/download - GRCOV_VERSION: 0.5.15 + GRCOV_VERSION: 0.7.1 run: | curl -L "$LINK/v$GRCOV_VERSION/grcov-linux-x86_64.tar.bz2" | tar xj -C $HOME/.cargo/bin @@ -57,6 +57,7 @@ profile: minimal toolchain: nightly override: true + components: llvm-tools-preview - name: Run cargo clean run: | @@ -66,23 +67,26 @@ env: CARGO_INCREMENTAL: 0 RUSTFLAGS: > - -Zprofile -Ccodegen-units=1 -Clink-dead-code -Coverflow-checks=off - -Cpanic=abort -Zpanic_abort_tests + -Zinstrument-coverage RUSTDOCFLAGS: > - -Zprofile -Ccodegen-units=1 -Clink-dead-code -Coverflow-checks=off - -Cpanic=abort -Zpanic_abort_tests + -Zinstrument-coverage run: | + cargo build cargo test --no-fail-fast --verbose + cargo run --bin cargo-cbuild -- cbuild --manifest-path=example-project/Cargo.toml + cargo run --bin cargo-cinstall -- cinstall --manifest-path=example-project/Cargo.toml --destdir=/tmp/install + cargo run --bin cargo-ctest -- ctest --manifest-path=example-project/Cargo.toml + cargo run --bin cargo-capi -- capi - name: Run grcov id: coverage - uses: actions-rs/grcov@v0.1 + run: grcov . --binary-path target/debug/deps/ -s . -t lcov --branch --ignore-not-existing --ignore '../**' --ignore '/*' -o coverage.lcov - name: Coveralls upload uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: ${{ steps.coverage.outputs.report }} + path-to-lcov: coverage.lcov Ubuntu-Stable: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/Cargo.toml new/cargo-c-0.8.0/Cargo.toml --- old/cargo-c-0.7.0/Cargo.toml 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/Cargo.toml 2021-04-02 15:52:04.000000000 +0200 @@ -1,6 +1,6 @@ [package] name = "cargo-c" -version = "0.7.0+cargo-0.49" +version = "0.8.0+cargo-0.51" authors = ["Luca Barbato <lu_z...@gentoo.org>"] description = "Helper program to build and install c-like libraries" license = "MIT" @@ -27,16 +27,18 @@ path = "src/bin/ctest.rs" [dependencies] -cargo = "0.49" +cargo = "0.51" semver = "0.10" log = "0.4" structopt = "0.3" regex = "1" -cbindgen = "0.16" +cbindgen = "0.18" toml = "0.5" -serde = "1.0" +serde = "1.0.123" serde_derive = "1.0" +serde_json = "1.0.62" anyhow = "1.0" +cc = "1.0" [features] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/README.md new/cargo-c-0.8.0/README.md --- old/cargo-c-0.7.0/README.md 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/README.md 2021-04-02 15:52:04.000000000 +0200 @@ -34,7 +34,7 @@ ``` ``` sh # build the library, create the .h header, create the .pc file, build and run the tests -$ cargo ctest +$ cargo ctest ``` ``` sh # build the library, create the .h header, create the .pc file and install all of it @@ -52,7 +52,7 @@ the first member is the crate you want to export, that means that you might have [to add a "." member at the start of the list][diff-3]. - ~~Since Rust 1.38, also add "staticlib" to the "lib" `crate-type`.~~ Do not specify the `crate-type`, cargo-c will add the correct library target by itself. -- You may use the feature `capi` to add C-API-specific optional dependencies. +- You may use the feature `capi` to add C-API-specific optional dependencies. > **NOTE**: It must be always present in `Cargo.toml` - Remember to [add][diff-4] a [`cbindgen.toml`][cbindgen-toml] and fill it with at least the include guard and probably you want to set the language to C (it @@ -154,3 +154,11 @@ [dev.to]: https://dev.to/luzero/building-crates-so-they-look-like-c-abi-libraries-1ibn [using]: https://dev.to/luzero/building-crates-so-they-look-like-c-abi-libraries-1ibn#using-cargoc + +## Sponsors + +- [@Darkspirit](https://github.com/Darkspirit) is sponsored [@lu-zero](https://github.com/lu-zero). + +## Acknowledgements + +This software has been partially developed in the scope of the H2020 project SIFIS-Home with GA n. 952652. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/bin/capi.rs new/cargo-c-0.8.0/src/bin/capi.rs --- old/cargo-c-0.7.0/src/bin/capi.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/bin/capi.rs 2021-04-02 15:52:04.000000000 +0200 @@ -12,8 +12,8 @@ fn main() -> CliResult { let mut config = Config::default()?; - let cli_build = subcommand_cli("build", "Build the crate C-API"); - let cli_install = subcommand_cli("install", "Install the crate C-API"); + let cli_build = subcommand_build("build", "Build the crate C-API"); + let cli_install = subcommand_install("install", "Install the crate C-API"); let cli_test = subcommand_test("test"); let mut app = app_from_crate!() @@ -33,9 +33,11 @@ let args = app.clone().get_matches(); - let (cmd, subcommand_args) = match args.subcommand() { + let (cmd, subcommand_args, default_profile) = match args.subcommand() { ("capi", Some(args)) => match args.subcommand() { - (cmd, Some(args)) if cmd == "build" || cmd == "install" || cmd == "test" => (cmd, args), + ("build", Some(args)) => ("build", args, "dev"), + ("test", Some(args)) => ("test", args, "dev"), + ("install", Some(args)) => ("install", args, "release"), _ => { // No subcommand provided. app.print_help()?; @@ -58,7 +60,7 @@ let mut ws = subcommand_args.workspace(&config)?; let (build_targets, install_paths, capi_config, static_libs, compile_opts) = - cbuild(&mut ws, &config, &subcommand_args)?; + cbuild(&mut ws, &config, &subcommand_args, default_profile)?; if cmd == "install" { cinstall(&ws, &capi_config, build_targets, install_paths)?; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/bin/cbuild.rs new/cargo-c-0.8.0/src/bin/cbuild.rs --- old/cargo-c-0.7.0/src/bin/cbuild.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/bin/cbuild.rs 2021-04-02 15:52:04.000000000 +0200 @@ -3,14 +3,14 @@ use cargo::Config; use cargo_c::build::*; -use cargo_c::cli::subcommand_cli; +use cargo_c::cli::subcommand_build; use structopt::clap::*; fn main() -> CliResult { let mut config = Config::default()?; - let subcommand = subcommand_cli("cbuild", "Build the crate C-API"); + let subcommand = subcommand_build("cbuild", "Build the crate C-API"); let mut app = app_from_crate!() .settings(&[ @@ -40,7 +40,7 @@ let mut ws = subcommand_args.workspace(&config)?; - let _ = cbuild(&mut ws, &config, &subcommand_args)?; + let _ = cbuild(&mut ws, &config, &subcommand_args, "dev")?; Ok(()) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/bin/cinstall.rs new/cargo-c-0.8.0/src/bin/cinstall.rs --- old/cargo-c-0.7.0/src/bin/cinstall.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/bin/cinstall.rs 2021-04-02 15:52:04.000000000 +0200 @@ -3,7 +3,7 @@ use cargo::Config; use cargo_c::build::{cbuild, config_configure}; -use cargo_c::cli::subcommand_cli; +use cargo_c::cli::subcommand_install; use cargo_c::install::cinstall; use structopt::clap::*; @@ -11,7 +11,7 @@ fn main() -> CliResult { let mut config = Config::default()?; - let subcommand = subcommand_cli("cinstall", "Install the crate C-API"); + let subcommand = subcommand_install("cinstall", "Install the crate C-API"); let mut app = app_from_crate!() .settings(&[ AppSettings::UnifiedHelpMessage, @@ -41,7 +41,7 @@ let mut ws = subcommand_args.workspace(&config)?; let (build_targets, install_paths, capi_config, _, _) = - cbuild(&mut ws, &config, &subcommand_args)?; + cbuild(&mut ws, &config, &subcommand_args, "release")?; cinstall(&ws, &capi_config, build_targets, install_paths)?; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/bin/ctest.rs new/cargo-c-0.8.0/src/bin/ctest.rs --- old/cargo-c-0.7.0/src/bin/ctest.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/bin/ctest.rs 2021-04-02 15:52:04.000000000 +0200 @@ -41,7 +41,7 @@ let mut ws = subcommand_args.workspace(&config)?; let (build_targets, _, _, static_libs, compile_opts) = - cbuild(&mut ws, &config, &subcommand_args)?; + cbuild(&mut ws, &config, &subcommand_args, "dev")?; ctest( &ws, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/build.rs new/cargo-c-0.8.0/src/build.rs --- old/cargo-c-0.7.0/src/build.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/build.rs 2021-04-02 15:52:04.000000000 +0200 @@ -1,8 +1,10 @@ use std::fs::File; use std::io::{BufRead, BufReader, Read, Write}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; -use cargo::core::profiles::Profiles; +use cargo::core::{compiler::Executor, profiles::Profiles}; use cargo::core::{TargetKind, Workspace}; use cargo::ops::{self, CompileFilter, CompileOptions, FilterRule, LibRule}; use cargo::util::command_prelude::{ArgMatches, ArgMatchesExt, CompileMode, ProfileChecking}; @@ -15,7 +17,6 @@ use crate::build_targets::BuildTargets; use crate::install::{InstallPaths, LibType, UnixLibNames}; use crate::pkg_config_gen::PkgConfig; -use crate::static_libs::get_static_libs_for_target; use crate::target; /// Build the C header @@ -23,8 +24,8 @@ ws: &Workspace, name: &str, version: &Version, - root_output: &PathBuf, - root_path: &PathBuf, + root_output: &Path, + root_path: &Path, ) -> anyhow::Result<()> { ws.config() .shell() @@ -59,8 +60,8 @@ fn copy_prebuilt_include_file( ws: &Workspace, name: &str, - root_output: &PathBuf, - root_path: &PathBuf, + root_output: &Path, + root_path: &Path, ) -> anyhow::Result<()> { ws.config() .shell() @@ -76,13 +77,7 @@ Ok(()) } -fn build_pc_file( - ws: &Workspace, - name: &str, - root_output: &PathBuf, - pc: &PkgConfig, -) -> anyhow::Result<()> { - ws.config().shell().status("Building", "pkg-config file")?; +fn build_pc_file(name: &str, root_output: &Path, pc: &PkgConfig) -> anyhow::Result<()> { let pc_path = root_output.join(&format!("{}.pc", name)); let mut out = std::fs::File::create(pc_path)?; @@ -94,7 +89,27 @@ Ok(()) } -fn patch_lib_kind_in_target(ws: &mut Workspace, libkinds: &[&str]) -> anyhow::Result<()> { +fn build_pc_files( + ws: &Workspace, + name: &str, + root_output: &Path, + pc: &PkgConfig, +) -> anyhow::Result<()> { + ws.config().shell().status("Building", "pkg-config files")?; + build_pc_file(name, root_output, pc)?; + let pc_uninstalled = pc.uninstalled(&root_output); + build_pc_file( + &format!("{}-uninstalled", name), + root_output, + &pc_uninstalled, + ) +} + +fn patch_target( + ws: &mut Workspace, + libkinds: &[&str], + capi_config: &CApiConfig, +) -> anyhow::Result<()> { use cargo::core::compiler::CrateType; let pkg = ws.current_mut()?; @@ -115,6 +130,7 @@ for target in targets.iter_mut() { if target.is_lib() { target.set_kind(TargetKind::Lib(kinds.clone())); + target.set_name(&capi_config.library.name); } } @@ -137,7 +153,7 @@ ws: &Workspace, name: &str, target: &target::Target, - targetdir: &PathBuf, + targetdir: &Path, ) -> anyhow::Result<()> { let os = &target.os; let env = &target.env; @@ -148,7 +164,13 @@ .status("Building", ".def file using dumpbin")?; let txt_path = targetdir.join(format!("{}.txt", name)); - let mut dumpbin = std::process::Command::new("dumpbin"); + + let target_str = format!("{}-pc-windows-msvc", &target.arch); + let mut dumpbin = match cc::windows_registry::find(&target_str, "dumpbin.exe") { + Some(command) => command, + None => std::process::Command::new("dumpbin"), + }; + dumpbin .arg("/EXPORTS") .arg(targetdir.join(format!("{}.dll", name))); @@ -201,8 +223,8 @@ ws: &Workspace, name: &str, target: &target::Target, - targetdir: &PathBuf, - dlltool: &PathBuf, + targetdir: &Path, + dlltool: &Path, ) -> anyhow::Result<()> { let os = &target.os; let env = &target.env; @@ -243,15 +265,22 @@ struct FingerPrint<'a> { name: &'a str, - root_output: &'a PathBuf, + root_output: &'a Path, build_targets: &'a BuildTargets, install_paths: &'a InstallPaths, + static_libs: &'a str, +} + +#[derive(serde::Serialize, serde::Deserialize)] +struct Cache { + hash: u64, + static_libs: String, } impl<'a> FingerPrint<'a> { fn new( name: &'a str, - root_output: &'a PathBuf, + root_output: &'a Path, build_targets: &'a BuildTargets, install_paths: &'a InstallPaths, ) -> Self { @@ -260,6 +289,7 @@ root_output, build_targets, install_paths, + static_libs: "", } } @@ -298,25 +328,32 @@ .join(format!("cargo-c-{}.cache", self.name)) } - fn load_previous(&self) -> anyhow::Result<u64> { + fn load_previous(&self) -> anyhow::Result<Cache> { let mut f = std::fs::File::open(&self.path())?; - let mut buf = [0; 8]; - f.read_exact(&mut buf)?; + let mut cache_str = String::new(); + f.read_to_string(&mut cache_str)?; + let cache = toml::de::from_str(&cache_str)?; - Ok(u64::from_le_bytes(buf)) + Ok(cache) } fn is_valid(&self) -> bool { match (self.load_previous(), self.hash()) { - (Ok(prev), Ok(Some(current))) => prev == current, + (Ok(prev), Ok(Some(current))) => prev.hash == current, _ => false, } } fn store(&self) -> anyhow::Result<()> { let mut f = std::fs::File::create(&self.path())?; + if let Some(hash) = self.hash()? { - f.write_all(&hash.to_le_bytes())?; + let cache = Cache { + hash, + static_libs: self.static_libs.to_owned(), + }; + let buf = toml::ser::to_vec(&cache)?; + f.write_all(&buf)?; } Ok(()) @@ -353,7 +390,7 @@ fn load_manifest_capi_config( name: &str, - root_path: &PathBuf, + root_path: &Path, ws: &Workspace, ) -> anyhow::Result<CApiConfig> { let mut manifest = std::fs::File::open(root_path.join("Cargo.toml"))?; @@ -494,15 +531,20 @@ }) } -pub fn compile_options( +fn compile_options( ws: &Workspace, config: &Config, args: &ArgMatches<'_>, + default_profile: &str, compile_mode: CompileMode, ) -> anyhow::Result<CompileOptions> { + use cargo::core::compiler::CompileKind; let mut compile_opts = args.compile_options(config, compile_mode, Some(ws), ProfileChecking::Checked)?; + compile_opts.build_config.requested_profile = + args.get_profile_name(config, default_profile, ProfileChecking::Checked)?; + patch_capi_feature(&mut compile_opts, ws)?; compile_opts.filter = CompileFilter::new( @@ -513,13 +555,78 @@ FilterRule::none(), ); + compile_opts.build_config.unit_graph = false; + + let rustc = config.load_global_rustc(Some(ws))?; + + // Always set the target, requested_kinds is a vec of a single element. + if compile_opts.build_config.requested_kinds[0].is_host() { + compile_opts.build_config.requested_kinds = + CompileKind::from_requested_targets(config, &[rustc.host.to_string()])? + } + Ok(compile_opts) } +#[derive(Default)] +struct Exec { + ran: AtomicBool, + link_line: Mutex<String>, +} + +use cargo::core::*; +use cargo::util::ProcessBuilder; +use cargo::CargoResult; + +impl Executor for Exec { + fn exec( + &self, + cmd: &ProcessBuilder, + _id: PackageId, + _target: &Target, + _mode: CompileMode, + on_stdout_line: &mut dyn FnMut(&str) -> CargoResult<()>, + on_stderr_line: &mut dyn FnMut(&str) -> CargoResult<()>, + ) -> CargoResult<()> { + self.ran.store(true, Ordering::Relaxed); + cmd.exec_with_streaming( + on_stdout_line, + &mut |s| { + #[derive(serde::Deserialize, Debug)] + struct Message { + message: String, + level: String, + } + + if let Ok(msg) = serde_json::from_str::<Message>(s) { + // suppress the native-static-libs messages + if msg.level == "note" { + if msg.message.starts_with("Link against the following native artifacts when linking against this static library") { + Ok(()) + } else if let Some(link_line) = msg.message.strip_prefix("native-static-libs:") { + *self.link_line.lock().unwrap() = link_line.to_string(); + Ok(()) + } else { + on_stderr_line(s) + } + } else { + on_stderr_line(s) + } + } else { + on_stderr_line(s) + } + }, + false, + ) + .map(drop) + } +} + pub fn cbuild( ws: &mut Workspace, config: &Config, args: &ArgMatches<'_>, + default_profile: &str, ) -> anyhow::Result<( BuildTargets, InstallPaths, @@ -527,23 +634,26 @@ String, CompileOptions, )> { + let rustc = config.load_global_rustc(Some(ws))?; let targets = args.targets(); let target = match targets.len() { - 0 => None, - 1 => Some(targets[0].clone()), + 0 => rustc.host.to_string(), + 1 => targets[0].to_string(), _ => { anyhow::bail!("Multiple targets not supported yet"); } }; - let rustc_target = target::Target::new(target.as_ref())?; - let libkinds = args - .values_of("library-type") - .map_or_else(|| vec!["staticlib", "cdylib"], |v| v.collect::<Vec<_>>()); + let rustc_target = target::Target::new(&target)?; + let libkinds = args.values_of("library-type").map_or_else( + || match (rustc_target.os.as_str(), rustc_target.env.as_str()) { + ("none", _) | (_, "musl") => vec!["staticlib"], + _ => vec!["staticlib", "cdylib"], + }, + |v| v.collect::<Vec<_>>(), + ); let only_staticlib = !libkinds.contains(&"cdylib"); - patch_lib_kind_in_target(ws, &libkinds)?; - let name = &ws .current()? .manifest() @@ -556,27 +666,19 @@ let root_path = ws.current()?.root().to_path_buf(); let capi_config = load_manifest_capi_config(name, &root_path, &ws)?; - let install_paths = InstallPaths::new(name, args, &capi_config); + patch_target(ws, &libkinds, &capi_config)?; - let mut pc = PkgConfig::from_workspace(name, &install_paths, args, &capi_config); + let name = &capi_config.library.name; - let static_libs = get_static_libs_for_target( - rustc_target.verbatim.as_ref(), - &ws.target_dir().as_path_unlocked().to_path_buf(), - )?; - - if only_staticlib { - pc.add_lib(&static_libs); - } - pc.add_lib_private(&static_libs); + let install_paths = InstallPaths::new(name, args, &capi_config); - let mut compile_opts = compile_options(ws, config, args, CompileMode::Build)?; + let mut compile_opts = compile_options(ws, config, args, default_profile, CompileMode::Build)?; let profiles = Profiles::new( ws.profiles(), config, compile_opts.build_config.requested_profile, - ws.features(), + ws.unstable_features(), )?; // TODO: there must be a simpler way to get the right path. @@ -584,41 +686,63 @@ .target_dir() .as_path_unlocked() .to_path_buf() - .join( - target - .map(PathBuf::from) - .unwrap_or_else(|| PathBuf::from(".")), - ) + .join(PathBuf::from(target)) .join(&profiles.get_dir_name()); - let mut link_args: Vec<String> = rustc_target + let mut rustc_args: Vec<String> = rustc_target .shared_object_link_args(&capi_config, &install_paths.libdir, &root_output) .into_iter() .flat_map(|l| vec!["-C".to_string(), format!("link-arg={}", l)]) .collect(); - link_args.push("--cfg".into()); - link_args.push("cargo_c".into()); + rustc_args.push("--cfg".into()); + rustc_args.push("cargo_c".into()); - compile_opts.target_rustc_args = Some(link_args); + rustc_args.push("--print".into()); + rustc_args.push("native-static-libs".into()); + + if args.is_present("crt-static") { + rustc_args.push("-C".into()); + rustc_args.push("target-feature=+crt-static".into()); + } + + compile_opts.target_rustc_args = Some(rustc_args); let build_targets = BuildTargets::new(&name, &rustc_target, &root_output, &libkinds, &capi_config); - // TODO: check the root_output - let _r = ops::compile(ws, &compile_opts)?; + let mut finger_print = FingerPrint::new(&name, &root_output, &build_targets, &install_paths); - let finger_print = FingerPrint::new(&name, &root_output, &build_targets, &install_paths); + let pristine = finger_print.load_previous().is_err(); - if !finger_print.is_valid() { - build_pc_file(&ws, &name, &root_output, &pc)?; - let pc_uninstalled = pc.uninstalled(&root_output); - build_pc_file( - &ws, - &format!("{}-uninstalled", name), - &root_output, - &pc_uninstalled, - )?; + if pristine { + // If the cache is somehow missing force a full rebuild; + compile_opts.build_config.force_rebuild = true; + } + + let exec = Arc::new(Exec::default()); + let _r = ops::compile_with_exec(ws, &compile_opts, &(exec.clone() as Arc<dyn Executor>))?; + + if pristine { + // restore the default to make sure the tests do not trigger a second rebuild. + compile_opts.build_config.force_rebuild = false; + } + + let new_build = exec.ran.load(Ordering::Relaxed); + let mut static_libs = exec.link_line.lock().unwrap().clone(); + + // it is a new build, build the additional files and update update the cache + // if the hash value does not match. + if new_build && !finger_print.is_valid() { + finger_print.static_libs = &static_libs; + + let mut pc = PkgConfig::from_workspace(name, &install_paths, args, &capi_config); + if only_staticlib { + pc.add_lib(&static_libs); + } + pc.add_lib_private(&static_libs); + + build_pc_files(&ws, &name, &root_output, &pc)?; if !only_staticlib { build_def_file(&ws, &name, &rustc_target, &root_output)?; @@ -657,6 +781,9 @@ } finger_print.store()?; + } else { + // It is not a new build, recover the static_libs value from the cache + static_libs = finger_print.load_previous()?.static_libs; } Ok(( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/build_targets.rs new/cargo-c-0.8.0/src/build_targets.rs --- old/cargo-c-0.7.0/src/build_targets.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/build_targets.rs 2021-04-02 15:52:04.000000000 +0200 @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use crate::build::CApiConfig; use crate::target::Target; @@ -18,7 +18,7 @@ pub fn new( name: &str, target: &Target, - targetdir: &PathBuf, + targetdir: &Path, libkinds: &[&str], capi_config: &CApiConfig, ) -> BuildTargets { @@ -31,13 +31,18 @@ None }; - let lib_name = &capi_config.library.name; + let lib_name = name; let os = &target.os; let env = &target.env; let (shared_lib, static_lib, impl_lib, def) = match (os.as_str(), env.as_str()) { - ("linux", _) | ("freebsd", _) | ("dragonfly", _) | ("netbsd", _) | ("android", _) => { + ("none", _) + | ("linux", _) + | ("freebsd", _) + | ("dragonfly", _) + | ("netbsd", _) + | ("android", _) => { let static_lib = targetdir.join(&format!("lib{}.a", lib_name)); let shared_lib = targetdir.join(&format!("lib{}.so", lib_name)); (shared_lib, static_lib, None, None) @@ -70,7 +75,9 @@ } else { None }; - let shared_lib = if libkinds.contains(&"cdylib") { + + // Bare metal does not support shared objects + let shared_lib = if libkinds.contains(&"cdylib") && os.as_str() != "none" { Some(shared_lib) } else { None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/cli.rs new/cargo-c-0.8.0/src/cli.rs --- old/cargo-c-0.7.0/src/cli.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/cli.rs 2021-04-02 15:52:04.000000000 +0200 @@ -31,6 +31,9 @@ #[structopt(long = "dlltool", parse(from_os_str))] /// Use the provided dlltool when building for the windows-gnu targets. dlltool: Option<PathBuf>, + #[structopt(long = "crt-static")] + /// Build the library embedding the C runtime + crt_static: bool, } fn base_cli() -> App<'static, 'static> { @@ -60,7 +63,6 @@ .hidden(true), ) .arg_jobs() - .arg_release("Build artifacts in release mode, with optimizations") .arg_profile("Build artifacts with the specified profile") .arg_features() .arg_target_triple("Build for the target triple") @@ -70,7 +72,7 @@ .arg_build_plan() } -pub fn subcommand_cli(name: &str, about: &'static str) -> App<'static, 'static> { +pub fn subcommand_build(name: &str, about: &'static str) -> App<'static, 'static> { base_cli() .name(name) .about(about) @@ -84,6 +86,7 @@ .case_insensitive(true) .possible_values(&["cdylib", "staticlib"]), ) + .arg_release("Build artifacts in release mode, with optimizations") .after_help( " Compilation can be configured via the use of profiles which are configured in @@ -93,6 +96,33 @@ ) } +pub fn subcommand_install(name: &str, about: &'static str) -> App<'static, 'static> { + base_cli() + .name(name) + .about(about) + .arg( + multi_opt( + "library-type", + "LIBRARY-TYPE", + "Build only a type of library", + ) + .global(true) + .case_insensitive(true) + .possible_values(&["cdylib", "staticlib"]), + ) + .arg(opt("debug", "Build in debug mode instead of release mode")) + .arg_release( + "Build artifacts in release mode, with optimizations. This is the default behavior.", + ) + .after_help( + " +Compilation can be configured via the use of profiles which are configured in +the manifest. The default profile for this command is `release`, but passing +the --debug flag will use the `dev` profile instead. +", + ) +} + pub fn subcommand_test(name: &str) -> App<'static, 'static> { base_cli() .settings(&[AppSettings::TrailingVarArg]) @@ -104,6 +134,7 @@ .multiple(true) .last(true), ) + .arg_release("Build artifacts in release mode, with optimizations") .arg(opt("no-run", "Compile, but don't run tests")) .arg(opt("no-fail-fast", "Run all tests regardless of failure")) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/install.rs new/cargo-c-0.8.0/src/install.rs --- old/cargo-c-0.7.0/src/install.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/install.rs 2021-04-02 15:52:04.000000000 +0200 @@ -9,8 +9,8 @@ use anyhow::Context; -fn append_to_destdir(destdir: &PathBuf, path: &PathBuf) -> PathBuf { - let mut joined = destdir.clone(); +fn append_to_destdir(destdir: &Path, path: &Path) -> PathBuf { + let mut joined = destdir.to_path_buf(); for component in path.components() { match component { Component::Prefix(_) | Component::RootDir => {} @@ -22,45 +22,45 @@ #[cfg(test)] mod tests { - use std::path::PathBuf; + use std::path::{Path, PathBuf}; #[test] fn append_to_destdir() { assert_eq!( - super::append_to_destdir(&PathBuf::from(r"/foo"), &PathBuf::from(r"/bar/./..")), + super::append_to_destdir(&Path::new(r"/foo"), &PathBuf::from(r"/bar/./..")), PathBuf::from(r"/foo/bar/./..") ); assert_eq!( - super::append_to_destdir(&PathBuf::from(r"foo"), &PathBuf::from(r"bar")), + super::append_to_destdir(&Path::new(r"foo"), &PathBuf::from(r"bar")), PathBuf::from(r"foo/bar") ); assert_eq!( - super::append_to_destdir(&PathBuf::from(r""), &PathBuf::from(r"")), + super::append_to_destdir(&Path::new(r""), &PathBuf::from(r"")), PathBuf::from(r"") ); if cfg!(windows) { assert_eq!( - super::append_to_destdir(&PathBuf::from(r"X:\foo"), &PathBuf::from(r"Y:\bar")), + super::append_to_destdir(&Path::new(r"X:\foo"), &PathBuf::from(r"Y:\bar")), PathBuf::from(r"X:\foo\bar") ); assert_eq!( - super::append_to_destdir(&PathBuf::from(r"A:\foo"), &PathBuf::from(r"B:bar")), + super::append_to_destdir(&Path::new(r"A:\foo"), &PathBuf::from(r"B:bar")), PathBuf::from(r"A:\foo\bar") ); assert_eq!( - super::append_to_destdir(&PathBuf::from(r"\foo"), &PathBuf::from(r"\bar")), + super::append_to_destdir(&Path::new(r"\foo"), &PathBuf::from(r"\bar")), PathBuf::from(r"\foo\bar") ); assert_eq!( super::append_to_destdir( - &PathBuf::from(r"C:\dest"), - &PathBuf::from(r"\\server\share\foo\bar") + &Path::new(r"C:\dest"), + &Path::new(r"\\server\share\foo\bar") ), PathBuf::from(r"C:\\dest\\foo\\bar") ); @@ -135,7 +135,7 @@ } } - fn links(&self, install_path_lib: &PathBuf) { + fn links(&self, install_path_lib: &Path) { let mut ln_sf = std::process::Command::new("ln"); ln_sf.arg("-sf"); ln_sf @@ -154,12 +154,12 @@ pub(crate) fn install( &self, capi_config: &CApiConfig, - shared_lib: &PathBuf, - install_path_lib: &PathBuf, + shared_lib: &Path, + install_path_lib: &Path, ) -> anyhow::Result<()> { if capi_config.library.versioning { copy(shared_lib, install_path_lib.join(&self.with_full_ver))?; - self.links(&install_path_lib); + self.links(install_path_lib); } else { copy(shared_lib, install_path_lib.join(&self.canonical))?; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/lib.rs new/cargo-c-0.8.0/src/lib.rs --- old/cargo-c-0.7.0/src/lib.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/lib.rs 2021-04-02 15:52:04.000000000 +0200 @@ -3,5 +3,4 @@ pub mod cli; pub mod install; pub mod pkg_config_gen; -pub mod static_libs; pub mod target; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/pkg_config_gen.rs new/cargo-c-0.8.0/src/pkg_config_gen.rs --- old/cargo-c-0.7.0/src/pkg_config_gen.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/pkg_config_gen.rs 2021-04-02 15:52:04.000000000 +0200 @@ -2,7 +2,7 @@ use crate::build::CApiConfig; use crate::install::InstallPaths; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; #[derive(Debug, Clone)] pub struct PkgConfig { @@ -56,9 +56,11 @@ if let Some(subdir) = &capi_config.library.install_subdir { libdir.push(subdir); } - let mut libs = Vec::new(); - libs.push(format!("-L{}", libdir.display())); - libs.push(format!("-l{}", capi_config.library.name)); + + let libs = vec![ + format!("-L{}", libdir.display()), + format!("-l{}", capi_config.library.name), + ]; let cflags = if capi_config.header.enabled { if capi_config.header.subdirectory { @@ -111,13 +113,17 @@ pc } - pub(crate) fn uninstalled(&self, output: &PathBuf) -> Self { + pub(crate) fn uninstalled(&self, output: &Path) -> Self { let mut uninstalled = self.clone(); - uninstalled.prefix = output.clone(); + uninstalled.prefix = output.to_path_buf(); uninstalled.includedir = "${prefix}".into(); uninstalled.libdir = "${prefix}".into(); // First libs item is the search path uninstalled.libs[0] = "-L${prefix}".into(); + // First cflags item is the in include dir, if lib provides headers + if uninstalled.cflags[0].starts_with("-I") { + uninstalled.cflags[0] = "-I{prefix}".into(); + } uninstalled } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/static_libs.rs new/cargo-c-0.8.0/src/static_libs.rs --- old/cargo-c-0.7.0/src/static_libs.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/static_libs.rs 1970-01-01 01:00:00.000000000 +0100 @@ -1,46 +0,0 @@ -use std::ffi::OsString; -use std::path::PathBuf; -use std::process::{Command, Stdio}; -use std::{env, str}; - -use anyhow::Result; -use regex::Regex; - -pub fn get_static_libs_for_target<T: AsRef<std::ffi::OsStr>>( - target: Option<T>, - target_dir: &PathBuf, -) -> Result<String> { - let rustc = env::var_os("RUSTC").unwrap_or_else(|| OsString::from("rustc")); - - let mut cmd = Command::new(rustc); - cmd.arg("--color") - .arg("never") - .arg("--crate-type") - .arg("staticlib") - .arg("--print") - .arg("native-static-libs") - .arg("-") - .arg("--out-dir") - .arg(target_dir) - .stdin(Stdio::null()); - - if let Some(t) = target { - cmd.arg("--target").arg(t); - } - - let out = cmd.output()?; - - log::info!("native-static-libs check {:?} {:?}", cmd, out); - - if out.status.success() { - let re = Regex::new(r"note: native-static-libs: (.+)").unwrap(); - let s = str::from_utf8(&out.stderr).unwrap(); - - Ok(re - .captures(s) - .map_or("", |cap| cap.get(1).unwrap().as_str()) - .to_owned()) - } else { - Err(anyhow::anyhow!("cannot run {:?}", cmd)) - } -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cargo-c-0.7.0/src/target.rs new/cargo-c-0.8.0/src/target.rs --- old/cargo-c-0.7.0/src/target.rs 2020-12-21 10:44:42.000000000 +0100 +++ new/cargo-c-0.8.0/src/target.rs 2021-04-02 15:52:04.000000000 +0200 @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::path::Path; use anyhow::*; @@ -14,19 +14,15 @@ // pub vendor: String, pub os: String, pub env: String, - pub verbatim: Option<std::ffi::OsString>, } impl Target { - pub fn new<T: AsRef<std::ffi::OsStr>>(target: Option<T>) -> Result<Self, anyhow::Error> { + pub fn new<T: AsRef<std::ffi::OsStr>>(target: T) -> Result<Self, anyhow::Error> { let rustc = std::env::var("RUSTC").unwrap_or_else(|_| "rustc".into()); let mut cmd = std::process::Command::new(rustc); cmd.arg("--print").arg("cfg"); - - if let Some(t) = target.as_ref() { - cmd.arg("--target").arg(t); - } + cmd.arg("--target").arg(target); let out = cmd.output()?; if out.status.success() { @@ -48,7 +44,6 @@ // vendor: match_re(vendor_re, s), os: match_re(os_re, s), env: match_re(env_re, s), - verbatim: target.map(|v| v.as_ref().to_os_string()), }) } else { Err(anyhow!("Cannot run {:?}", cmd)) @@ -59,8 +54,8 @@ pub fn shared_object_link_args( &self, capi_config: &CApiConfig, - libdir: &PathBuf, - target_dir: &PathBuf, + libdir: &Path, + target_dir: &Path, ) -> Vec<String> { let mut lines = Vec::new(); ++++++ vendor.tar.xz ++++++ /work/SRC/openSUSE:Factory/cargo-c/vendor.tar.xz /work/SRC/openSUSE:Factory/.cargo-c.new.2401/vendor.tar.xz differ: char 13, line 1