[Bug 258372] x11-fonts/fontconfig: cannot install as user (into non-default prefix)

From: <bugzilla-noreply_at_freebsd.org>
Date: Fri, 27 Jan 2023 13:12:19 UTC

--- Comment #6 from John Hein <jcfyecrayz@liamekaens.com> ---
(In reply to Gerald Pfeifer from comment #4)
> Does /var/db/fontconfig exist on your system? If so, that might explain
> why it does not try to generate that directory, whereas it does it in my
> case - and fails.

Yes, /var/db/fontconfig did exist in my previous testing.  When I move it away
and re-install ('make -C x11-fonts/fontconfig INSTALL_AS_USER=1
LOCALBASE=/usr/local.user PKG_DBDIR=/usr/local.user/var/db/pkg
PORT_DBDIR=/usr/local.user/var/db/ports reinstall'), it fails with 'pkg: Fail
to create /var/db/fontconfig:Permission denied' as described in comment 0.

So the pkg-create(8) man page where @dir is described is incomplete (IMO).  It
only discusses what happens when the pkg is deleted.  It omits any description
about behavior on pkg install.  One could read that the implication of that
omission is that nothing is done at install.  But that does not appear to be a
correct interpretation of that omission.  To be more clear, the pkg-create(8)
man page could describe @dir behavior at install time.

So, given confirmation of that error, what should fontconfig (or other ports
per comment 1) do for @dir entries that point explicitly to directories where
the user does not have write permission when INSTALL_AS_USER is set?

Some possible courses of action:

  (1) Change the pkg tool. pkg could warn instead of fail for @dir creation (or
deletion?) failures if INSTALL_AS_USER is set.  pkg already looks for

    o Skip chflags
    o Skip chown
    o Skip checks that fail if the pkg db file is not owned by root. Perhaps
that check is not needed, or should not trigger an exit at the point of the
check anyway.  The pkg tool will not be able to write to the db file if the
user does not have the appropriate permissions, so just let pkg fail naturally
when it does the write attempt.  The check could remain and just emit a warning
(instead of being fatal if the check fails) regardless of INSTALL_AS_USER.

  (2) Modify plist for INSTALL_AS_USER.  Ports that have @dir entries that
point to non-user directories, could have a plist that sets a different value
for the @dir directory.  Maybe <localbase>/var/db/fontconfig in this case, for
instance.  What defines a "non-user" directory is not obvious, however -
anything outside PREFIX? anything outside LOCALBASE?  Maybe there could be an
INSTALL_AS_USER_ROOT variable where such plist entries would go (instead of the
default /) when using INSTALL_AS_USER.

  (3) A variant of (2)... allow currently hard-coded directories in the plist
like /var/db/fontconfig to be defined by a make variable (instead of
hard-coded).  For example, have the plist entry be something like @dir
%%FONTCONFIG_DB%% and define FONTCONFIG_DB in PLIST_SUB.  This would default to
/var/db/fontconfig, of course - and maybe it could default to
${LOCALBASE}/var/db/fontconfig if INSTALL_AS_USER is set.

  (4) Continue with existing behavior (but document it).  If INSTALL_AS_USER is
set, expect that @dir directories are in a parent directory that is expected to
be writable by the install user.  This is effectively what is done now.  But
that policy is likely just an implicit or even just accidental policy - it
could be explicitly spelled out in the @dir documentation.

(2) and (3) would be per-port modifications (as opposed to a change to the
ports framework or the pkg tool).  There could be another variant of (2) or (3)
that could be defined by the framework so individual ports affected by this
issue would not need to be modified one by one.  For instance, when a
hard-coded absolute path is an argument to @dir (or maybe an absolute path that
is outside of PREFIX / LOCALBASE?), the plist generation step in bsd.port.mk
could be modified to change the @dir entry to, say, '@dir <localbase>/dir' when
INSTALL_AS_USER is set.  Or the pkg tool could be modified to do something
similar (I don't like that as well, however - pkg should just do what the plist
says to do, so the plist should be modified as needed before being passed to

If we don't want to define a global policy for @dir when INSTALL_AS_USER is set
(i.e., modify the framework or pkg tool for these cases), I think I prefer (3)
for each affected port at this time.

If we do want to implement something that does not requiring changes for every
affected port, I think I prefer (2) - specifically modifying generate-plist in
bsd.port.mk to detect absolute path @dir entries that are outside PREFIX or
LOCALBASE and prepend ${INSTALL_AS_USER_ROOT} (any potential better name
suggestion for that is welcome).

You are receiving this mail because:
You are the assignee for the bug.