# Two build paths, one spec, chosen by the `vendor` bcond. # # Fedora packages every crate in this project's Cargo.lock, so Fedora builds # UNBUNDLED with the cargo RPM macros against the system crate registry: # "All packages whose upstreams allow them to be built against system # libraries MUST be built against system libraries" # (https://docs.fedoraproject.org/en-US/packaging-guidelines/), and "packages # SHOULD NOT use bundled crate dependencies, whenever possible" # (https://docs.fedoraproject.org/en-US/packaging-guidelines/Rust/). # # Everywhere else -- EPEL, CentOS Stream, openSUSE, Mageia, Amazon Linux, # openEuler, Azure Linux, and Fedora ELN -- ships neither cargo-rpm-macros nor # the rust-*-devel crates, so those chroots build VENDORED from Source1, # exactly as every build did before this split, and declare what they bundle # with Provides: bundled(crate(...)) below. # # Copr builds ONE source RPM and feeds it to every chroot, but mock rebuilds # that SRPM inside each chroot before resolving its BuildRequires, so this # condition is re-evaluated per chroot and each one gets the path and the # BuildRequires it can satisfy. Source1 is therefore always generated and # always shipped; the unbundled path simply never unpacks it. # `rpmbuild --with vendor` forces the vendored path anywhere, `--without # vendor` the unbundled one (Copr can set either per chroot). # # %%{fedora} alone is NOT quite the right test: Amazon Linux 2023 defines # %%{fedora} too (it is Fedora-derived) yet ships neither cargo-rpm-macros nor # the rust-* crates, so it is excluded by %%{amzn} and builds vendored - found # when the v0.4.11 tag build failed on exactly that chroot with 'No matching # package to install: cargo-rpm-macros'. For everything else, "The ELN buildroot defines the %%{rhel} # macro ... and does not define the %%{fedora} macro" -- # https://docs.fedoraproject.org/en-US/eln/eln-macros/ -- and neither do RHEL, # CentOS Stream, openSUSE or Mageia. %if 0%{?fedora} && !0%{?amzn} %bcond_with vendor %else %bcond_without vendor %endif # The test suite compiles and RUNS x86-64 programs, so it can only pass on # x86_64; %%check is guarded accordingly below. --without check skips it. %bcond_without check Name: vox Version: 0.4.14 Release: 1%{?dist} Summary: Compiler for a constrained, sentence-based English programming language # The binary statically links its Rust dependencies, so the tag is the # effective licence of what ships, not just of our own source. Output of # %%cargo_license_summary, copied here as the Rust Packaging Guidelines direct: # GPL-3.0-or-later # MIT OR Apache-2.0 # The conjunction of those is the tag below. GPL-3.0-or-later is vox itself; # MIT OR Apache-2.0 is thiserror, the one crate linked into the binary -- # proc-macro2, quote, syn and unicode-ident are proc-macro/build-time only, so # the macro excludes them and so does this tag. On the vendored path the same # crates are linked, so the same expression holds; the extra crates in the # vendor tarball are declared with bundled(crate(...)) below. License: GPL-3.0-or-later AND (MIT OR Apache-2.0) URL: https://github.com/Vox-lang/vox Source0: %{url}/archive/v%{version}/vox-%{version}.tar.gz # Vendored crates.io dependencies. There is no upstream URL for this one: it # is generated by .copr/Makefile's srpm target, from the Cargo.lock inside # Source0, with # # tar -xzf vox-%%{version}.tar.gz # cd vox-%%{version} && cargo vendor --locked ../vendor # tar -C .. -czf vox-%%{version}-vendor.tar.gz vendor # # so that the vendored build path needs no network access. Vendoring is done # against the Cargo.lock inside Source0 rather than the working tree's, so the # crate versions can never disagree with the source the SRPM actually ships. Source1: vox-%{version}-vendor.tar.gz # The Rust toolchain links through cc, so a C compiler is invoked on both # paths even though no C is compiled: "If your application is a C or C++ # application you must list a BuildRequires against gcc, gcc-c++ or clang" -- # https://docs.fedoraproject.org/en-US/packaging-guidelines/C_and_C++/ BuildRequires: gcc %if %{with vendor} BuildRequires: cargo BuildRequires: rust >= 1.71 %else # "Packages that build Rust code with cargo ... MUST add BuildRequires: # cargo-rpm-macros" (Rust Packaging Guidelines). >= 24 is the bound Fedora's # own rust2rpm-generated specs carry (rust-thiserror, rust-ripgrep); it covers # every macro used below, including %%cargo_license_summary and %%cargo_license. BuildRequires: cargo-rpm-macros >= 24 %endif %if %{with check} %ifarch x86_64 # %%check compiles Vox programs and runs them, which shells out to nasm and # ld. Only on x86_64: see the %%check section for why the suite runs nowhere # else, and nasm is an x86 assembler that other architectures need not carry. BuildRequires: nasm BuildRequires: binutils %endif %endif # vox shells out to nasm/ld only when it compiles a *user's* .vox program, # not to build vox itself, so these are runtime Requires, not BuildRequires. Requires: nasm Requires: binutils # Libraries are not part of the compiler and it never needs them -- Vox has no # standard library by design. Suggests records that they exist without dnf # pulling them in; a plain `dnf install vox` stays exactly as it was. Suggests: vox-libs %if %{with vendor} # Every crate in Cargo.lock is built into this path's binary, so each is # declared: "all bundled crate dependencies MUST be declared with virtual # Provides in the format Provides: bundled(crate($crate)) = $version in the # subpackage that contains the Rust component" -- # https://docs.fedoraproject.org/en-US/packaging-guidelines/Rust/ # # Hand-written on purpose: Copr builds one SRPM for every chroot, so nothing # may rewrite this file at SRPM time. scripts/check-spec-bundled.sh derives # the same list from Cargo.lock and fails if the two drift; ./test.sh runs it. Provides: bundled(crate(proc-macro2)) = 1.0.107 Provides: bundled(crate(quote)) = 1.0.47 Provides: bundled(crate(syn)) = 3.0.3 Provides: bundled(crate(thiserror)) = 2.0.20 Provides: bundled(crate(thiserror-impl)) = 2.0.20 Provides: bundled(crate(unicode-ident)) = 1.0.24 # Debuginfo is skipped on THIS path only, and the guidelines want the reason # in the spec. find-debuginfo's source-file attribution for this LTO release # binary is chroot-dependent: it produced a real vox-debugsource package on # Fedora 44, but on Fedora ELN the debugsourcefiles.list came back empty and # rpm there treats an empty %%files -f list as fatal ("Empty %%files file ... # debugsourcefiles.list") -- commit 932174b, which is the failure this line # was added for. This path is exactly the set of chroots that cannot be tested # from a Fedora box, ELN among them, so the skip stays here rather than # chasing per-chroot elfutils behaviour. # # The unbundled path does NOT skip it, and is the path Fedora reviews. There, # %%cargo_prep writes the build profile itself -- `debug` from # %%{rustflags_debuginfo}, `strip = "none"` -- so debug info is pinned in # cargo's own profile rather than only in the RUSTFLAGS that # %%set_build_flags exports, and normal debuginfo extraction applies. %global debug_package %{nil} %endif %description %{summary}. Vox compiles directly to native x86_64 NASM assembly with no libc, no garbage collector, and no hidden runtime system. All abstractions are resolved at compile time. %prep %if %{with vendor} %autosetup -n vox-%{version} -a1 mkdir -p .cargo cat > .cargo/config.toml <<'EOF' [source.crates-io] replace-with = "vendored-sources" [source.vendored-sources] directory = "vendor" EOF %else # Source1 is deliberately not unpacked here: this path builds against the # system crate registry, and an unpacked vendor/ would put crate sources in # the build tree that the binary does not use. %autosetup -n vox-%{version} %cargo_prep %endif %if %{without vendor} %generate_buildrequires %cargo_generate_buildrequires %endif %build %if %{with vendor} cargo build --release --offline %else %cargo_build %{cargo_license_summary} %{cargo_license} > LICENSE.dependencies %endif %install %if %{with vendor} install -Dm0755 target/release/%{name} %{buildroot}%{_bindir}/%{name} %else %cargo_install %endif install -d %{buildroot}%{_datadir}/%{name} cp -r coreasm %{buildroot}%{_datadir}/%{name}/coreasm find %{buildroot}%{_datadir}/%{name}/coreasm -type d -exec chmod 0755 {} + find %{buildroot}%{_datadir}/%{name}/coreasm -type f -exec chmod 0644 {} + install -Dpm0644 man/%{name}.1 %{buildroot}%{_mandir}/man1/%{name}.1 %if %{with check} %check # The suite compiles Vox sources to x86-64 assembly and runs the result, so it # is meaningful only where that result can execute. Other architectures build # the compiler but cannot run what it emits. %ifarch x86_64 # Point the compiler at the coreasm in the build tree. Without it the # resolution order would reach for an installed /usr/share/vox/coreasm, and a # runtime change in this source tree would go untested. export VOX_CORE_PATH="$(pwd)/coreasm" %if %{with vendor} cargo test --release --offline %else %cargo_test %endif %endif %endif %files %license LICENSE %if %{without vendor} %license LICENSE.dependencies %endif %doc README.md %{_bindir}/%{name} %{_datadir}/%{name}/ %{_mandir}/man1/%{name}.1* %changelog * Fri Aug 28 2026 TheJostler - 0.4.14-1 - New upstream release 0.4.14 * Mon Aug 24 2026 TheJostler - 0.4.13-1 - New upstream release 0.4.13 * Mon Aug 24 2026 TheJostler - 0.4.12-1 - New upstream release 0.4.12 * Sun Aug 23 2026 TheJostler - 0.4.11-1 - New upstream release 0.4.11 * Sat Aug 22 2026 TheJostler - 0.4.10-1 - Update to 0.4.10 and ship a manual page, so "man vox" works - Build against Fedora's packaged crates instead of vendored ones, and run the upstream test suite at build time * Fri Aug 14 2026 TheJostler - 0.3.5-1 - Initial COPR packaging