mongo-php-driver: Unable to Compile Driver for XAMPP on macOS

PHP XAMPP 7.2.7 on mac high sierra

Show this error when running make all

tmp/mongo-php-driver/src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.c:85:10: fatal error:
      'unicode/usprep.h' file not found
#include <unicode/usprep.h>
         ^~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [src/libmongoc/src/libmongoc/src/mongoc/mongoc-scram.lo] Error 1

It also happen when using PECL

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 18 (8 by maintainers)

Most upvoted comments

I started with a new macOS installation of High Sierra (version 10.13.6) and downloaded xampp-osx-7.2.7-0-r01-installer.dmg. Following the default installation process, XAMPP was installed to /Applications/XAMPP. The XAMPP manager app was opened after the installation completed and “Manage Servers” showed that “Apache Web Server” running (“MySQL Database” and “ProFTPD” were stopped). The installer also opened Safari to http://mongodbs-mackbook-pro.local/dashboard, which I left open to return to later.

I opened a terminal and attempting to install with the MongoDB driver with /Applications/XAMPP/bin/pecl install mongodb:

$ /Applications/XAMPP/bin/pecl install mongodb
No releases available for package "pecl.php.net/mongodb"
install failed

I attempted to update channels:

$ /Applications/XAMPP/bin/pecl update-channels
channel-add: temp_dir is not writable: "/var/folders/..." - You can change this location with "pear config-set temp_dir"

I attempted to update the temp dir:

$ /Applications/XAMPP/bin/peear config-set temp_dir /tmp
config-set succeeded

Another attempt to update channels:

$ /Applications/XAMPP/bin/pecl update-channels pecl.php.net
Updating channel "pecl.php.net"
could not create lock file: fopen(/Applications/XAMPP/xamppfiles/lib/php/.lock): failed to open stream: Permission denied
...

At this point, I decided to use sudo to update channels and install the driver:

$ sudo /Applications/XAMPP/bin/pecl update-channels pecl.php.net
Password: 
Updating channel "pecl.php.net"
Update of Channel "pecl.php.net" succeeded

Attempting to install again:

$ sudo /Applications/XAMPP/bin/pecl install mongodb
No releases available for package "pecl.php.net/mongodb"
install failed

Attempting to list packages:

$ sudo /Applications/XAMPP/bin/pecl list-all
Connection to `ssl://pecl.php.net:443' failed:

At this point, I gather that there may be some incompatibility between the build of PHP included with XAMPP and the OpenSSL library on macOS High Sierra. I’ll note the version of OpenSSL that PHP was compiled against and the version of OpenSSL available on macOS:

$ sudo /Applications/XAMPP/bin/php -i | grep "SSL Version"
SSL Version => OpenSSL/1.0.2o
$ openssl version
LibreSSL 2.2.7

I decide to manually download the PECL package (mongodb-1.5.1.tgz) and install it from the local filesystem to bypass this SSL issue.

$ sudo /Applications/XAMPP/bin/pecl install /Users/mongodb/Downlaods/mongodb-1.5.1.tgz
423 source files, building
running: phpize

...

Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

ERROR: `phpize' failed

I install Homebrew and proceed to install the following packages:

$ brew install autoconf

I then repeat installation of the extension, which ultimately fails for the same reason cited in your original comment, which was failure to include unicode/usprep.h. I notice that the configure output when I attempted to install the driver also includes the following suspect lines that you shared:

checking for pkg-config... /Applications/XAMPP/xamppfiles/bin/pkg-config

...

checking for PHP_MONGODB_ZLIB... yes
./configure: line 10588: cd: @@BITROCK_COMMON_ROOTDIR@@: No such file or directory

...

checking for PHP_MONGODB_ICU... yes
./configure: line 14035: cd: @@BITROCK_COMMON_ROOTDIR@@: No such file or directory

Googling for BITROCK_COMMON_ROOTDIR did not turn up much, but “bitrock” comes up as the developer of Bitnami, which is affiliated with XAMPP. I also think it’s suspect that XAMPP is providing its own copy of pkg-config, which reports @@BITROCK_COMMON_ROOTDIR@@ in its include path (as you shared in https://github.com/mongodb/mongo-php-driver/issues/883#issuecomment-406140279). Since macOS High Sierra does not appear to ship with pkg-config, I decide to install it via Homebrew:

$ brew install pkg-config

If you run configure --help for the extension, it reports that the PKG_CONFIG environment variable may be assigned the “path to pkg-config utility”. That is extracted from scripts/autotools/m4/pkg.m4, which is the build script responsible for finding pkg-config and using it to check for dependencies. That said, I was not successful attempting to get XAMPP’s pecl command to respect my customized PKG_CONFIG environment variable. I decided to look into how the pecl command was picking up /Applications/XAMPP/xamppfiles/bin/ and found that it is assigned to the bin_dir PEAR configuration option.

$ /Applications/XAMPP/bin/pecl config-get bin_dir
/Applications/XAMPP/xamppfiles/bin

Since this is the same directory that contains other essential binaries (e.g. phpize), I don’t think we can alter it without introducing a new problem. I think the best solution is to override /Applications/XAMPP/xamppfiles/bin/pkg-config with a symlink to version installed by Homebrew.

$ cd /Applications/XAMPP/xamppfiles/bin
$ sudo mv pkg-config pkg-config.bak
$ sudo ln -sf `which pkg-config` pkg-config

Let’s repeat the install process:

$ sudo /Applications/XAMPP/bin/pecl install /Users/mongodb/Downlaods/mongodb-1.5.1.tgz

The configure script still picks up /Applications/XAMPP/xamppfiles/bin/pkg-config as expected, but that is now a symlink to Homebrew’s pkg-config binary. The @@BITROCK_COMMON_ROOTDIR@@ errors are gone and configure reports that ZLIB was found but ICU was not. That’s understandable as I’ve not installed ICU manually with Homebrew (as you did in https://github.com/mongodb/mongo-php-driver/issues/883#issuecomment-406143360). The build ultimately succeeds and instructs me to add “extnesion=mongodb.so” to php.ini.

$ /Applications/XAMPP/xamppfiles/bin/php --ini
Configuration File (php.ini) Path: /Applications/XAMPP/xamppfiles/etc
Loaded Configuration File:         /Applications/XAMPP/xamppfiles/etc/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

I add extension=mongodb.so to /Applications/XAMPP/xamppfiles/etc/php.ini and confirm that the extension is loaded by the XAMPP’s CLI environment:

$ /Applications/XAMPP/xamppfiles/bin/php -m | grep mongodb
mongodb

I return Safari, which has been open to http://mongodbs-mackbook-pro.local/dashboard since XAMPP was installed. There is a “PHPInfo” link at the top, which simply displays phpinfo() output on its own page. This reports that the PHP web SAPI is using the same INI file as the CLI environment; however, the mongodb extension is not listed. That is to be expected, as the Apache process and its PHP module has not been restarted. I open the XAMPP control panel, restart the “Apache Web Server”, and then reload the “PHPInfo” dashboard page. The mongodb extension is still not listed. phpinfo() reports that the PHP error log is `/Applications/XAMPP/xamppfiles/logs/php_error_log, so I tail that and find:

[20-Jul-2018 18:47:57 UTC] PHP Warning:  PHP Startup: Unable to load dynamic library 'mongodb.so' (tried: /Applications/XAMPP/xamppfiles/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so (dlopen(/Applications/XAMPP/xamppfiles/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so, 9): Symbol not found: __cg_jpeg_resync_to_restart
  Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
  Expected in: /Applications/XAMPP/xamppfiles/lib/libjpeg.8.dylib
 in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO), /Applications/XAMPP/xamppfiles/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so.so (dlopen(/Applications/XAMPP/xamppfiles/lib/php/extensions/no-debug-non-zts-20170718/mongodb.so.so, 9): image not found)) in Unknown on line 0

Searching Google for this error turned up a number of forum threads referring to DYLD_LIBRARY_PATH. These two threads stood out:

  • https://stackoverflow.com/q/24941078/162228 involves a user attempting to executing ffmpeg from a PHP script using exec(), which demonstrates that this environment variable does not just affect the loading of PHP extensions.
  • https://stackoverflow.com/q/3146274/162228 is a more general discussion about DYLD_LIBRARY_PATH on macOS, and provides a lot of context about how it works. It also refers to a DYLD_FALLBACK_LIBRARY_PATH environment variable, but I did not see that utilized at all in XAMPP and did not pursue it.

I’ll note that DYLD_LIBRARY_PATH actually appears as an environment variable in phpinfo() output with the value /Applications/XAMPP/xamppfiles/lib/. XAMPP appears to set DYLD_LIBRARY_PATH in /Applications/XAMPP/xamppfiles/bin/envvars. This script checks if a path is already assigned and will prepend /Applications/XAMPP/xamppfiles/lib/ if so, or simply assign /Applications/XAMPP/xamppfiles/bin/ is the environment variable was empty. On my fresh install of macOS High Sierra, DYLD_LIBRARY_PATH was not defined so XAMPP was assigning its own path. This interfers with PHP’s ability to dynamically mongodb.so and/or the libraries it was built with. I did look defining DYLD_LIBRARY_PATH to /usr/local/lib:/usr/lib first and allowing XAMPP to prepend its own directory, but that did not help. I expect that some of the libraries shipping with XAMPP are not ABI compatible with those that ship with macOS, which were used to build mongodb.so.

Ultimately, I modified /Applications/XAMPP/xamppfiles/bin/envvars and commented out the export DYLD_LIBRARY_PATH line. After restarting Apache from the XAMPP control panel, I noticed that mongodb was now successfully loaded by the PHP web SAPI and the DYLD_LIBRARY_PATH environment variable was no longer present. I’m hestitant to suggest this as a final solution, as XAMPP’s Apache or PHP environments may still be relying on DYLD_LIBRARY_PATH to load other libraries. This may be especially true for the other PHP extensions that ship with XAMPP.

In conclusion, there is definitely a conflict with XAMPP; however, I don’t believe this is limited to the MongoDB driver and suspect it extends to other PECL extensions that dynamically link shared libraries. I’d argue that the best solution is to install PHP using Homebrew and manually install extensions with its pecl command (extension formulae no longer exist since the PHP tap was deprecated). If using XAMPP is a priority, I think the XAMPP-VM environment is preferable to their standard macOS package, as it runs PHP inside of a Linux VM. Lastly, I’ll concede that the suggestion in https://github.com/mongodb/mongo-php-driver/issues/822#issuecomment-406271673 to use MAMP is also well founded.

Sorry to bump an old thread. However, this came up in a Google search while trying to fix my issue. It is similar/related and this info may help someone else who stumbles here.

NOTE: I am on MacOS Catalina and using XAMPP. This issue was present for people on High Sierra and others as well.

I was getting:

fatal error: 'unicode/usprep.h' file not found
#include <unicode/usprep.h>
         ^~~~~~~~~~~~~~~~~~

Notice it’s complaining about usprep.h and make fails. While searching, this was due to icu4c. I had it insalled via homebrew, it was a minor version out of date… updated it just because, no luck. hmm…

After banging my head, I ended up doing which icu4c which obviously failed (turns out isn’t a real binary lol). I then tried which icuinfo, and immediately saw (hoped) that I just figured out the issue. It was pulling from my XAMPP bin directory.

I had to modify the paths to get the bin and sbin dirs for icu4c to be searched first.

More info on my SO answer here: https://stackoverflow.com/a/67349734/2703135

I hope it helps someone 😃

Ah i got it

$ brew install icu4c
$ brew link icu4c --force

it solved my problem, thank you for some clue.