FS#71948 - [nvidia-utils] create_links() method in PKGBUILD causes nvidia-utils to fail in unique circumstances

Attached to Project: Arch Linux
Opened by solonovamax (solonovamax) - Sunday, 29 August 2021, 22:07 GMT
Last edited by Sven-Hendrik Haase (Svenstaro) - Tuesday, 22 February 2022, 10:36 GMT
Task Type Bug Report
Category Packages: Extra
Status Closed
Assigned To Sven-Hendrik Haase (Svenstaro)
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 1
Private No

Details

Description:
The `nvidia-utils` base package will fail to build when the path in which it is built contains `so`, and one of the shared libraries doesn't print a "Library soname" entry on `readelf -d`.

This occurs due to the sed regex using the wildcard character, `.`, instead of the escaped dot character, `\.`. Additionally, this issue only occurs when one of the shared libraries *doesn't* have a `Library soname` entry, so it makes sense that nobody had encountered this before me.

Here is `readelf -d` output on the shared library which produced this error for me: (useless stuff trimmed)

```
Dynamic section at offset 0x3e20 contains 24 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libEGL_nvidia.so.0]
0x0000000000000001 (NEEDED) Shared library: [libEGL.so.1]
0x0000000000000001 (NEEDED) Shared library: [libnvidia-egl-wayland.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]

[ other garbage ... ]
```

As you can see, there is no `Library soname: [...]` entry, as there should be.

This causes the `_base=$(echo ${_soname} | sed -r 's/(.*).so.*/\1.so/')` expression to be evaluated to, in my case, `/home.so` (as my username is `solonovamax`, so the path contains `/home/solonovamax/...`, and the fault sed regex matches `/home/so`, replacing it with `/home.so`.


This happened to me when building the AUR package `nvidia-dkms-performance`, so I took this opportunity to rewrite the `create_links()` function to be slightly more robust, so that it should avoid this, and possibly future, errors. I submitted a patch to that package, and they merged it and suggested I also submit a patch to the `nvidia-utils` package since that's where it was derived from, so here I am.

Here is a patch for the PKGBUILD:

```
--- PKGBUILD.old 2021-08-29 17:33:12.240556832 -0400
+++ PKGBUILD 2021-08-29 17:32:21.807128590 -0400
@@ -22,9 +22,25 @@
create_links() {
+ _orig_dir="$(pwd)"
+
# create soname links
find "$pkgdir" -type f -name '*.so*' ! -path '*xorg/*' -print0 | while read -d $'\0' _lib; do
- _soname=$(dirname "${_lib}")/$(readelf -d "${_lib}" | grep -Po 'SONAME.*: \[\K[^]]*' || true)
- _base=$(echo ${_soname} | sed -r 's/(.*).so.*/\1.so/')
- [[ -e "${_soname}" ]] || ln -s $(basename "${_lib}") "${_soname}"
- [[ -e "${_base}" ]] || ln -s $(basename "${_soname}") "${_base}"
+ _dirname="$(dirname "${_lib}")"
+ _original="$(basename "${_lib}")"
+ _soname="$(readelf -d "${_lib}" | grep -Po 'SONAME.*: \[\K[^]]*' || true)"
+ _base="$(echo ${_soname} | sed -r 's/(.*)\.so.*/\1.so/')"
+
+ cd "${_dirname}"
+
+ if ! [[ -z "${_soname}" ]]; then # if not empty
+ if ! [[ -e "./${_soname}" ]]; then
+ ln -s $(basename "${_lib}") "./${_soname}"
+ fi
+ fi
+ if ! [[ -z "${_base}" ]]; then # if not empty (if _soname is empty, _base should be too)
+ if ! [[ -e "./${_base}" ]]; then
+ ln -s "./${_soname}" "./${_base}"
+ fi
+ fi
done
+ cd "${_orig_dir}"
}
```
This task depends upon

Closed by  Sven-Hendrik Haase (Svenstaro)
Tuesday, 22 February 2022, 10:36 GMT
Reason for closing:  Fixed
Additional comments about closing:  Applied in svn
Comment by solonovamax (solonovamax) - Sunday, 29 August 2021, 22:27 GMT
pain I can't use markdown
Comment by Sven-Hendrik Haase (Svenstaro) - Wednesday, 13 October 2021, 03:31 GMT
Could you attach the patch as a file instead?
Comment by solonovamax (solonovamax) - Wednesday, 27 October 2021, 03:12 GMT
@Svenstaro

Here you go
Comment by Jonathon (jonathon) - Tuesday, 02 November 2021, 13:44 GMT
That patch can possibly be compressed a little (attached).
Comment by solonovamax (solonovamax) - Thursday, 11 November 2021, 17:13 GMT
I forgot about pushd and popd while writing that. Yeah, everything in that new patch @jonathon linked looks fine to me, as the only changes were minimal.
Comment by Jonathon (jonathon) - Thursday, 11 November 2021, 17:32 GMT
As feedback, I implemented this for the 390xx and 470xx AUR packages and it's working fine. Thanks solonovamax! :)
Comment by Jonathon (jonathon) - Thursday, 11 November 2021, 23:03 GMT
Actually, something isn't right - DKMS build can fail with multiple kernels. Digging more.

Something in the above patch seems to cause DKMS to enter the wrong kernel libs directory when building for kernels after the first, leading to an incorrect configure step and then on to a build failure.
Comment by Sven-Hendrik Haase (Svenstaro) - Tuesday, 16 November 2021, 06:24 GMT
jonathon, got anything new for me here? I'm fine with adding this but it should work in all circumstances. :)
Comment by Jonathon (jonathon) - Tuesday, 16 November 2021, 17:37 GMT
Not as yet - I reverted back to the current implementation but did add the smaller tweak to escape the . as suggested in the change, `_base="$(echo ${_soname} | sed -r 's/(.*)\.so.*/\1.so/')"`

This works fine so far; I haven't circled back around to the full set of changes.
Comment by Sven-Hendrik Haase (Svenstaro) - Sunday, 20 February 2022, 03:36 GMT
If you have a final known-good patch for me I might apply it. Otherwise the current command seems to work well enough for our purposes.
Comment by Jonathon (jonathon) - Tuesday, 22 February 2022, 00:37 GMT
I think the attached minimal change is a useful step; it's not the full extent of the proposed patch but minimally invasive and in use (and so tested) by other NVIDIA packages in the AUR (e.g. beta, 470xx, 390xx).

Loading...