diff --git a/Cargo.toml b/Cargo.toml index 7f8449678..7b7b76b20 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,6 @@ opt-level = 1 # No optimizations are too slow for us. [profile.release] lto = "thin" -# We use FFI so this is safest -panic = "abort" # We assume we're being delivered via e.g. RPM which supports split debuginfo debug = true @@ -76,7 +74,7 @@ similar-asserts = "2.0.0" static_assertions = "1.1.0" tempfile = "3.10.1" thiserror = "2.0.11" -tokio = ">= 1.37.0" +tokio = { version = ">= 1.37.0", features = ["test-util"] } tokio-util = { features = ["io-util"], version = "0.7.10" } toml = "1.0.0" tracing = "0.1.40" diff --git a/Makefile b/Makefile index 5c924f3a4..17bb57b79 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,22 @@ CARGO_OPTIONS ?= --features "$(CARGO_FEATURES)" # image configuration rather than documentation. DISABLE_DOCS ?= +# Set to 1 to install already-built binaries and man pages without invoking +# cargo, e.g. from an RPM %install after the binaries were built in %build: +# make install SKIP_BUILD=1 +SKIP_BUILD ?= + +# Cargo profile used to build xtask (e.g. for man pages). RPM builds set this +# to `rpm` so xtask shares the %cargo_build profile instead of clobbering its +# state through the target/release -> target/rpm symlink from %cargo_prep. +XTASK_PROFILE ?= release + +# The cargo command used by the build targets. RPM builds set this to +# %{__cargo} so the environment (e.g. RUSTC_BOOTSTRAP) matches the +# %cargo_* macros; otherwise build scripts that depend on it re-run and +# invalidate the shared build state. +CARGO ?= cargo + # Build all binaries .PHONY: bin # The man pages are built first so that the production binary below @@ -64,16 +80,25 @@ ifneq ($(DISABLE_DOCS),1) bin: manpages endif bin: - cargo build --release $(CARGO_OPTIONS) --bins + $(CARGO) build --release $(CARGO_OPTIONS) --bins # The docgen feature this adds implies install-to-disk, so the man pages # document the full CLI regardless of CARGO_OPTIONS. .PHONY: manpages manpages: - cargo run --release --package xtask -- manpages -- $(CARGO_OPTIONS) + $(CARGO) run --profile $(XTASK_PROFILE) --package xtask -- manpages -- $(CARGO_OPTIONS) + +# Convert the man page markdown in docs/src/man without building bootc to +# sync its generated CLI sections; CI ensures those are already up to date. +.PHONY: manpages-no-sync +manpages-no-sync: + $(CARGO) run --profile $(XTASK_PROFILE) --package xtask -- manpages --no-sync .PHONY: completion +ifneq ($(SKIP_BUILD),1) completion: bin +endif +completion: mkdir -p target/completion for shell in bash elvish fish powershell zsh; do \ target/release/bootc completion $$shell > target/completion/bootc.$$shell; \ diff --git a/contrib/packaging/bootc.spec b/contrib/packaging/bootc.spec index 164dd6ee8..9d2a6cf4b 100644 --- a/contrib/packaging/bootc.spec +++ b/contrib/packaging/bootc.spec @@ -137,8 +137,6 @@ cd %{name}-%{version}-build %build export SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH=%{system_reinstall_bootc_install_podman_path} -# Build this first to avoid feature skew -make manpages # Build all binaries %if 0%{?container_build} @@ -156,6 +154,17 @@ cargo build -j%{_smp_build_ncpus} --release %{?with_rhsm:--features rhsm} %{?wit %endif %endif +# The generated CLI sections in the man page sources are kept in sync by CI, +# so just convert them; this avoids building bootc a second time. +# Outside of container builds, use the same cargo environment and profile as +# %%cargo_build/%%cargo_test, so xtask doesn't invalidate their shared state +# (target/release is a symlink to target/rpm, created by %%cargo_prep). +%if 0%{?container_build} +make manpages-no-sync +%else +make manpages-no-sync XTASK_PROFILE=rpm CARGO="%{__cargo}" +%endif + %if ! 0%{?container_build} %cargo_vendor_manifest # https://pagure.io/fedora-rust/rust-packaging/issue/33 @@ -165,8 +174,10 @@ sed -i -e '/https:\/\//d' cargo-vendor.txt %endif %install -# Pass CARGO_FEATURES explicitly to prevent auto-detection rebuild in install environment -%make_install INSTALL="install -p -c" CARGO_FEATURES="%{?with_rhsm:rhsm} %{?with_rhel9:rhel9}" +# Everything was built in %%build; SKIP_BUILD=1 keeps make from invoking cargo +# again (which would also overwrite the %%cargo_build output in target/rpm via +# the target/release symlink created by %%cargo_prep). +%make_install INSTALL="install -p -c" SKIP_BUILD=1 %if %{with ostree_ext} make install-ostree-hooks DESTDIR=%{?buildroot} %endif diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 6342b2f58..c0ea199d4 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -83,7 +83,6 @@ uapi-version = "0.4.0" ostree-ext = { path = "../ostree-ext", features = ["bootc", "internal-testing-api"] } similar-asserts = { workspace = true } static_assertions = { workspace = true } -tokio = { workspace = true, features = ["test-util"] } [features] default = ["install-to-disk", "selinux"] diff --git a/crates/xtask/src/man.rs b/crates/xtask/src/man.rs index 173ef469a..5ca400fbd 100644 --- a/crates/xtask/src/man.rs +++ b/crates/xtask/src/man.rs @@ -835,6 +835,13 @@ pub fn generate_man_pages(sh: &Shell, cargo_options: &[String]) -> Result<()> { generate_pages(sh, false) } +/// Generate manuals from the Markdown as-is, without building bootc to sync +/// the generated CLI sections first. +#[context("Generating manpages")] +pub fn generate_man_pages_no_sync(sh: &Shell) -> Result<()> { + generate_pages(sh, false) +} + /// Get version from Cargo.toml #[context("Querying package version")] fn get_package_version() -> Result { diff --git a/crates/xtask/src/xtask.rs b/crates/xtask/src/xtask.rs index 9c496e254..d06b56c86 100644 --- a/crates/xtask/src/xtask.rs +++ b/crates/xtask/src/xtask.rs @@ -79,6 +79,11 @@ struct Cli { enum Commands { /// Generate man pages Manpages { + /// Only convert the markdown in docs/src/man, without first building + /// bootc to sync its generated CLI sections. CI verifies those are up + /// to date, so this is suitable for packaging a release. + #[arg(long, conflicts_with = "cargo_options")] + no_sync: bool, /// Extra options for cargo when building bootc, after `--` /// (e.g. `-- --no-default-features --features install-to-disk`) #[arg(last = true)] @@ -395,7 +400,16 @@ fn try_main() -> Result<()> { let sh = xshell::Shell::new()?; match cli.command { - Commands::Manpages { cargo_options } => man::generate_man_pages(&sh, &cargo_options), + Commands::Manpages { + no_sync, + cargo_options, + } => { + if no_sync { + man::generate_man_pages_no_sync(&sh) + } else { + man::generate_man_pages(&sh, &cargo_options) + } + } Commands::GuideManpages => man::generate_guide_man_pages(&sh), Commands::CheckDocs => man::check_docs(), Commands::UpdateGenerated { command } => match command {