m4(1) on Solnix vs Linux and the BSDs
On a default Solnix system, m4 is the illumos m4 at /usr/bin/m4, which has only -e, -s, -B, -H, -S, -T, -D and -U and no long options. The published Solnix page is for GNU m4 (pkgs.solnix.m4), so GNU-style options such as -P, -I, -d, -t and -E are not available in the default m4.
The manual pages
What Solnix runs
The published m4(1) page comes from pkgs.solnix.m4 and documents GNU M4 1.4.19. What /usr/bin/m4 runs by default is the illumos m4, which has a different, much smaller option set. /usr/xpg4/bin/m4 is also shipped. Its synopsis differs from /usr/bin/m4 only in how -D and -U are written; the visible page text describes no behavioural difference. The bundle does not say where the GNU m4 binary from pkgs.solnix.m4 is installed or how to put it ahead of /usr/bin/m4 on PATH. Check before relying on GNU options in scripts.
Differences
| Compared with | Topic | What differs |
|---|---|---|
| Linux | same program as the published page | The published Solnix page is GNU M4 (1.4.19), and Linux ships GNU M4 1.4.21. The option lists are identical. Only the -H default differs between the two pages: 509 on Solnix, 65537 on Linux. The default Solnix /usr/bin/m4 is a different program.Source: Solnix m4(1) (GNU M4 1.4.19) -H; Linux m4(1) (GNU M4 1.4.21) -H |
| Linux | default m4 lacks GNU options | illumos /usr/bin/m4 accepts only -e, -s, -B, -H, -S, -T, -D and -U. It has no --long options, -E, -P, -I, -d, -t, -g, -G, -F, -R, -L, -Q or -W, which GNU m4 on Linux has. Scripts using those fail unless GNU m4 is run.Source: illumos m4(1) SYNOPSIS and OPTIONS; Linux m4(1) OPTIONS |
| Linux, NetBSD | -e versus -i for interactive mode | illumos -e runs interactively: interrupts are ignored and output is unbuffered. GNU m4 (Linux) and NetBSD m4 use -i/--interactive for this. FreeBSD and OpenBSD document no interactive option.Source: illumos m4(1) -e; Linux m4(1) -i; NetBSD m4(1) -i; FreeBSD/OpenBSD m4(1) SYNOPSIS |
| Linux | -H hash table default | illumos -H sets the symbol table hash array size, default 199, and the size should be prime. The Solnix GNU page gives 509 and the Linux page gives 65537 for the same option. FreeBSD and OpenBSD document no -H.Source: illumos m4(1) -H; Solnix m4(1) -H; Linux m4(1) -H |
| all four | option ordering | illumos requires -B, -e, -H, -s, -S and -T to appear before any file name and before any -D or -U. The other pages state no such ordering rule.Source: illumos m4(1) OPTIONS ("To be effective, the above flags must appear before any file names"); Linux/FreeBSD/OpenBSD/NetBSD m4(1) OPTIONS |
| FreeBSD, OpenBSD, NetBSD | built-ins without parentheses | illumos treats a defined macro name with no following ( as a call with no arguments. FreeBSD, OpenBSD and NetBSD say most built-ins are not special unless followed by (, and note that many other m4 expand them anyway. Source: illumos m4(1) Macro Syntax; FreeBSD/OpenBSD/NetBSD m4(1) DESCRIPTION and STANDARDS |
| FreeBSD, OpenBSD, NetBSD | diversions | illumos m4 keeps 10 output streams, 0-9, and discards output diverted to any other number. On the BSDs the number of diversions is unlimited, but only in GNU compatibility mode (-g).Source: illumos m4(1) divert; FreeBSD/OpenBSD/NetBSD m4(1) -g |
| FreeBSD, OpenBSD, NetBSD | trace output file and -o | The BSDs use -o filename (NetBSD also --error-output) to send trace output to a file. GNU m4 uses --debugfile[=FILE] instead, and the illumos m4 has no equivalent option.Source: FreeBSD m4(1) -o; OpenBSD m4(1) -o; NetBSD m4(1) -o; Linux m4(1) --debugfile |
| OpenBSD | long options and -G | OpenBSD m4 has no long options and no -G, only -g. FreeBSD, NetBSD and GNU m4 accept both -g and -G and have long forms such as --define and --include.Source: OpenBSD m4(1) SYNOPSIS; FreeBSD m4(1) -G, -g; NetBSD m4(1) -G, -g; Linux m4(1) -G, -g |
| FreeBSD, OpenBSD, NetBSD | -E and exit status | GNU m4 and, per the pages, FreeBSD and OpenBSD treat one -E as making warnings produce a non-zero exit, and two -E as stopping at the first warning. NetBSD documents only that warnings make m4 exit. GNU m4 documents exit 63 for a frozen-file version mismatch. The BSDs document 0 or >0.Source: Linux m4(1) -E and exit status; FreeBSD/OpenBSD m4(1) -E, EXIT STATUS; NetBSD m4(1) -E |
| FreeBSD, OpenBSD | frozen state files | GNU m4 (-F, -R) and NetBSD m4 (-F, -R) can save and reload a frozen state. FreeBSD and OpenBSD document no such options, and the illumos m4 has none either.Source: Linux m4(1) -F, -R; NetBSD m4(1) -F, -R; FreeBSD/OpenBSD m4(1) SYNOPSIS; illumos m4(1) SYNOPSIS |
| FreeBSD, OpenBSD, NetBSD | M4PATH | The GNU page documents M4PATH as a colon-separated list of directories searched after any -I directories. The illumos text shown and the BSD pages do not mention M4PATH. The illumos m4 also has no -I.Source: Solnix m4(1) (M4PATH paragraph); Linux m4(1); illumos m4(1) OPTIONS; FreeBSD/OpenBSD/NetBSD m4(1) |
| NetBSD | -L and -v | On NetBSD, -L sets a nesting limit but is documented as unimplemented and unlimited, and -v prints the version. GNU m4 uses -L to change the nesting limit (default 0, unlimited) and has only --version, not -v.Source: NetBSD m4(1) -L, -v; Linux m4(1) -L, --version |
Standards
- POSIX: m4 is a POSIX.1-2024 utility.
- FreeBSD: The m4 utility is compliant with the IEEE Std 1003.1-2008 (“POSIX.1”) specification. The flags [
-dEGgIPot] and several macros (builtin, esyscmd, expr, format, indir, paste, patsubst, regexp, spaste, unix, __line__, __file__) are extensions. - OpenBSD: The m4 utility is compliant with the IEEE Std 1003.1-2008 (“POSIX.1”) specification. The flags [
-dEgIPot] and the same set of macros are extensions. - NetBSD: The m4 utility is compliant with the IEEE Std 1003.1-2008 (“POSIX.1”) specification. The flags
-dgIotand the same set of macros are extensions.
Writing portable scripts
- For portable scripts use only
-D,-Uand-s, which the illumos, GNU and BSD pages all document. Put them before the file names, since illumos requires-Dand-Uafter its other flags. - Always write a macro call with ( immediately after the name. illumos expands a bare name as a call, while the BSDs leave most built-ins unexpanded without parentheses.
- Do not rely on
-d,-t,-P,-Eor-Iwhen/usr/bin/m4may run. Install pkgs.solnix.m4 and run it explicitly if you need them.
Every difference here is taken from the manual pages linked above: Solnix's published page, Linux (man-pages and the GNU and util-linux manuals), FreeBSD, OpenBSD and NetBSD. Each row names its source. Where a manual is silent, this page is too. Compiled 2026-10-26. Found a mistake? Mail hackers@lists.solnix.io.