Switch to --package-metadata
Use a compiler specs file to avoid issues with escaping and quoting when a package is built using autotools. Generate the osCpe string at build time for now, as it's not set as an env var by rpm yet.
This commit is contained in:
parent
145f26fa48
commit
9da9df8af2
@ -1,66 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
readonly=1
|
||||
insert_after=1
|
||||
|
||||
pad_string() {
|
||||
for _ in $(seq "$1"); do
|
||||
printf ' BYTE(0x00)'
|
||||
done
|
||||
}
|
||||
|
||||
write_string() {
|
||||
text="$1"
|
||||
prefix="$2"
|
||||
label="$3"
|
||||
total="$4"
|
||||
|
||||
printf "%s/* %s: '%s' */" "$prefix" "$label" "$text"
|
||||
for i in $(seq ${#text}); do
|
||||
if (( i % 4 == 1 )); then
|
||||
printf '\n%s' "$prefix"
|
||||
else
|
||||
printf ' '
|
||||
fi
|
||||
printf 'BYTE(0x%02x)' "'${text:i-1:1}"
|
||||
done
|
||||
|
||||
pad_string $(( total - ${#text} ))
|
||||
printf '\n'
|
||||
}
|
||||
|
||||
write_script() {
|
||||
value_len=$(( (${#1} + 3) / 4 * 4 ))
|
||||
[ -n "$readonly" ] && readonly_attr='(READONLY) '
|
||||
|
||||
printf 'SECTIONS\n{\n'
|
||||
printf ' .note.package %s: ALIGN(4) {\n' "$readonly_attr"
|
||||
# Note that for the binary fields we use the native 4 bytes type, to avoid
|
||||
# endianness issues.
|
||||
printf ' LONG(0x0004) /* Length of Owner including NUL */\n'
|
||||
printf ' LONG(0x%04x) /* Length of Value including NUL */\n' \
|
||||
${value_len}
|
||||
printf ' LONG(0xcafe1a7e) /* Note ID */\n'
|
||||
|
||||
printf " BYTE(0x46) BYTE(0x44) BYTE(0x4f) BYTE(0x00) /* Owner: 'FDO' */\n"
|
||||
|
||||
write_string "$1" ' ' 'Value' "$value_len"
|
||||
|
||||
printf ' }\n}\n'
|
||||
[ -n "$insert_after" ] && printf 'INSERT AFTER .note.gnu.build-id;\n'
|
||||
:
|
||||
}
|
||||
|
||||
if [ "$1" == "--readonly=no" ]; then
|
||||
shift
|
||||
readonly=
|
||||
fi
|
||||
|
||||
if [ "$1" == "--insert-after=no" ]; then
|
||||
shift
|
||||
insert_after=
|
||||
fi
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: 0BSD
|
||||
# Prints a quoted --package-metadata string suitable for being used from an RPM
|
||||
# macro in a way that gets correctly propagated down to the linker.
|
||||
|
||||
cpe="$(cat /usr/lib/system-release-cpe)"
|
||||
json="$(printf '{"type":"rpm","name":"%s","version":"%s","architecture":"%s","osCpe":"%s"}' "$1" "$2" "$3" "$cpe")"
|
||||
write_script "$json"
|
||||
|
||||
# We need to print the escapes as-is, so single quote echo, but also print the
|
||||
# variables, so do it in multiple lines.
|
||||
# The many quotes are necessary so that the compiler gets:
|
||||
# -Xlinker "--package-metadata={\"type\":\"rpm\",\"name\":\"foo\",\"version\":\"bar\",\"architecture\":\"baz\",\"osCpe\":\"barbaz\"}"
|
||||
# This way the inner quotes make it into the parsed string, and the outer quotes
|
||||
# ensure the { } do not get expanded. -Xlinker instead of -Wl allows to use commas.
|
||||
echo -n '-Xlinker \"--package-metadata={\\\"type\\\":\\\"rpm\\\",\\\"name\\\":\\\"'
|
||||
echo -n "$1"
|
||||
echo -n '\\\",\\\"version\\\":\\\"'
|
||||
echo -n "$2"
|
||||
echo -n '\\\",\\\"architecture\\\":\\\"'
|
||||
echo -n "$3"
|
||||
echo -n '\\\",\\\"osCpe\\\":\\\"'
|
||||
echo -n "$cpe"
|
||||
# Yes, the closing bracket needs to be escaped, otherwise it gets duplicated:
|
||||
# "--package-metadata={\"type\":\"rpm\",\"name\":\"foo\",\"version\":\"bar\",\"architecture\":\"baz\",\"osCpe\":\"barbaz\"}"}
|
||||
echo -n '\\\"\}\"'
|
||||
|
@ -7,49 +7,26 @@
|
||||
# To opt out of the use of this feature completely, include this in
|
||||
# the spec file:
|
||||
#
|
||||
# %undefine _package_note_file
|
||||
# %undefine _package_note_flags
|
||||
#
|
||||
# The other macros can be undefined too to replace parts of the
|
||||
# functionality. If %_generate_package_note_file is undefined, the
|
||||
# linker script will not be generated, but the link flags may still
|
||||
# refer to it. This may be useful if the default generation method is
|
||||
# insufficient and a different mechanism will be used to generate
|
||||
# %_package_note_file. If %_package_note_flags is undefined, the
|
||||
# linker argument that injects the script will not be added to
|
||||
# %build_ldfags, but the linker script would still be generated.
|
||||
|
||||
# The name of the file with the linker script. If %{buildsubdir} is
|
||||
# defined, the file will be placed therein. Otherwise, one level up,
|
||||
# directly in %{_builddir}.
|
||||
#
|
||||
# Note that %{version}-%{release} used here might be redefined from
|
||||
# the "primary" values when subpackages with different version-release
|
||||
# are specified. The contents of the script use the shell variable
|
||||
# $RPM_PACKAGE_NAME, $RPM_PACKAGE_VERSION, $RPM_PACKAGE_RELEASE,
|
||||
# and $RPM_ARCH that are set early and seem to always contain the "primary"
|
||||
# values for the main package.
|
||||
%_package_note_file %{_builddir}%{?buildsubdir:/%{buildsubdir}}/.package_note-%{name}-%{version}-%{release}.%{_arch}.ld
|
||||
|
||||
# Which linker will be used? This should be either "bfd", "gold", or
|
||||
# "lld". Unfortunately linkers other than bfd do not support some of
|
||||
# the options that we'd like to use, so if this is set to anything
|
||||
# other than "bfd", note insertion is disabled.
|
||||
# "mold". Unfortunately "lld" does not support the --package-metadata flag so
|
||||
# the note insertion is disabled when using it.
|
||||
#
|
||||
# (The default linker for clang on armv7hl is lld.)
|
||||
%_package_note_linker %["%_target_cpu" == "armv7hl" && "%{toolchain}" == "clang" ? "lld" : "bfd"]
|
||||
|
||||
# Whether to specify the READONLY attribute for the inserted
|
||||
# section. We generally want this, but binutils <= 2.37 and other
|
||||
# linkers do not support it.
|
||||
%_package_note_readonly %["%_package_note_linker" == "bfd"?"1":"0"]
|
||||
# These are defined for backwards compatibility. Do not use.
|
||||
%_package_note_file 1
|
||||
%_generate_package_note_file %{nil}
|
||||
|
||||
# Overall status: 1 if looks like we can insert the note, 0 otherwise
|
||||
%_package_note_status %[0%{?_package_note_file:1} && 0%{?name:1} && "%_target_cpu" != "noarch" && "%_package_note_linker" == "bfd" ? 1 : 0]
|
||||
%_package_note_status %[0%{?_package_note_file:1} && 0%{?name:1} && "%_target_cpu" != "noarch" && "%_package_note_linker" != "lld" ? 1 : 0]
|
||||
|
||||
# The linker flags to be passed to the compiler to insert the notes section.
|
||||
%_package_note_flags %[%_package_note_status?"-Wl,%["%_package_note_linker" != "lld"?"-dT":"-T"],%{_package_note_file}":""]
|
||||
# The linker flags to be passed to the compiler to insert the notes section will be created by the spec file,
|
||||
# to avoid issues with quoting and escaping across different build systems and shells.
|
||||
%_package_note_flags %[%_package_note_status?"-specs=/usr/lib/rpm/redhat/redhat-package-notes":""]
|
||||
|
||||
# The command to actually generate the linker script that inserts the
|
||||
# notes file. This command is automatically used as part of the build
|
||||
# preamble.
|
||||
%_generate_package_note_file %[%_package_note_status?"if [ -f %{_rpmconfigdir}/generate-rpm-note.sh ]; then %{_rpmconfigdir}/generate-rpm-note.sh %[0%{?_package_note_readonly}?"":"--readonly=no "]${RPM_PACKAGE_NAME:?} ${RPM_PACKAGE_VERSION:?}-${RPM_PACKAGE_RELEASE:?} ${RPM_ARCH:?} >%{_package_note_file}; fi":""]
|
||||
# Passing linker flags inline via -Xlinker causes autotools failures, as libtool eats the escaped quotes
|
||||
#%_package_note_json %(%{_rpmconfigdir}/generate-rpm-note.sh %name %version %_arch)
|
||||
#%_package_note_flags %[%_package_note_status?"%_package_note_json":""]
|
||||
|
@ -1,21 +1,14 @@
|
||||
Name: package-notes
|
||||
Version: 0.4
|
||||
Version: 0.5
|
||||
Release: %autorelease
|
||||
Summary: Generate a linker script to insert .note.package section
|
||||
|
||||
%global forgeurl https://github.com/systemd/package-notes
|
||||
%forgemeta
|
||||
|
||||
License: CC0
|
||||
URL: %{forgeurl}
|
||||
Source0: %{forgesource}
|
||||
Summary: Generate LDFLAGS to insert .note.package section
|
||||
License: 0BSD
|
||||
|
||||
Source0: redhat-package-notes.in
|
||||
Source1: generate-rpm-note.sh
|
||||
Source2: macros.package-notes-srpm
|
||||
|
||||
BuildArch: noarch
|
||||
BuildRequires: python3-devel
|
||||
Requires: python3dist(simplejson)
|
||||
|
||||
%description
|
||||
This package provides a generator of linker scripts that insert a section with
|
||||
@ -24,33 +17,31 @@ for.
|
||||
|
||||
%package srpm-macros
|
||||
Summary: %{summary}
|
||||
Obsoletes: package-notes < 0.5
|
||||
# Those are minimum versions that implement --package-metadata
|
||||
Conflicts: binutils < 2.38-23
|
||||
Conflicts: binutils-gold < 2.38-23
|
||||
Conflicts: mold < 1.3.0
|
||||
|
||||
%description srpm-macros
|
||||
RPM macros to inject a linker script into link flags and a helper to generate
|
||||
a script that inserts a section with an ELF note with a JSON payload that
|
||||
describes the package the binary was built for.
|
||||
RPM macros to insert a section with an ELF note with a JSON payload that
|
||||
describes the package the binary was built for via compiler spec file.
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
|
||||
%build
|
||||
# nothing to do
|
||||
|
||||
%install
|
||||
install -Dt %{buildroot}%{_bindir}/ generate-package-notes
|
||||
install -m0644 -Dt %{buildroot}%{_mandir}/man1/ debian/generate-package-notes.1
|
||||
%build
|
||||
sed "s|@OSCPE@|$(cat /usr/lib/system-release-cpe)|" %{SOURCE0} > redhat-package-notes
|
||||
|
||||
# A partial reimplementation without Python
|
||||
%install
|
||||
install -Dt %{buildroot}%{_rpmconfigdir}/redhat/ redhat-package-notes
|
||||
install -Dt %{buildroot}%{_rpmconfigdir}/ %{SOURCE1}
|
||||
install -m0644 -Dt %{buildroot}%{_rpmmacrodir}/ %{SOURCE2}
|
||||
|
||||
%files
|
||||
%{_bindir}/generate-package-notes
|
||||
%{_mandir}/man1/generate-package-notes.1*
|
||||
|
||||
%files srpm-macros
|
||||
%{_rpmconfigdir}/generate-rpm-note.sh
|
||||
%{_rpmmacrodir}/macros.package-notes-srpm
|
||||
%{_rpmconfigdir}/redhat/redhat-package-notes
|
||||
|
||||
%changelog
|
||||
%autochangelog
|
||||
|
2
redhat-package-notes.in
Normal file
2
redhat-package-notes.in
Normal file
@ -0,0 +1,2 @@
|
||||
*link:
|
||||
+ --package-metadata={\"type\":\"rpm\",\"name\":\"%:getenv(RPM_PACKAGE_NAME \",\"version\":\"%:getenv(RPM_PACKAGE_VERSION -%:getenv(RPM_PACKAGE_RELEASE \",\"architecture\":\"%:getenv(RPM_ARCH \",\"osCpe\":\"@OSCPE@\"}))))
|
Loading…
Reference in New Issue
Block a user