Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@

## [Unreleased]

### Fixed

- **两处只有把 glx 那一版真正跑一遍才会现形的缺陷。** 上一轮我量了 opencl 和
vulkan,`compat.glx-runtime` 的新逻辑**从头到尾没有被执行过**。

⚠️⚠️ **`DT_NEEDED` 里可以是绝对路径。** 这个 farm 的四个 glvnd 厂商入口
(`libEGL_nvidia`、`libGLESv1_CM_nvidia`、`libGLESv2_nvidia`、`libGLX_nvidia`)
直接写着 `/lib/x86_64-linux-gnu/...`。loader 对这类条目直接打开、**完全不走
搜索路径**,所以 farm 既服务不了它也不该为它封 unserved —— 而把它当 soname 会
去查一个带斜杠的名字,并且造出一个**名字是路径**的 unserved 链接。三个包一并
跳过这类条目。

⚠️ **找不到 `readelf` 时那一趟静默返回空**,读数与「farm 已完全闭合」一模一样。
这正是这批改动要消灭的那种混淆,只是掉到了工具查找这一层。现在会明确告警,
并且 `compat.glx-runtime` 的工具查找也和另外两个一样**先查 store 再查 PATH**
—— 这个包跑在从未被要求装工具链的机器上。

实测(本机,对着已装的 glx farm 走同一套逻辑):52 个成员、跳过 4 条绝对路径、
19 条需补,**19 条全部来自生态载荷,0 条 unserved**,没有路径形状的条目。

### Changed

- **`compat.vulkan` 1.4.357.1 —— 移动一个钉,需要一个新版本。**
Expand Down
45 changes: 44 additions & 1 deletion pkgs/c/compat.glx-runtime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,21 @@ end
-- the host, cannot load it. `readelf -d` answers what the FILE says, and
-- membership is decided against this directory alone, which is the question
-- mcpp asks of it.
-- The store first, PATH second. Under xlings a payload's own binutils is the
-- one that matches the objects being read, and a host `readelf` may simply not
-- be installed -- this package runs on machines that were never asked to have a
-- toolchain. compat.opencl-runtime and compat.vulkan-runtime look the same way.
local function find_tool(name)
for _, root in ipairs(xim_store_roots()) do
local f = io.popen(string.format(
[[ls -1 "%s"/xim-x-binutils/*/bin/%s "%s"/xim-x-gcc/*/bin/%s 2>/dev/null | sort -V | tail -1]],
root, name, root, name))
if f then
local hit = (f:read("l") or ""):gsub("[\r\n]+$", "")
f:close()
if hit ~= "" then return hit end
end
end
local f = io.popen(string.format([[command -v %s 2>/dev/null]], name))
if f then
local hit = (f:read("l") or ""):gsub("[\r\n]+$", "")
Expand All @@ -290,7 +304,20 @@ end

local function unresolved_against_farm(outdir)
local readelf = find_tool("readelf")
if not readelf then return {} end
-- A MISSING TOOL IS NOT AN EMPTY ANSWER.
--
-- Returning `{}` here would report "no member needs anything this farm
-- lacks", which is the reading a fully closed farm produces -- so the one
-- environment where this pass cannot run would be indistinguishable from
-- the one where it ran and found nothing. That is the confusion this whole
-- change exists to remove, one layer down, in the tool lookup.
if not readelf then
log.warn("compat.glx-runtime: readelf was not found, so the farm's own members were "
.. "not checked. This is NOT the same as finding no gaps: "
.. "install xim:binutils, or read HOST-SURFACE.txt with the "
.. "knowledge that it is incomplete.")
return {}
end
local have, members = {}, {}
local lsf = io.popen(string.format([[ls -1 "%s" 2>/dev/null]], outdir))
if not lsf then return {} end
Expand All @@ -307,10 +334,26 @@ local function unresolved_against_farm(outdir)
if f then
for line in f:lines() do
local n = line:gsub("[\r\n]+$", "")
-- AN ABSOLUTE `DT_NEEDED` NEVER GOES THROUGH A SEARCH PATH.
--
-- The loader opens it directly, so this farm can neither serve
-- it nor honestly record it as unserved -- and treating it as a
-- soname produces a lookup for a name with slashes in it and,
-- worse, an `unserved` link whose name is a path. Measured on
-- this farm: four members -- the glvnd vendor entries
-- `libEGL_nvidia`, `libGLESv1_CM_nvidia`, `libGLESv2_nvidia`
-- and `libGLX_nvidia` -- name `/lib/x86_64-linux-gnu/...`
-- outright. They are a host reach that bypasses everything this
-- package arranges, which is worth knowing and is not this
-- pass's to answer.
if n:sub(1, 1) == "/" then
goto continue
end
if n ~= "" and not have[n] and not never_farm[n] and not seen[n] then
seen[n] = true
out[#out + 1] = n
end
::continue::
end
f:close()
end
Expand Down
31 changes: 30 additions & 1 deletion pkgs/c/compat.opencl-runtime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,20 @@ end
-- one is how a farm's own check passes while its consumer's does not.
local function unresolved_against_farm(outdir)
local readelf = find_tool("readelf")
if not readelf then return {} end
-- A MISSING TOOL IS NOT AN EMPTY ANSWER.
--
-- Returning `{}` here would report "no member needs anything this farm
-- lacks", which is the reading a fully closed farm produces -- so the one
-- environment where this pass cannot run would be indistinguishable from
-- the one where it ran and found nothing. That is the confusion this whole
-- change exists to remove, one layer down, in the tool lookup.
if not readelf then
log.warn("compat.opencl-runtime: readelf was not found, so the farm's own members were "
.. "not checked. This is NOT the same as finding no gaps: "
.. "install xim:binutils, or read HOST-SURFACE.txt with the "
.. "knowledge that it is incomplete.")
return {}
end
local have, members = {}, {}
local lsf = io.popen(string.format([[ls -1 "%s" 2>/dev/null]], outdir))
if not lsf then return {} end
Expand All @@ -419,10 +432,26 @@ local function unresolved_against_farm(outdir)
if f then
for line in f:lines() do
local n = line:gsub("[\r\n]+$", "")
-- AN ABSOLUTE `DT_NEEDED` NEVER GOES THROUGH A SEARCH PATH.
--
-- The loader opens it directly, so this farm can neither serve
-- it nor honestly record it as unserved -- and treating it as a
-- soname produces a lookup for a name with slashes in it and,
-- worse, an `unserved` link whose name is a path. Measured on
-- this farm: four members -- the glvnd vendor entries
-- `libEGL_nvidia`, `libGLESv1_CM_nvidia`, `libGLESv2_nvidia`
-- and `libGLX_nvidia` -- name `/lib/x86_64-linux-gnu/...`
-- outright. They are a host reach that bypasses everything this
-- package arranges, which is worth knowing and is not this
-- pass's to answer.
if n:sub(1, 1) == "/" then
goto continue
end
if n ~= "" and not have[n] and not never_farm[n] and not seen[n] then
seen[n] = true
out[#out + 1] = n
end
::continue::
end
f:close()
end
Expand Down
31 changes: 30 additions & 1 deletion pkgs/c/compat.vulkan-runtime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,20 @@ end
-- one is how a farm's own check passes while its consumer's does not.
local function unresolved_against_farm(outdir)
local readelf = find_tool("readelf")
if not readelf then return {} end
-- A MISSING TOOL IS NOT AN EMPTY ANSWER.
--
-- Returning `{}` here would report "no member needs anything this farm
-- lacks", which is the reading a fully closed farm produces -- so the one
-- environment where this pass cannot run would be indistinguishable from
-- the one where it ran and found nothing. That is the confusion this whole
-- change exists to remove, one layer down, in the tool lookup.
if not readelf then
log.warn("compat.vulkan-runtime: readelf was not found, so the farm's own members were "
.. "not checked. This is NOT the same as finding no gaps: "
.. "install xim:binutils, or read HOST-SURFACE.txt with the "
.. "knowledge that it is incomplete.")
return {}
end
local have, members = {}, {}
local lsf = io.popen(string.format([[ls -1 "%s" 2>/dev/null]], outdir))
if not lsf then return {} end
Expand All @@ -834,10 +847,26 @@ local function unresolved_against_farm(outdir)
if f then
for line in f:lines() do
local n = line:gsub("[\r\n]+$", "")
-- AN ABSOLUTE `DT_NEEDED` NEVER GOES THROUGH A SEARCH PATH.
--
-- The loader opens it directly, so this farm can neither serve
-- it nor honestly record it as unserved -- and treating it as a
-- soname produces a lookup for a name with slashes in it and,
-- worse, an `unserved` link whose name is a path. Measured on
-- this farm: four members -- the glvnd vendor entries
-- `libEGL_nvidia`, `libGLESv1_CM_nvidia`, `libGLESv2_nvidia`
-- and `libGLX_nvidia` -- name `/lib/x86_64-linux-gnu/...`
-- outright. They are a host reach that bypasses everything this
-- package arranges, which is worth knowing and is not this
-- pass's to answer.
if n:sub(1, 1) == "/" then
goto continue
end
if n ~= "" and not have[n] and not never_farm[n] and not seen[n] then
seen[n] = true
out[#out + 1] = n
end
::continue::
end
f:close()
end
Expand Down
Loading