Home / Alt manpages / makeconv(1)

  • makeconv(1)
  • User command
  • linux

Compile an ICU .ucm Converter Table with makeconv

makeconv turns an ICU Unicode Codepage Mapping file, normally ending in .ucm, into the binary .cnv file that ICU can actually load. You will compile a real table into a separate directory, inspect the output, and see where installation and packaging take over from here. The examples use ICU 74.2 as shipped by Ubuntu's icu-devtools package. Allow about 10 minutes if you already have a valid table.

Before You Start

You need the makeconv executable and a source table in ICU UCM format. On this machine both come from icu-devtools version 74.2-1ubuntu3.1, so check that before relying on behaviour from another release:

dpkg-query -W -f='${Package} ${Version}\n' icu-devtools
makeconv --version

The installed command reports tool version 6.2 even though the Debian package is version 74.2. The local manual is the authority for the documented interface: it lists -h, -?, --help, -c, -v, and -d. This guide sticks to those portable options. The binary's own help output lists newer or build-specific options too, but they sit outside the documented contract used here.

A UCM file is input data, not generic text: it must contain the headers and mappings ICU requires. If you are creating one, start from a known-good ICU table and check the UCM format documentation. Do not edit a production table in place for a first attempt.

1. Put the Source and Output in a Scratch Area

Use a work directory with nothing valuable in it. Swap in your own verified table; this example downloads no data and assumes the file already exists:

mkdir -p "$HOME/icu-converter-test/input" "$HOME/icu-converter-test/output"
cp /path/to/example.ucm "$HOME/icu-converter-test/input/"
cd "$HOME/icu-converter-test"
ls -l input/example.ucm

Expect one readable file with a non-zero size. The command needs no elevated privileges. Keep the original outside the output directory so a failed compile cannot replace it.

2. Compile the Table Into a Chosen Directory

Pass the UCM path as the final argument and pick the destination with -d. The output keeps the source base name and swaps its extension for .cnv:

makeconv -v \
  -d "$HOME/icu-converter-test/output" \
  "$HOME/icu-converter-test/input/example.ucm"

With a valid table, verbose mode prints progress and a final write message; the exact text varies with the table and tool build. Check the result rather than treating a quiet terminal as proof:

test -s "$HOME/icu-converter-test/output/example.cnv" && \
  file "$HOME/icu-converter-test/output/example.cnv" && \
  printf '%s\n' 'converter compiled'

A normal result is a non-empty data file and the final line converter compiled. Do not try to read the binary as text. Its base name matters, because ICU uses both the converter name stored inside the table and the generated filename.

Checkpoint: Confirm the First Build

  • Source still there. The original exists under input/.
  • Name matches. The output has the same base name with a .cnv suffix.
  • Output is real. It is non-empty and written to the directory you chose with -d.

The -c option bakes a copyright notice into the binary data. It does not repair a table, install a converter, or change the mapping. Use it when the notice is part of your distribution requirement:

rm -f "$HOME/icu-converter-test/output/example.cnv"
makeconv -c -v \
  -d "$HOME/icu-converter-test/output" \
  "$HOME/icu-converter-test/input/example.ucm"
test -s "$HOME/icu-converter-test/output/example.cnv"

That removal only targets the generated scratch output. Do not copy the pattern into a shared data directory without checking the exact filename first. To undo this experiment entirely, inspect the scratch files, then remove the directory:

find "$HOME/icu-converter-test" -maxdepth 2 -type f -print
rm -r "$HOME/icu-converter-test"

Removing a generated file is reversible only as long as the UCM source survives. A converter already installed into an ICU data directory may also be part of a package or archive, so deleting the standalone file may not change what applications actually load.

4. Install Only After Deciding How ICU Will Load It

The manual says the default destination is the directory named by ICU_DATA. If you set that variable, include its trailing slash. You can inspect the intended directory without changing anything:

printf 'ICU_DATA=%s\n' "${ICU_DATA:-not set}"
makeconv -v -d /path/to/icu-data/ /path/to/example.ucm

That second command writes into the specified data directory and may therefore need elevated privileges. Stop and check ownership, package management and backups before reaching for sudo. Prefer a private data directory while testing:

mkdir -p "$HOME/icu-converter-test/icu-data"
ICU_DATA="$HOME/icu-converter-test/icu-data/" \
  makeconv -v "$HOME/icu-converter-test/input/example.ucm"
test -s "$HOME/icu-converter-test/icu-data/example.cnv"

Do not assume that placing a standalone file beside packaged ICU data overrides an archive or shared library. If the converter was originally grouped with pkgdata, rebuild that package with the replacement .cnv file. A generated file on its own is not a complete installation plan.

5. Diagnose Failures Without Overwriting Anything

A missing conversion type, malformed header, invalid mapping, unreadable input, or unwritable destination causes a non-zero failure and no usable result. Start with the complete command and its error text:

makeconv -v -d "$HOME/icu-converter-test/output" \
  "$HOME/icu-converter-test/input/example.ucm"
printf 'exit status: %s\n' "$?"

If the error mentions UCM structure, compare the file with a table from the ICU data repository and check required headers such as the converter class, minimum and maximum character width, and substitution character. If it mentions the destination, check permissions and free space, then use a fresh scratch directory. If the compile succeeds but an application still cannot find the converter, check that application's ICU data directory and whether it reads a packaged data archive instead.

Do not solve an input error by adding a converter alias. The manual keeps compilation and aliases separate: a newly installed converter is found by ICU on its own, while convrtrs.txt is needed for extra aliases or tags. Treat alias configuration and binary compilation as two different changes.

Done means

  • Confirmed the version. You identified the local ICU package and tool version.
  • Compiled successfully. A valid .ucm source produced a non-empty .cnv file.
  • Kept the source safe. The output directory was verified and the original UCM file preserved for recovery.
  • Know where it loads from. You know whether the consuming application reads standalone data or a packaged ICU archive.