Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Resolve build failure on Apple Silicon of PHP 8.0 due to old bundled pcre2 #1358

Merged
merged 1 commit into from Mar 22, 2024

Conversation

driskell
Copy link
Contributor

@driskell driskell commented Dec 7, 2023

On macOS on Apple Silicon you get an Allocation of JIT memory failure error at the end of the build of PHP 8.0. This is due to a bug in the bundled PCRE2 library. It's fixed in the bundled version in PHP 8.1, and I think lower versions don't bundle it so you're highly likely to link to a version with the fix.

I wasn't sure how this can be best fixed, and wanted to be able to make it "seamless" and more "intuitive" by detecting Apple Silicon and PHP 8.0 and then forcing it to link to a newer PCRE2 externally, and report if it can't find it, rather than blindly continuing only to fail.

I know there's no other code in phpbrew that appears to check the environment. Happy to discuss a better approach. In an ideal world phpbrew would actually be able to verify the environment before building so it can say "You are missing X" so maybe this is a good discussion area to get something in place as throwing Exception is not my greatest idea here!

@peter279k
Copy link
Member

@driskell, thanks for your PR.

If possible, could you provide your macOS environemt that you run this change? (e.g. Mac Mini M1)

And I can reproduce the issue and verify the PR is correct easily :).

@driskell
Copy link
Contributor Author

driskell commented Dec 7, 2023

@driskell, thanks for your PR.

If possible, could you provide your macOS environemt that you run this change? (e.g. Mac Mini M1)

And I can reproduce the issue and verify the PR is correct easily :).

Apple MacBook Pro M3

@driskell
Copy link
Contributor Author

@peter279k Is there a way I can help to get this merged?

@peter279k peter279k requested a review from c9s March 18, 2024 16:37
@peter279k
Copy link
Member

Thanks for PR. This PR needs the macOS machine to be verified.

Do you try to build the phpbrew with this PR to verify that?

@driskell
Copy link
Contributor Author

@peter279k I responded on the other ticket it’s all same details. I don’t actually understand your question but if you meant OS version it is macOS Sonoma 14.x and as noted above it’s an M3 Apple MacBook Pro but it reproduces on M1 and M2 as well. Unfortunately I have no Intel to test with

@peter279k
Copy link
Member

I meant it will happen on the M3, M2 and M1? Especially it's effected in the Apple Silicon architecture.

@driskell
Copy link
Contributor Author

I meant it will happen on the M3, M2 and M1? Especially it's effected in the Apple Silicon architecture.

I think it does yes as some colleagues are M1.

It looks like I didn’t log my research so I’m trying to trace my steps. I’ll update when I’ve done so

@driskell
Copy link
Contributor Author

driskell commented Mar 19, 2024

OK so it is fixed since 8.1.11 on Apple Silicon

php/php-src@f8b217a

PHP changelog notes it too. I can add it to the comments here.

I think when I originally fixed this I only got as far as bisecting and noted latest 8.1 worked but not latest 8.0 and noticed that linking newer PCRE2 and ignoring the bundled version fixed it. Probably saw the Bus error noted in the commit above and derived from there the same they did.

I can test 7.4 too as seems some reports it not working there either:
asdf-community/asdf-php#94 (comment)

src/PhpBrew/VariantBuilder.php Outdated Show resolved Hide resolved
src/PhpBrew/VariantBuilder.php Outdated Show resolved Hide resolved
src/PhpBrew/Build.php Show resolved Hide resolved
@peter279k peter279k self-assigned this Mar 19, 2024
@driskell
Copy link
Contributor Author

I was planning to test 8.1.10 and 8.1.11 specifically just to confirm, but also check on 7.4 etc. but haven't had time yet. Will update when I get to it. I also have a colleague now with an Intel so can also check on that but they did use this PR and it didn't encounter issues for them.

@peter279k
Copy link
Member

Here are my tests for compiling the PHP 8.1.10, PHP 8.1.11, PHP 7.4.28 and PHP 7.4.33 versions with the latest PHPBrew version in the M2:

Here are my CPU information:

administrator@68537 ~ % sysctl -a | grep machdep.cpu
machdep.cpu.cores_per_package: 8
machdep.cpu.core_count: 8
machdep.cpu.logical_per_package: 8
machdep.cpu.thread_count: 8
machdep.cpu.brand_string: Apple M2

Building the PHP 8.1.10 log is as follows:

$ phpbrew --version
phpbrew - 2.2.0
cliframework core: 2.5.4
$ phpbrew --debug install 8.1.10 +mbstring +json +filter +openssl +zip +intl +xml +ctype +pcre
make: *** [ext/phar/phar.phar] Error 255

Please checkout the build log file for more details:
         tail /Users/administrator/.phpbrew/build/php-8.1.10/build.log
bash-3.2$ tail /Users/administrator/.phpbrew/build/php-8.1.10/build.log

Fatal error: Uncaught InvalidArgumentException: RegexIterator::__construct(): Allocation of JIT memory failed, PCRE JIT will be disabled. This is likely caused by security restrictions. Either grant PHP permission to allocate executable memory, or set pcre.jit=0 in /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php:1145
Stack trace:
#0 /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php(1145): RegexIterator->__construct(Object(RecursiveIteratorIterator), '/\\.svn/')
#1 /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php(1089): PharCommand::phar_add(Object(Phar), 0, '/Users/administ...', NULL, '/\\.svn/', Object(SplFileInfo), NULL, false)
#2 /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php(225): PharCommand->cli_cmd_run_pack(Array)
#3 /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php(2101): CLICommand->__construct(19, Array)
#4 {main}
  thrown in /Users/administrator/.phpbrew/build/php-8.1.10/ext/phar/phar.php on line 1145
make: *** [ext/phar/phar.phar] Error 255

Building the PHP 8.1.11 log is as follows:

$ phpbrew --debug install 8.1.11 +mbstring +json +filter +openssl +zip +intl +xml +ctype +pcre
make >> '/Users/administrator/.phpbrew/build/php-8.1.11/build.log' 2>&1
Build finished: 3.3 minutes.
Installing...
---> Creating php.ini
---> Copying /Users/administrator/.phpbrew/build/php-8.1.11/php.ini-development
---> Found date.timezone is not set, patching...
Source directory: /Users/administrator/.phpbrew/build/php-8.1.11
Congratulations! Now you have PHP with 8.1.11 as php-8.1.11

* To configure your installed PHP further, you can edit the config file(s) at
    /Users/administrator/.phpbrew/php/php-8.1.11/etc/cli/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-8.1.11

Or you can use switch command to switch your default php to php-8.1.11:

    $ phpbrew switch php-8.1.11

Enjoy!

Building the PHP 7.4.28 log is as follows:

$ phpbrew --debug install 7.4.28 +mbstring +json +filter +openssl='/opt/homebrew/opt/openssl@1.1' +zip +intl +xml +ctype +pcre
make >> '/Users/administrator/.phpbrew/build/php-7.4.28/build.log' 2>&1
Error: Make failed:
The last 5 lines in the log file:
      _zif_dns_get_record in dns.o

      _zif_dns_get_mx in dns.o

ld: symbol(s) not found for architecture arm64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

make: *** [sapi/cli/php] Error 1

Please checkout the build log file for more details:
         tail /Users/administrator/.phpbrew/build/php-7.4.28/build.log
bash-3.2$ tail /Users/administrator/.phpbrew/build/php-7.4.28/build.log
      _zif_dns_check_record in dns.o
      _zif_dns_get_record in dns.o
      _zif_dns_get_mx in dns.o
  "_res_9_search", referenced from:
      _zif_dns_check_record in dns.o
      _zif_dns_get_record in dns.o
      _zif_dns_get_mx in dns.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [sapi/cli/php] Error 1

According to the above PHP 7.4.28 compiling log, it seems that it has other problems due to the Apple Silicon architecture.
And it's out of scope for this PR. This issue is effect in all PHP 7.4 verisons.

@peter279k
Copy link
Member

Here are compiling PHP 8.0.30 (it's the latest PHP 8.0 version) log is as follows with the latest PHPBrew version:

$ phpbrew --debug install 8.0 +mbstring +json +filter +openssl='/opt/homebrew/opt/openssl@1.1' +zip +in
tl +xml +ctype +pcre
===> phpbrew will now build 8.0.30
make >> '/Users/administrator/.phpbrew/build/php-8.0.30/build.log' 2>&1
Error: Make failed:
The last 5 lines in the log file:
$ tail /Users/administrator/.phpbrew/build/php-8.0.30/build.log
Fatal error: Uncaught InvalidArgumentException: RegexIterator::__construct(): Allocation of JIT memory failed, PCRE JIT will be disabled. This is likely caused by security restrictions. Either grant PHP permission to allocate executable memory, or set pcre.jit=0 in /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php:1133
Stack trace:
#0 /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php(1133): RegexIterator->__construct(Object(RecursiveIteratorIterator), '/\\.svn/')
#1 /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php(1077): PharCommand::phar_add(Object(Phar), 0, '/Users/administ...', NULL, '/\\.svn/', Object(SplFileInfo), NULL, true)
#2 /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php(225): PharCommand->cli_cmd_run_pack(Array)
#3 /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php(2089): CLICommand->__construct(19, Array)
#4 {main}
  thrown in /Users/administrator/.phpbrew/build/php-8.0.30/ext/phar/phar.php on line 1133
make: *** [ext/phar/phar.phar] Error 255

@driskell
Copy link
Contributor Author

Thanks for that! Saved me some time.

I have now updated the comment to reference the exact fix in PHP and also to fix it to 8.1.11 only so it only pulls in the homebrew PCRE2 if it needs to

@peter279k
Copy link
Member

Using this patch to build a PHPBrew and compiling the PHP 8.1.10 and PHP 8.0.30 logs are as follows:

$ brew --prefix pcre2
/opt/homebrew/opt/pcre2
$ phpbrew --version
phpbrew - 2.2.0-pr-1358
cliframework core: 2.5.4

$ phpbrew --debug install 8.1.10 +mbstring +json +filter +openssl +zip +intl +xml +ctype +pcre
./configure '--cache-file=/Users/administrator/.phpbrew/cache/config.cache' '--prefix=/Users/administrator/.phpbrew/php/php-8.1.10' '--disable-all' '--enable-phar' '--enable-session' '--enable-short-tags' '--enable-tokenizer' '--enable-mbstring' '--enable-json' '--enable-filter' '--with-openssl' '--with-zip' '--enable-intl' '--enable-dom' '--with-libxml' '--enable-simplexml' '--enable-xml' '--enable-xmlreader' '--enable-xmlwriter' '--with-xsl' '--enable-ctype' '--with-external-pcre=/opt/homebrew/opt/pcre2' '--enable-opcache' '--enable-cli' '--with-config-file-path=/Users/administrator/.phpbrew/php/php-8.1.10/etc/cli' '--with-config-file-scan-dir=/Users/administrator/.phpbrew/php/php-8.1.10/var/db/cli' 'PKG_CONFIG_PATH=/opt/homebrew/opt/oniguruma/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/icu4c/lib/pkgconfig' >> '/Users/administrator/.phpbrew/build/php-8.1.10/build.log' 2>&1

Build finished: 3 minutes.
Installing...
---> Creating php.ini
---> Copying /Users/administrator/.phpbrew/build/php-8.1.10/php.ini-development
---> Found date.timezone is not set, patching...
Source directory: /Users/administrator/.phpbrew/build/php-8.1.10
Congratulations! Now you have PHP with 8.1.10 as php-8.1.10

* To configure your installed PHP further, you can edit the config file(s) at
    /Users/administrator/.phpbrew/php/php-8.1.10/etc/cli/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-8.1.10

Or you can use switch command to switch your default php to php-8.1.10:

    $ phpbrew switch php-8.1.10

Enjoy!

$ phpbrew --debug install 8.0.30 +mbstring +json +filter +openssl='/opt/homebrew/opt/openssl@1.1' +zip +intl +xml +ctype +pcre
./configure '--cache-file=/Users/administrator/.phpbrew/cache/config.cache' '--prefix=/Users/administrator/.phpbrew/php/php-8.0.30' '--disable-all' '--enable-phar' '--enable-session' '--enable-short-tags' '--enable-tokenizer' '--enable-mbstring' '--enable-json' '--enable-filter' '--with-openssl' '--with-zip' '--enable-intl' '--enable-dom' '--with-libxml' '--enable-simplexml' '--enable-xml' '--enable-xmlreader' '--enable-xmlwriter' '--with-xsl' '--enable-ctype' '--with-external-pcre=/opt/homebrew/opt/pcre2' '--enable-opcache' '--enable-cli' '--with-config-file-path=/Users/administrator/.phpbrew/php/php-8.0.30/etc/cli' '--with-config-file-scan-dir=/Users/administrator/.phpbrew/php/php-8.0.30/var/db/cli' 'PKG_CONFIG_PATH=/opt/homebrew/opt/oniguruma/lib/pkgconfig:/opt/homebrew/opt/openssl@3/lib/pkgconfig:/opt/homebrew/opt/icu4c/lib/pkgconfig' >> '/Users/administrator/.phpbrew/build/php-8.0.30/build.log' 2>&1

===> Checking patches...
Checking patch for php5.3.x on 64bit machine when intl is enabled.
Checking patch for openssl dso linking patch
0 changes patched.
Checking patch for php5.6 with openssl 1.1.x patch.
===> Building...
make >> '/Users/administrator/.phpbrew/build/php-8.0.30/build.log' 2>&1
Build finished: 2.6 minutes.
Installing...
---> Creating php.ini
---> Copying /Users/administrator/.phpbrew/build/php-8.0.30/php.ini-development
---> Found date.timezone is not set, patching...
Source directory: /Users/administrator/.phpbrew/build/php-8.0.30
Congratulations! Now you have PHP with 8.0.30 as php-8.0.30

* To configure your installed PHP further, you can edit the config file(s) at
    /Users/administrator/.phpbrew/php/php-8.0.30/etc/cli/php.ini

To use the newly built PHP, try the line(s) below:

    $ phpbrew use php-8.0.30

Or you can use switch command to switch your default php to php-8.0.30:

    $ phpbrew switch php-8.0.30

Enjoy!

@driskell, I think this PR is verified and please help me to review and check that. Thanks.

@peter279k
Copy link
Member

@c9s, could you help me to review this PR? Thanks.

@c9s
Copy link
Member

c9s commented Mar 20, 2024

@peter279k looks good to me

@peter279k peter279k merged commit 890e9e2 into phpbrew:master Mar 22, 2024
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants