Home / Alt manpages / pkgdata(1)

  • pkgdata(1)
  • User command
  • linux

Package ICU Resource Data with pkgdata

pkgdata turns a compiled ICU resource bundle into a small .dat archive. This walks you through building one and checking the result, without touching your original source files. Allow about 15 minutes for a simple test. This guide targets the pkgdata 74.2 shipped by Ubuntu's icu-devtools package; option details and build output can differ in other ICU releases.

1. Check the installed tool

Run this as your ordinary user. Packaging into a directory you own does not need root.

$ command -v pkgdata
/usr/bin/pkgdata
$ dpkg-query -W -f='${Package} ${Version}\n' icu-devtools
icu-devtools 74.2-1ubuntu3.1
$ pkgdata --help
usage: pkgdata [-options] [-] [packageFile]
...

The installed help is worth reading on its own: it exposes a few build options the older manual page does not mention, including --force-prefix and --without-assembly. This guide sticks to options confirmed by both the local manual page and the installed command. There is no --version option in this build, asking for one is simply an error, so use the package query above to pin down the version.

Checkpoint

You have /usr/bin/pkgdata and a recorded ICU package version.

2. Prepare a real ICU input file

pkgdata packages ICU binary data. A plain text file is not valid input for common mode, even if the command happily reads its name. For a harmless demo, compile one small resource bundle with the installed genrb tool:

$ workdir=/tmp/pkgdata-demo
$ mkdir -p "$workdir/source" "$workdir/res" "$workdir/out"
$ printf '%s\n' 'menu { title { "Example" } }' > "$workdir/source/menu.txt"
$ genrb -s "$workdir/source" -d "$workdir/res" menu.txt
$ find "$workdir/res" -maxdepth 1 -type f -printf '%f\n'
menu.res

The input to pkgdata is now menu.res. Keep the source directory and the generated resource directory separate, so a failed packaging attempt can never overwrite your source text.

If you already have ICU .res, .cnv or other supported binary data, use those instead. Do not grab an arbitrary application document as a test input: the resulting package has to actually contain ICU data objects.

Checkpoint

test -r /tmp/pkgdata-demo/res/menu.res succeeds, and the file is not something you would need to recreate from memory.

3. Build the default archive

Use common, also called archive, to build one architecture-dependent data file. Set the source and destination directories explicitly, and pass the input name relative to the source directory: an absolute path here gets misread as an old-style package path.

$ cd /tmp/pkgdata-demo/res
$ pkgdata --verbose \
    --mode common \
    --name demo \
    --sourcedir . \
    --destdir /tmp/pkgdata-demo/out \
    menu.res
# pkgdata: Reading menu.res..
# Writing package file /tmp/pkgdata-demo/out/demo.dat ..

--name demo controls the output name, so the result lands as demo.dat. common is already the default mode, but stating it makes the build script easier to review at a glance. The archive is architecture-dependent, as the manual says, and normally gets looked up through an ICU data directory or loaded via an ICU API.

Verify both the exit status and the output file:

$ test "$?" -eq 0
$ file /tmp/pkgdata-demo/out/demo.dat
/tmp/pkgdata-demo/out/demo.dat: ICU data file

The exact file description can vary. What matters is a zero exit status, a non-empty demo.dat, and no error from the packaging command.

Checkpoint

/tmp/pkgdata-demo/out/demo.dat exists and the original menu.res is unchanged.

4. Choose a packaging mode deliberately

The modes are not interchangeable output formats, so pick with intent:

  • common or archive makes one .dat package.
  • dll or library builds a shared library. The manual says this suits ICU itself or data linked into an application, not a general-purpose plug-in loaded at will.
  • static builds a static library for applications that link the data in directly.
  • files keeps the data as separate files, useful when a packaging workflow demands that, but it never produces a single archive.

For example, the same resource processed in files mode:

$ mkdir -p /tmp/pkgdata-demo/files
$ pkgdata --verbose --mode files --name demo \
    --sourcedir /tmp/pkgdata-demo/res \
    --destdir /tmp/pkgdata-demo/files \
    menu.res
# pkgdata: Reading menu.res..

In this mode the command lays out separate data files rather than writing demo.dat. Treat the destination as a staging directory, and inspect it before any installation step.

5. Install only after inspection

--install is a separate operational decision from building the archive: it decides where the data ends up. The manual documents DESTDIR as the installation prefix used by --install, but the installed help simply says to specify an installation target, and the exact invocation depends on the surrounding ICU build workflow. Do not point it at a live ICU data directory during an experiment. Use the same build inputs, a staging target your own user owns, and inspect the result before copying anything into a system location:

$ find /tmp/pkgdata-demo/stage -type f -printf '%p %s bytes\n'

If a real deployment needs a protected directory, stop here, review the staged files, and use your normal change process with the elevated privileges it requires. A failed package build can leave a partial destination behind; use a fresh staging directory for the next attempt rather than guessing which files are still safe to keep. The safe recovery for this demo is simply to abandon the temporary directory and rebuild into a new one. Never delete a system data directory as an undo step.

Common traps

  • "not an ICU data file" or an input access error: check that the input is actually compiled ICU data, and that the argument is relative to --sourcedir. Generate a resource with genrb, or use binary data your ICU build already produced.
  • Output lands in the wrong directory: remember --destdir controls the build destination, while --install performs installation. The default destination is the current directory, and the default temporary directory is the destination directory.
  • A rebuild seems to do nothing: use --rebuild to force rebuilding all data, when inputs or settings changed and the normal timestamp checks are not giving you what you expect.
  • A shared-library build fails: dll and static modes pull compiler and linker settings from ICU's build configuration. On this installation, pkgdata reads those from /usr/lib/x86_64-linux-gnu/icu/74.2/pkgdata.inc. Fix the ICU build environment first; sudo will not repair a missing compiler setting.
  • Unexpected package contents: use --verbose and read every input line. A package file can also be passed as an argument; the installed help describes it as a text file listing the files to package. Keep such a list under version control, or inspect it before running the command, since it defines exactly what goes in.

Done means

  • You confirmed the installed pkgdata version and read its help output.
  • Your inputs are valid ICU binary data, not arbitrary text files.
  • You built the intended mode with explicit source, destination and package name options.
  • You checked the exit status and inspected the generated file or staging tree.
  • You kept installation separate from packaging and never overwrote a live ICU data directory while testing.