opcua-cli · v4.3.x
Docs · Building

Troubleshooting

PHAR and static-binary build failures cluster around five recurring causes. Each one has a known fix.

Build failures fall into five buckets. This page walks each through, with the canonical fix.

1. phar.readonly blocks PHAR write

text symptom
PharException: Cannot write out phar archive, phar is read-only

PHP defaults phar.readonly to 1. Box needs to write the PHAR; the setting must be disabled for the compile.

Fix:

bash terminal
php -d phar.readonly=0 box.phar compile -v

The setting is per-invocation — the produced PHAR runs fine under the default read-only mode.

2. Composer install pulls dev dependencies into the PHAR

text symptom
# PHAR is unexpectedly large (5 MB+ instead of ~650 KB)

A previous composer install (without --no-dev) left dev packages in vendor/ — Pest, PHPStan, php-cs-fixer. Box packs whatever it finds in vendor.

Fix:

bash terminal — clean install
rm -rf vendor
composer install --no-dev --prefer-dist --classmap-authoritative
php -d phar.readonly=0 box.phar compile

Always rm -rf vendor before the PHAR build if you've been running tests.

3. SPC doctor reports missing native tools

text symptom
[!] missing: autoconf
[!] missing: bison
[!] missing: re2c

SPC compiles PHP + OpenSSL + libxml2 from source — it needs the full C build toolchain.

Fix on Debian / Ubuntu:

bash terminal — apt
sudo apt-get install -y \
    build-essential autoconf bison re2c libtool pkg-config \
    libxml2-dev libssl-dev zlib1g-dev libicu-dev libonig-dev \
    git curl wget

Fix on Fedora / RHEL:

bash terminal — dnf
sudo dnf install -y \
    @development-tools autoconf bison re2c libtool pkgconfig \
    libxml2-devel openssl-devel zlib-devel libicu-devel oniguruma-devel

Fix on Alpine:

bash terminal — apk
apk add --no-cache \
    build-base autoconf bison re2c libtool pkgconfig \
    libxml2-dev openssl-dev zlib-dev icu-dev oniguruma-dev \
    git curl

After that:

bash terminal
./spc-src/bin/spc doctor --auto-fix

SPC re-checks and reports remaining issues.

4. SPC download hits GitHub API rate limit

text symptom
Failed to fetch "https://api.github.com/repos/php/php-src/tags": HTTP 403

GitHub's unauthenticated API rate limit is 60 requests per hour. The first SPC download bursts through that easily.

Fix:

bash terminal — token
export GITHUB_TOKEN=ghp_yourPersonalAccessTokenHere
./spc-src/bin/spc download --with-php=8.4 --for-extensions="$SPC_EXTENSIONS"

Even a token with no scopes works — it just lifts the rate limit to 5000/hour. Generate one at github.com/settings/tokens.

5. Out of memory during SPC build

text symptom
g++: internal compiler error: Killed (program cc1plus)

Common on 1 GB / 2 GB VMs. The PHP compile step is memory- hungry — especially with -j parallelism.

Fix — limit parallelism:

bash terminal — single-threaded build
./spc-src/bin/spc build "$SPC_EXTENSIONS" --build-micro -j 1

-j 1 does a single-threaded build — slower but uses less RAM. Try -j 2 if -j 1 succeeds.

Or — bigger host. 4 GB RAM + 4 CPUs is a comfortable build configuration.

Specific extension failures

openssl fails to build

OpenSSL headers missing. Install libssl-dev (Debian) / openssl-devel (Fedora) / openssl-dev (Alpine).

simplexml / dom / xml* fail

libxml2 headers missing. Install libxml2-dev (Debian) / libxml2-devel (Fedora) / libxml2-dev (Alpine).

mbstring fails

Oniguruma headers missing. Install libonig-dev (Debian) / oniguruma-devel (Fedora) / oniguruma-dev (Alpine).

These three cover ~90% of "extension X fails to build" cases.

Resulting binary fails to run

"missing shared object"

text symptom
./opcua-cli: error while loading shared libraries: libssl.so.1.1: cannot open shared object file

The build was not fully static — some library linked dynamically. Verify with:

bash terminal — ldd
ldd ./opcua-cli
# Should print "not a dynamic executable"

If ldd reports dependencies, rebuild — SPC's static linking went wrong. The common cause is a missing static-lib .a for one of the dependencies; check the SPC build log.

"PHP version mismatch"

The bundled PHP differs from what was expected. SPC's combine step uses whatever PHP was built last; if you built 8.4 then 8.3, the combine uses 8.3.

Fix — start fresh:

bash terminal — clean build
rm -rf spc-src/buildroot spc-src/source spc-src/downloads
./spc-src/bin/spc download --with-php=8.4 --for-extensions="$SPC_EXTENSIONS"
./spc-src/bin/spc build "$SPC_EXTENSIONS" --build-micro
./spc-src/bin/spc micro:combine build/opcua-cli.phar --output=opcua-cli

Windows-specific issues

MSYS2 not in PATH

The Windows build uses MSYS2's bash. Open the "MSYS2 MinGW 64-bit" shell from the Start menu rather than cmd.exe or PowerShell.

Long paths

Windows' 260-character path limit catches the deeply-nested SPC build directories. Enable long-path support (fsutil behavior set DisableLongPaths 0 as Administrator, plus a registry tweak — see Microsoft docs).

Antivirus quarantines the binary

Real-time scanners sometimes flag unsigned .exe files. Whitelist the build directory or sign the binary.

When to escalate

If you've tried the fixes above and the build still fails:

  1. Check the issue tracker. Many of these failures have been reported; the issue may already have an answer: github.com/php-opcua/opcua-cli/issues
  2. Check SPC's issues for SPC-specific build problems: github.com/crazywhalecc/static-php-cli/issues
  3. Open a new issue with:
    • Full output of ./spc-src/bin/spc doctor --auto-fix
    • The failing command and its stderr
    • Host OS / arch / PHP version
    • The version of opcua-cli you're building (git rev-parse HEAD)

Most build failures have a known cause within the five buckets above. The escalation path is for the genuine novel ones.