Skip to content

Creating static binaries on macOS fail with watcher enabled #2329

@fastnloud

Description

@fastnloud

What happened?

Creating static binaries on macOS fail with watcher enabled.

When I disable this by omitting watcher from the default list in PHP_EXTENSION_LIBS the build finishes successfully.

Tested with a new Symfony project:

  1. Run: symfony new my_project_directory --version="8.0.*"
  2. Prepare app:
rm -Rf $(TMPDIR)/frankenphp-prepared-app
mkdir -p $(TMPDIR)/frankenphp-prepared-app

git archive HEAD | tar -x -C $(TMPDIR)/frankenphp-prepared-app
rm -Rf $(TMPDIR)/frankenphp-prepared-app/tests/

cd $(TMPDIR)/frankenphp-prepared-app && \
	composer install --ignore-platform-reqs --no-dev -a && \
	composer dump-autoload --no-dev -a
  1. Build static binary with the following flags:
    EMBED=/var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T//frankenphp-prepared-app \
    PHP_VERSION=8.4 \
    FRANKENPHP_VERSION=1.12.1 \
    PHP_EXTENSIONS=ctype,iconv,tokenizer,xml,filter \
    PHP_EXTENSION_LIBS=libavif,nghttp2,nghttp3,ngtcp2,watcher \
    ./build-static.sh
  1. Error:
[08:01:21] [I] [EXEC] xcaddy build --output frankenphp --with github.com/dunglas/frankenphp=/Users/me/Code/frankenphp --with github.com/dunglas/frankenphp/caddy=/Users/me/Code/frankenphp/caddy --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli
✗ Command execution failed: Command exited with non-zero code: 1
----------------------------------------

Failed module: Builder for macOS

Failed command: xcaddy build --output frankenphp --with github.com/dunglas/frankenphp=/Users/me/Code/frankenphp --with github.com/dunglas/frankenphp/caddy=/Users/me/Code/frankenphp/caddy --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli                                                
Command executed in: /Users/me/Code/frankenphp/dist/static-php-cli/buildroot/bin
Command inline env variables:
    CGO_ENABLED=1
    CGO_CFLAGS=-fPIC -O2 -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include/php -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include/php/main -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include/php/TSRM -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include/php/Zend -I/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/include/php/ext -fPIE -fstack-protector-strong -O2 -w -s -DFRANKENPHP_VERSION=1.12.1                                                                                                                                                          
    CGO_LDFLAGS=-L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc                                                                                                       
    XCADDY_GO_BUILD_FLAGS=-buildmode=pie -ldflags \"-linkmode=external -extldflags '-pie -Wl,-exported_symbols_list,/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib/libphp.a.dynsym ' -X 'github.com/caddyserver/caddy/v2/modules/caddyhttp.ServerHeader=FrankenPHP Caddy' -X 'github.com/caddyserver/caddy/v2.CustomBinaryName=frankenphp' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP v1.12.1 PHP 8.4.19 Caddy'\" -tags=nobadger,nomysql,nopgx                                                                                                
    LD_LIBRARY_PATH=/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib
    GOROOT=/Users/me/Code/frankenphp/dist/static-php-cli/pkgroot/aarch64-darwin/go-xcaddy
    GOBIN=/Users/me/Code/frankenphp/dist/static-php-cli/pkgroot/aarch64-darwin/go-xcaddy/bin
    GOPATH=/Users/me/Code/frankenphp/dist/static-php-cli/pkgroot/aarch64-darwin/go

----------------------------------------

⚠ The console output log is saved in /Users/me/Code/frankenphp/dist/static-php-cli/log/spc.output.log
⚠ The shell output log is saved in /Users/me/Code/frankenphp/dist/static-php-cli/log/spc.shell.log
⚠ If you want to see more details in console, use `--debug` option.

Build Type

Static binary

Worker Mode

No

Operating System

macOS

CPU Architecture

aarch64

PHP configuration

phpinfo() output
[08:00:19] [I] Build OS:              Darwin (arm64)
[08:00:19] [I] Build Target:          native-macos
[08:00:19] [I] Build Toolchain:       SPC\toolchain\ClangNativeToolchain
[08:00:19] [I] Build SAPI:            embed, frankenphp
[08:00:19] [I] Static Extensions (5): ctype,iconv,tokenizer,xml,filter
[08:00:19] [I] Shared Extensions (0): 
[08:00:19] [I] Libraries (15):        libiconv,zlib,libxml2,brotli,watcher,libaom,libavif,openssl,nghttp3,ngtcp2,nghttp2
[08:00:19] [I] Strip Binaries:        yes
[08:00:19] [I] Enable ZTS:            yes
[08:00:19] [I] Build Dev:             yes
[08:00:19] [I] Config File Path:      /usr/local/etc/php
[08:00:19] [I] PHP Version:           8.4.19

Relevant log output

Relevant log output
# caddy
/Users/me/Code/frankenphp/dist/static-php-cli/pkgroot/aarch64-darwin/go-xcaddy/pkg/tool/darwin_arm64/link: running clang failed: exit status 1
/usr/bin/clang -arch arm64 -Wl,-headerpad,1144 -o $WORK/b001/exe/a.out /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/go.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000000.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000001.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000002.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000003.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000004.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000005.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000006.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000007.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000008.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000009.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000010.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000011.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000012.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000013.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000014.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000015.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000016.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000017.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000018.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000019.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000020.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000021.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000022.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000023.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000024.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000025.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000026.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000027.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000028.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000029.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000030.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000031.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000032.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000033.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000034.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000035.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000036.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000037.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000038.o /var/folders/60/nqp4rch947l8y_8l3dvwkhjc0000gn/T/go-link-54886688/000039.o -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -lphp -lm -lutil -Wl,-rpath,/usr/local/lib -liconv -ldl -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lxml2 -liconv -lm -lz -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -lwatcher-c -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -framework CoreFoundation -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -L/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib -lphp -lnghttp2 -lngtcp2 -lngtcp2_crypto_ossl -lnghttp3 -lssl -lcrypto -lavif -laom -lwatcher-c -lbrotlidec -lbrotlienc -lbrotlicommon -lxml2 -lm -lz -liconv -lcharset -lresolv -lc++ -lc -lbrotlicommon -lbrotlidec -lbrotlienc -lresolv -framework CoreFoundation -framework Security -pie -Wl,-exported_symbols_list,/Users/me/Code/frankenphp/dist/static-php-cli/buildroot/lib/libphp.a.dynsym
clang: warning: argument unused during compilation: '-pie' [-Wunused-command-line-argument]
ld: warning: ignoring duplicate libraries: '-laom', '-lavif', '-lbrotlicommon', '-lbrotlidec', '-lbrotlienc', '-lc', '-lc++', '-lcharset', '-lcrypto', '-liconv', '-lm', '-lnghttp2', '-lnghttp3', '-lngtcp2', '-lngtcp2_crypto_ossl', '-lphp', '-lresolv', '-lssl', '-lwatcher-c', '-lxml2', '-lz'
Undefined symbols for architecture arm64:
  "_FSEventStreamCreate", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamFlushSync", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamInvalidate", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamRelease", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamSetDispatchQueue", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamStart", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
  "_FSEventStreamStop", referenced from:
      detail::wtr::watcher::adapter::watch(std::__1::__fs::filesystem::path const&, std::__1::function<void (wtr::watcher::event const&)> const&, detail::wtr::watcher::semabin const&) in libwatcher-c.a[2](libwatcher-c.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

2026/04/04 08:01:30 [INFO] Cleaning up temporary folder: /Users/me/Code/frankenphp/dist/static-php-cli/buildroot/bin/buildenv_2026-04-04-0801.660985087
2026/04/04 08:01:30 [FATAL] exit status 1
Command exited with non-zero code: 1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions