public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/folly-rpm-macros] rawhide: Add %getdeps_* macros for getdeps builds; drop the pre-getdeps ones
@ 2026-09-18 17:38 Michel Lind
  0 siblings, 0 replies; only message in thread
From: Michel Lind @ 2026-09-18 17:38 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/folly-rpm-macros
            Branch : rawhide
            Commit : 6836520b79f7e79851bc9d11f6fa47785eb5ed9f
            Author : Michel Lind <salimma@fedoraproject.org>
            Date   : 2026-09-18T16:21:12+01:00
            Stats  : +252/-38 in 6 file(s)
            URL    : https://src.fedoraproject.org/rpms/folly-rpm-macros/c/6836520b79f7e79851bc9d11f6fa47785eb5ed9f?branch=rawhide

            Log:
            Add %getdeps_* macros for getdeps builds; drop the pre-getdeps ones

- Add %getdeps_generate_buildrequires, %getdeps_build, %getdeps_install,
  %getdeps_test and %getdeps_vendor_license_{buildrequires,install,check}
- Link the vendored stack statically into the executables; no
  shared-library mode
- Provide bundled() for vendored projects via getdeps_vendor.attr
- Depend on go-vendor-tools, cmake-rpm-macros and python3
- Drop %%folly_arches, %%folly_toolchain and the folly-srpm-macros
  subpackage (obsoleted); nothing uses them

Meta's C++ projects build with build/fbcode_builder/getdeps.py, and as of
CacheLib PR #491 getdeps can vendor its third-party dependencies into a
directory and build from it offline. Packaging the stack with getdeps
instead of one lockstep package per library needs the same handful of
steps in every spec, so they live here: system packages wherever the
getdeps manifests allow (the BuildRequires are generated from the
manifests rather than copied by hand), a vendored tree from a second
Source tarball for the rest, no network, scratch space under %%_builddir
instead of the tmpfs /tmp default, parallelism capped with %%limit_build
using the manifests' 3072 MiB job weight, and a plain DESTDIR install of
getdeps' build directory since the project is configured with
CMAKE_INSTALL_PREFIX=%%_prefix.

A getdeps package ships executables with the vendored stack linked
statically into them, and %%getdeps_install removes the libraries,
headers and CMake/pkg-config files the build installs. A shared-library
mode (getdeps --shared-lib, static PIC archives of the dependencies
linked into the project's own shared libraries) was tried with cachelib
and dropped: it links, but every shared library carries its own copy of
the stack and the copies re-register the same gflags and folly
singletons at startup, which gflags treats as fatal. A -devel package
would also need folly and fbthrift headers that Fedora does not ship.

Licenses of the vendored tree are handled by go-vendor-tools rather than
a new implementation: a getdeps vendor directory has the shape of a Go
vendor directory once getdeps-vendor.txt is rewritten as modules.txt,
which the macros do on the fly, after which go_vendor_license's detector,
config, install and --verify all work unchanged. modules.txt itself is
not installed (-M) so rpm's go_mod_vendor generator does not emit
bundled(golang(...)) Provides; getdeps_vendor.attr emits plain
bundled(<project>) from the installed getdeps-vendor.txt instead. They
are unversioned because that file records content hashes, not versions.

%%getdeps_extra_cmake_defines takes the contents of a JSON object rather
than the object itself: rpm strips a pair of braces enclosing a macro's
value (the %%define foo {body} syntax), which the first cachelib mock
build hit as getdeps rejecting '"LIB_INSTALL_DIR": "lib64", ...' as
JSON. The macro adds the braces.

%%folly_arches and %%folly_toolchain date from the packaged Folly stack,
which is retired; nothing in rawhide, f45 or f44 BuildRequires either
package, and the getdeps specs declare ExclusiveArch and the
toolchain_clang bcond themselves. %%folly_arches also lived in
macros.folly-rpm, which is absent from the SRPM buildroot where
ExclusiveArch is evaluated, so it could never have taken effect in koji.
More generally, -srpm-macros packages only help once they are preloaded
into every SRPM buildroot, which is not worth it for a handful of specs.

Verified against the cachelib vendor tree on Fedora 44: the modules.txt
transform makes go_vendor_license report, --verify and install work
(the per-file breakdown catches fizz being BSD-3-Clause and mvfst's
BSD-2/BSD-3 third_party code). Macro expansions checked with rpm --load;
rpmlint on the spec reports only the pre-existing no-%%check-section.

Assisted-by: Claude Code:claude-fable-5-1
Signed-off-by: Michel Lind <salimma@fedoraproject.org>

---
diff --git a/README.md b/README.md
index 3ded564..ab66495 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,82 @@
 # folly-rpm-macros
 
-The folly-rpm-macros package
+RPM macros for the Fedora packages of Meta's C++ projects (cachelib,
+mcrouter, ...) that build with getdeps and vendor the Folly stack (folly,
+fizz, wangle, mvfst, fbthrift, ...) rather than depending on packaged copies.
+
+The pre-getdeps macros `%folly_arches` and `%folly_toolchain` (and the
+folly-srpm-macros subpackage) were dropped in version 46: the packages that
+used them are retired, and the getdeps specs declare `ExclusiveArch` and the
+`toolchain_clang` bcond themselves.
+
+## Building with getdeps
+
+Meta's projects build with `build/fbcode_builder/getdeps.py`. The
+`%getdeps_*` macros drive it for a distro build: system packages wherever
+the getdeps manifests allow, everything else from a vendored source tree
+shipped as a second Source tarball, no network, scratch space on disk, and
+the project installed under `%{_prefix}` via DESTDIR.
+
+Produce the vendor tarball from the upstream checkout, with the same system
+packages installed that the spec will BuildRequire so getdeps vendors
+exactly the projects the build will look for:
+
+    python3 build/fbcode_builder/getdeps.py --allow-system-packages \
+        vendor --no-tests --output-dir vendor <project>
+    tar cJf <name>-<version>-vendor.tar.xz vendor/
+
+Spec skeleton:
+
+    Source1:        %{name}-%{version}-vendor.tar.xz
+    BuildRequires:  folly-rpm-macros
+
+    %generate_buildrequires
+    %getdeps_generate_buildrequires
+    %getdeps_vendor_license_buildrequires
+
+    %prep
+    %autosetup -a1
+
+    %build
+    %getdeps_build
+
+    %install
+    %getdeps_install
+    %getdeps_vendor_license_install
+
+    %check
+    %getdeps_vendor_license_check
+
+    %files -f %{getdeps_vendor_license_filelist}
+
+A getdeps package ships executables (cachebench, mcrouter, wdt, ...) with the
+vendored stack linked statically into them; `%getdeps_install` removes the
+libraries, headers and CMake/pkg-config files the project installs. There is
+deliberately no shared-library mode. getdeps `--shared-lib` builds work at
+link time, but every shared library gets its own copy of the stack and the
+copies re-register the same gflags and folly singletons at startup (gflags
+aborts on the duplicate). A `-devel` package would also need folly and
+fbthrift headers, which Fedora does not ship.
+
+Other knobs, all overridable with `%global` before use: `%getdeps_project`
+(defaults to `%{name}`), `%getdeps_vendor_dir` (`vendor`; go-vendor-tools
+requires that name), `%getdeps_scratch_dir`, `%getdeps_job_weight_mib` (3072,
+fed to `%limit_build`) and `%getdeps_extra_cmake_defines` (the contents of a
+JSON object without the outer braces, e.g. `"FOO": "ON"`; applies to every
+project getdeps builds). `%getdeps_build -t` also builds the project's
+tests, which `%getdeps_test` then runs in `%check`.
+
+### Licenses of the vendored tree
+
+The `%getdeps_vendor_license_*` macros wrap go-vendor-tools' `go_vendor_license`:
+the vendored tree has the same shape as a Go vendor directory once
+`getdeps-vendor.txt` is transformed into `vendor/modules.txt`, which the
+macros do on the fly. `install` places every license file under
+`%{_defaultlicensedir}/%{name}/vendor/...` together with `getdeps-vendor.txt`,
+and `check` verifies the `License:` tag against every detected license. Pass
+`-c licenses.toml` to exclude test-only or build-tooling directories from
+the scan, and `-L` to tolerate a vendored project whose license file sits in
+a versioned subdirectory.
+
+`getdeps_vendor.attr` turns the installed `getdeps-vendor.txt` into
+`Provides: bundled(<project>)` for each vendored project.

diff --git a/folly-rpm-macros.spec b/folly-rpm-macros.spec
index 3e89288..039b320 100644
--- a/folly-rpm-macros.spec
+++ b/folly-rpm-macros.spec
@@ -1,34 +1,32 @@
 Name:           folly-rpm-macros
-Version:        37
+Version:        46
 Release:        %autorelease
-Summary:        Common RPM macros for the Folly stack
+Summary:        RPM macros for building Meta's C++ projects with getdeps
 
 License:        MIT
 URL:            https://src.fedoraproject.org/rpms/folly-rpm-macros
 Source0:        macros.folly-rpm
-Source1:        macros.folly-srpm
+Source1:        getdeps_vendor.attr
+Source2:        getdeps_vendor.prov
 
 BuildArch:      noarch
 
 Requires:       rpm
-
-%global _description %{expand:
-
-folly-rpm-macros contains common RPM macros for building Folly and other
-software that depends on it.
-
-You should not need to install this package manually as folly-devel pulls it in.}
-
-%description %{_description}
-
-
-%package -n folly-srpm-macros
-Summary:        RPM macros for building Folly source packages
-Requires:       rpm
-
-%description -n folly-srpm-macros %{_description}
-
-This package contains the macros needed for building Folly source packages.
+# the %%getdeps_* macros run getdeps.py with %%{__python3}
+Requires:       python3
+# %%getdeps_install runs %%{__cmake}
+Requires:       cmake-rpm-macros
+# the %%getdeps_vendor_license_* macros wrap go_vendor_license
+Requires:       go-vendor-tools
+# the %%folly_toolchain macro and its subpackage were dropped in 46; nothing used them
+Obsoletes:      folly-srpm-macros < 46
+
+%description
+folly-rpm-macros contains the %%getdeps_* macros for building Meta's C++
+projects (cachelib, mcrouter, ...) with build/fbcode_builder/getdeps.py from
+system packages plus a vendored tree of the remaining dependencies (folly,
+fizz, wangle, mvfst, fbthrift, ...), and the file attributes that turn the
+vendored tree into bundled() Provides.
 
 
 %prep
@@ -38,14 +36,15 @@ This package contains the macros needed for building Folly source packages.
 
 
 %install
-install -D -p -m 0644 -t %{buildroot}%{_rpmmacrodir} %{SOURCE0} %{SOURCE1}
+install -D -p -m 0644 -t %{buildroot}%{_rpmmacrodir} %{SOURCE0}
+install -D -p -m 0644 -t %{buildroot}%{_fileattrsdir} %{SOURCE1}
+install -D -p -m 0755 -t %{buildroot}%{_rpmconfigdir} %{SOURCE2}
 
 
 %files
 %{_rpmmacrodir}/macros.folly-rpm
-
-%files -n folly-srpm-macros
-%{_rpmmacrodir}/macros.folly-srpm
+%{_fileattrsdir}/getdeps_vendor.attr
+%{_rpmconfigdir}/getdeps_vendor.prov
 
 
 %changelog

diff --git a/getdeps_vendor.attr b/getdeps_vendor.attr
new file mode 100644
index 0000000..e144e74
--- /dev/null
+++ b/getdeps_vendor.attr
@@ -0,0 +1,4 @@
+# Generate bundled() Provides from the getdeps vendor manifest that
+# %getdeps_vendor_license_install places under %_defaultlicensedir.
+%__getdeps_vendor_provides %{_rpmconfigdir}/getdeps_vendor.prov
+%__getdeps_vendor_path     ^%{_defaultlicensedir}(/[^/]+)+/getdeps-vendor\\.txt$

diff --git a/getdeps_vendor.prov b/getdeps_vendor.prov
new file mode 100755
index 0000000..5058892
--- /dev/null
+++ b/getdeps_vendor.prov
@@ -0,0 +1,7 @@
+#!/bin/sh
+# Emit "bundled(<project>)" for each project listed in a getdeps-vendor.txt
+# (one "<project> <git-rev-or-sha256>" line per vendored project). The second
+# field is a content hash, not a version, so the Provides are unversioned.
+while read -r manifest; do
+    awk 'NF { print "bundled(" $1 ")" }' "$manifest"
+done | sort -u

diff --git a/macros.folly-rpm b/macros.folly-rpm
index 2acff40..cf8e231 100644
--- a/macros.folly-rpm
+++ b/macros.folly-rpm
@@ -1,7 +1,139 @@
-# s390x: Folly is known not to work on big-endian CPUs
-# https://bugzilla.redhat.com/show_bug.cgi?id=1892151
+# --- getdeps (build/fbcode_builder) -----------------------------------------
+#
+# Meta's C++ projects build with build/fbcode_builder/getdeps.py. These
+# macros drive it the way a distro build needs: dependencies from system
+# packages wherever the getdeps manifests allow, everything else from a
+# vendored source tree shipped as a second Source tarball (produced with
+# `getdeps.py vendor`), no network access, scratch space on disk, and the
+# top-level project installed under %%{_prefix} via DESTDIR.
+#
+# Minimal spec skeleton:
+#
+#   Source1:        %%{name}-%%{version}-vendor.tar.xz
+#   BuildRequires:  folly-rpm-macros
+#   %%generate_buildrequires
+#   %%getdeps_generate_buildrequires
+#   %%getdeps_vendor_license_buildrequires
+#   %%prep
+#   %%autosetup -a1
+#   %%build
+#   %%getdeps_build
+#   %%install
+#   %%getdeps_install
+#   %%getdeps_vendor_license_install
+#   %%check
+#   %%getdeps_vendor_license_check
+#   %%files -f %%{getdeps_vendor_license_filelist}
+#
+# Generate the vendor tarball with the same system packages installed that
+# the spec BuildRequires (and with --no-tests unless the spec builds tests),
+# so that getdeps vendors exactly the projects the build will look for.
 
-# 32-bit arches: upstream does not test on these, causing repeated failures, and
-# with F37 dropping armv7hl, and %{ix86} being optional, drop these
+# Path of getdeps.py inside the unpacked source tree.
+%getdeps_script build/fbcode_builder/getdeps.py
 
-%folly_arches x86_64 aarch64 ppc64le
+# The project's name in getdeps' manifests; override if it differs from %%{name}.
+%getdeps_project %{name}
+
+# Where %%autosetup unpacked the vendor tarball. Keep it "vendor": the license
+# macros delegate to go-vendor-tools, which only looks at <srcdir>/vendor.
+%getdeps_vendor_dir vendor
+
+# getdeps' default scratch dir is under /tmp, a tmpfs sized at half of RAM on
+# Fedora, where build trees compete with the compilers for memory.
+%getdeps_scratch_dir %{_builddir}/%{name}-getdeps
+
+# Estimated peak memory per compiler process, fed to %%limit_build to cap
+# parallelism on small builders. Matches job_weight_mib in the cachelib and
+# fbthrift manifests (measured p99 2.6 GiB, max 4 GiB).
+%getdeps_job_weight_mib 3072
+
+# A getdeps package ships executables. The vendored stack is linked
+# statically into them, and %%getdeps_install removes the libraries, headers
+# and CMake/pkg-config files the project installs. There is no shared-library
+# mode: the stack cannot be split across several shared libraries (each copy
+# re-registers the same gflags and folly singletons at startup, and gflags
+# aborts), and a -devel package would need folly headers that Fedora does not
+# ship.
+
+# Optional: extra CMake defines (getdeps --extra-cmake-defines), given as the
+# *contents* of a JSON object, without the outer braces: rpm strips a pair of
+# braces enclosing a macro's value, so the macro adds them itself. They apply
+# to every project getdeps builds, not only the top-level one.
+#   %%global getdeps_extra_cmake_defines "FOO": "ON", "BAR": "1"
+
+%__getdeps %{__python3} %{getdeps_script}
+%__getdeps_common_opts %{shrink:
+  --allow-system-packages
+  --vendor-dir %{getdeps_vendor_dir}
+  --scratch-path %{getdeps_scratch_dir}
+  --num-jobs %{_smp_build_ncpus}
+  %{?getdeps_extra_cmake_defines:--extra-cmake-defines '{%{getdeps_extra_cmake_defines}}'}
+}
+
+# getdeps_generate_buildrequires: for %%generate_buildrequires. Emits the
+# distro packages getdeps would take from the system for %%getdeps_project,
+# so the BuildRequires follow the manifests instead of being copied by hand.
+%getdeps_generate_buildrequires() %{shrink:
+  %{__getdeps} --allow-system-packages install-system-deps --recursive --dry-run %{getdeps_project}
+  | sed -n 's/^.*dnf install -y --skip-broken //p' | xargs -n1
+}
+
+# getdeps_build: build the dependencies and the project. Options:
+#   -t : also build the project's tests (for %%getdeps_test in %%check)
+%getdeps_build(t) \
+%set_build_flags \
+%{limit_build -m %{getdeps_job_weight_mib}} \
+%{__getdeps} %{__getdeps_common_opts} build --free-up-disk %{!-t:--no-tests} --src-dir=. --project-install-prefix %{getdeps_project}:%{_prefix} %{getdeps_project}
+
+# getdeps_install: install the project into %%{buildroot}. getdeps configured
+# it with CMAKE_INSTALL_PREFIX=%%{_prefix} (--project-install-prefix), so this
+# is a plain DESTDIR install of its build directory, followed by pruning the
+# libraries, headers and CMake/pkg-config files (the buildroot holds only this
+# project's files at that point, so the globs are safe).
+%getdeps_install() \
+DESTDIR=%{buildroot} %{__cmake} --install "$(%{__getdeps} %{__getdeps_common_opts} show-build-dir %{getdeps_project})" \
+rm -rf %{buildroot}%{_libdir}/lib*.so* %{buildroot}%{_libdir}/lib*.a %{buildroot}%{_libdir}/cmake %{buildroot}%{_libdir}/pkgconfig %{buildroot}%{_includedir}
+
+# getdeps_test: run the project's tests (built with %%getdeps_build -t).
+%getdeps_test() \
+%{__getdeps} %{__getdeps_common_opts} test --src-dir=. %{getdeps_project}
+
+# --- license handling for the vendored tree -----------------------------------
+#
+# Delegated to go-vendor-tools: its detector, config, install and verify
+# steps only need a Go-style vendor/modules.txt listing the vendored
+# modules, which is a one-line transform of getdeps-vendor.txt.
+
+%__getdeps_modules_txt() awk '{ print "# " $1 " v" $2 }' %{getdeps_vendor_dir}/getdeps-vendor.txt > %{getdeps_vendor_dir}/modules.txt
+
+# getdeps_vendor_license_buildrequires: for %%generate_buildrequires.
+# Same options as %%go_vendor_license_buildrequires (-c config, -d detector).
+%getdeps_vendor_license_buildrequires(c:d:D:) %{go_vendor_license_buildrequires %**}
+
+# getdeps_vendor_license_filelist: file list written by the install macro,
+# for `%%files -f`.
+%getdeps_vendor_license_filelist %{go_vendor_license_filelist}
+
+# getdeps_vendor_license_install: install every license file found in the
+# vendored tree under %%{_defaultlicensedir}/%%{name}/vendor/..., plus
+# getdeps-vendor.txt itself, and write %%getdeps_vendor_license_filelist.
+# Same options as %%go_vendor_license_install (-c, -n, -d, -D). modules.txt
+# is deliberately not installed (-M): rpm's go_mod_vendor generator would
+# turn it into bundled(golang(...)) Provides; bundled() Provides for getdeps
+# projects come from getdeps-vendor.txt via getdeps_vendor.attr instead.
+%getdeps_vendor_license_install(c:n:d:D:) \
+%{__getdeps_modules_txt} \
+%{go_vendor_license_install %** -M} \
+install -D -p -m 0644 -t %{buildroot}%{_defaultlicensedir}/%{?-n*}%{!?-n:%{name}} %{getdeps_vendor_dir}/getdeps-vendor.txt \
+echo '%%license %{_defaultlicensedir}/%{?-n*}%{!?-n:%{name}}/getdeps-vendor.txt' >> %{getdeps_vendor_license_filelist}
+
+# getdeps_vendor_license_check: for %%check. Verify that the spec's License
+# tag (or the expression given as argument) covers every license detected
+# in the source and vendored trees. Options as %%go_vendor_license_check,
+# plus:
+#   -L : ignore vendored projects with no license file at their top level
+#        (e.g. a tarball whose LICENSE sits in a versioned subdirectory)
+%getdeps_vendor_license_check(c:d:D:L) \
+%{__getdeps_modules_txt} \
+%{__go_vendor_license} %{-c:--config %{-c*}} %{-d:--detector %{-d*}} %{-D:--detector-config %{-D*}} report all %{-L:-L} --verify '%{expr: "%{*}" ? "%{*}" : "%{LICENSE}"}'

diff --git a/macros.folly-srpm b/macros.folly-srpm
deleted file mode 100644
index eca11e5..0000000
--- a/macros.folly-srpm
+++ /dev/null
@@ -1,7 +0,0 @@
-%folly_toolchain \
-%bcond_with toolchain_clang \
-\
-%if %{with toolchain_clang} \
-%global toolchain clang \
-%endif \
-%{nil}

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-18 17:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-18 17:38 [rpms/folly-rpm-macros] rawhide: Add %getdeps_* macros for getdeps builds; drop the pre-getdeps ones Michel Lind

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox