---
name: "update-plist"
section: "1"
platform: "openbsd"
package: "man"
version: "8.0-current-20261101"
release: "OpenBSD 8.0-current (2026-11-01)"
platforms: ["openbsd"]
url: "https://new.carta.tech/update-plist"
---

# update-plist(1)

create or update packing-list(s) for a given port

## NAME

**update-plist** – create or update packing-list(s) for a given port

## SYNOPSIS

PORTSDIR=*path*

\[FAKE\_TREE\_OWNER=*user* PORTS\_TREE\_OWNER=*user* **doas**\]

**update-plist** \[**-Ffmnqrvx**\] \[**-C** *dir*\] \[**-c** *var*\] \[**-E** *ext*\] \[**-e** *ext*\] \[**-I** *var*\] \[**-i** *var*\] \[**-j** *jobs*\] \[**-S** *var*\] \[**-s** *var*\] \[**-X** *path*\] \[**-w** *suffix*\] **--** *pkg\_create\_args* *...*

## DESCRIPTION

**update-plist** is a helper script for the target *update-plist* in [bsd.port.mk(5)](/bsd.port.mk/5.md).

Along with options and environment variables, **update-plist** uses the exact same options and arguments that would be passed to [pkg\_create(1)](/pkg_create/1.md). Since [pkg\_create(1)](/pkg_create/1.md) normally takes one single actual *pkgname*, there is no ambiguity in MULTI\_PACKAGES situations.

The first set of arguments correspond to the ‘default package’.

If PORTS\_PRIVSEP is in effect, **update-plist** is run as root, but will switch back to FAKE\_TREE\_OWNER for scanning the installation directory and to PORTS\_TREE\_OWNER for writing packing-lists.

**update-plist** may need to know the PORTSDIR location in order to scan dependencies to trim common directories.

The options are as follows:

- **-C** *dir*

  Use a cache directory *dir* for scanning dependencies. Beware that this directory should then be cleaned manually if the dependencies's packing-lists change. But this will speed up packing-list regeneration for ports with lots of dependencies significantly.

- **-c** *var*

  Variable *var* may be used as a way to insert **@**comment when other variables vanish.

- **-E** *ext*

  Write new files with *ext* extension instead of the default *.new*.

- **-e** *ext*

  Preserve old files as *ext* extension instead of the default *.orig*.

- **-F**

  Do not try to run pkg\_locate(1).

- **-f**

  Force pkg\_locate(1) to look up every file for conflicts instead of just the new ones.

- **-I** *var*

  Variable *var* may expand to nothing, in which case the variable from **-c** *var* can be used to prevent duplicate entries.

- **-i** *var*

  Ignore variable *var* for new substitutions. Only existing substitutions will be considered for the new lists.

- **-j** *jobs*

  Use *jobs* concurrent pkg\_locate(1) pipes. Default is ‘hw.ncpuonline’.

- **-n**

  Do not move the final packing-lists in position. Instead, leave the *\<file\>.new* files for comparison.

- **-q**

  Quiet mode. Do not display status progress messages. Note that this is not the opposite of verbose mode.

- **-r**

  Run the *fake* directory scan as root.

- **-S** *var*

  Consider variable for substitution only at the end of paths, e.g., for suffixes like *.pyc* or *.pyo*.

- **-s** *var*

  Consider variable for substitution only at start of paths, e.g., for directories like */etc/rc.d* or */usr/local*.

- **-v**

  Verbose mode. Explain about directories stripped from dependencies. Note that this is not the opposite of quiet mode.

- **-w** *suffix*

  Warn about suffixes such as *.orig* that (usually) should not end into packing-lists.

- **-X** *path*

  Exclude file at absolute *path* from the information recorded in the packing-list.

**update-plist** assumes all multi-packages live under the same installation directory( [pkg\_create(1)](/pkg_create/1.md)'s **-B** option), and it will scan all paths under that directory and dispatch them into corresponding subpackages, using the following heuristics:

- files that were in existing packing-list(s) will be kept in the same packing-list.

- new files and directories will be put in the packing-list that owns the corresponding directory.

- barring that, new files will be put into the first packing-list whose PREFIX fits.

As far as possible, everything that looks like actual files will be sorted in alphabetical order, after variable substitutions.

**update-plist** will warn for a lot of conditions, such as pre-formatted manpages, or files ending in pre-patch suffixes. Adding a **@comment** *intentional\<reason\>* will silence the warning. For instance:

```
@man man/ja_JP.EUC/cat1/kakasi.0
@comment intentional: mandoc doesn't handle this locale
```

**update-plist** will also scan dependencies, in order to strip common directories.

If the *pkglocatedb* package is installed, **update-plist** will make use of it and report unregistered conflicts. This can be disabled with **-F** as it is time-consuming.

Most SUBST\_VARS variables will be back-substituted into the regenerated packing-lists, starting from the longest variable values. **update-plist** tries to keep existing substitutions. It does not add new substitutions on BASE\_PKGPATH and BUILD\_PKGPATH, it does only substitute FULLPKGNAME in *share/doc/pkg-readmes* and it currently does not add new substitutions for ARCH nor MACHINE\_ARCH.

Some packages (notoriously Python packages) create some directories optionally based on flavors. Options **-c** and **-I** can be used to avoid duplicate directory definitions.

Specifically, a generated packing-list would contain

```
lib/python${MODPY_VERSION}/site-packages/bpdb/
lib/python${MODPY_VERSION}/site-packages/bpdb/${MODPY_PYCACHE}/
```

which expands to

```
lib/python3.7/site-packages/bpdb/
lib/python3.7/site-packages/bpdb/__pycache__/
```

for python3, which is fine.

But for python2, variable ‘MODPY\_PYCACHE’ will be empty, resulting in

```
lib/python2.7/site-packages/bpdb/
lib/python2.7/site-packages/bpdb/
```

thus a duplicate directory, [pkg\_create(1)](/pkg_create/1.md) won't be happy.

Using UPDATE\_PLIST\_ARGS = **-c** *MODPY\_COMMENT* **-I** *MODPY\_PYCACHE* will result in injecting ‘${MODPY\_COMMENT}’ wherever **update-plist** finds a duplicate directory by replacing ‘${MODPY\_PYCACHE}’ with nothing.

This yields

```
lib/python${MODPY_VERSION}/site-packages/bpdb/
${MODPY_COMMENT}lib/python${MODPY_VERSION}/site-packages/bpdb/MODPY_PYCACHE}/
```

and for python2 this expands to

```
lib/python2.7/site-packages/bpdb/
@comment lib/python2.7/site-packages/bpdb/
```

which is exactly what we want.

Specific items such as shared libraries or binaries will gain annotations and special handling, for instance LIBlibname\_VERSION.

Existing packing-lists are scanned for non-file entries, such as **newuser**, **mode**, or **exec** markers. Those will be inserted into the updated packing-lists at the most likely position.

**update-plist** will first write files as *\<file\>.new*, then it will display which files are new and which files have changed. If old packing-lists already exist, it will move old packing lists into *\<file\>.orig*, then move the new files into position.

## SEE ALSO

pkg\_add(1), [pkg\_create(1)](/pkg_create/1.md), [bsd.port.mk(5)](/bsd.port.mk/5.md)

## BUGS AND LIMITATIONS

**update-plist** might be the most complicated piece of the ports infrastructure. There will always be cases that require manual intervention. Since *fake* is now run as non-root, **update-plist** can't figure out users and groups for new files, so these should be considered carefully.
