[MacPorts] #74261: Symlinked prefix and Python ports
MacPorts
noreply at macports.org
Wed Jul 29 12:33:55 UTC 2026
#74261: Symlinked prefix and Python ports
-------------------------+--------------------
Reporter: RJVB | Owner: (none)
Type: enhancement | Status: new
Priority: Normal | Milestone:
Component: contrib | Version:
Keywords: | Port:
-------------------------+--------------------
I've been using MacPorts with the standard `$prefix` a symlink pointing to
a different partition since I started using MacPorts (a long time ago),
despite the fact that it was never supported. For the most part this has
worked without problems (I apply a small patch to "base" so that `port
provides` works 99.9% of the time). I can install prebuilt binary packages
thanks to how Unix handles symlinks. Building packages from source of
course creates binaries with the actual path to dependencies hardcoded,
thanks to Darwin's annoyingly unavoidable path normalisation, but that's
not an issue as long as I don't plan to distribute my builds.
I see that the "officially unsupported" policy has changed a bit since or
because of e.g. issue #69327, which is why I thought I'd come out of the
closet and create this ticket.
A recent update to the Python PG and/or Python's own code for installing
packages introduced a nuisance. Somewhere, the normalised `$prefix` is
injected as the install location and I thus end up with a `$destroot`
containing, in my case, `/Volumes/Debian/MP9` instead of `/opt/local`.
Which of course raises a warning about a layout violation.
It would of course be nice to fix the issue at the source (it seems like
something that upstream might consider a bug, and I would in fact not be
surprised that it's related to what caused #69327). That would require
knowing where the issue arises though, and I have no idea how to triage
that.
Avoiding the consequences via a mod of the Python PG turned out to be
deceptively simple though ''(for a `$prefix` where the symlink is the last
path component)'', and might be a workaround that could evolve into a more
generic modification for "base" itself. The idea is to recreate the actual
configuration at the start of the destroot phase, and then standardise
that back at the end of the phase.
So I added this at the start of the existing `pre-destroot`:
{{{
# See if we have a symlinked $prefix, and if so replicate the set-up
under $destroot
if {[file type ${prefix}] eq "link" && [file type
${destroot}${prefix}] eq "directory"} {
set realprefix [realpath ${prefix}]
if {![file exists ${destroot}${realprefix}]} {
xinstall -m 755 -d ${destroot}[file dirname ${realprefix}]
# ${destroot}${prefix} will have been populated by now, and we
want to preserve that tree.
# So rename it to the actual name it's supposed to have (this
should all be on the same FS!)
file rename ${destroot}${prefix} ${destroot}${realprefix}
# we should now have a directory ${destroot}[file dirname
${prefix}] !
ln -sf ${destroot}${realprefix} ${destroot}${prefix}
ui_warn "\t had to make \$destroot${prefix} a symlink to
\$destroot${realprefix}"
}
}
}}}
and this at the start of the existing `post-destroot`:
{{{
# See if we have to restore the correct $prefix
if {[file type ${prefix}] eq "link" && [file type
${destroot}${prefix}] eq "link"} {
set realprefix [realpath ${prefix}]
file delete ${destroot}${prefix}
file rename ${destroot}${realprefix} ${destroot}${prefix}
ui_warn "\t restored the symlink-to-be \$destroot${prefix}
from \$destroot${realprefix}"
}
}}}
Problem solved ...
As said, this was designed for a `$prefix` where the last component (i.e.
`local`) is a symlink, but I *think* that the implementation will work for
any `$prefix` that has a symlink somewhere in its path. During the
workaround, the symlinked `${destroot}${prefix}` is there only for ports
that also install files to that expected `${destroot}${prefix}` path (IIRC
`port:py-cython` does).
So all that might be needed to generalise this workaround could be to
replace the initial `[file type ${prefix}] eq "link"` check with
`[realpath ${prefix}] ne ${prefix}`.
----
Ahhh, if only Darwin had a proper "bind mount" feature, allowing any
directory to be mounted elsewhere...!
--
Ticket URL: <https://trac.macports.org/ticket/74261>
MacPorts <https://www.macports.org/>
Ports system for macOS
More information about the macports-tickets
mailing list