This week OroCRM released an early version of their new open source business application framework and CRM suite. This article is extensibly about solving the
symfony/icu v1.2.0-RC1 requires lib-icu >=4.4 problem some Mac based developers ran into when installing this early-alpha software, but really its an excuse to talk about PHP’s architecture and how it loses some of it’s easy to install luster as soon as other packages are required.
While these instructions are Mac specific, they should give you the general idea of what you’ll need to do on any
*nix system to get things up and running.
PHP is often called a glue language — although this is one of those terms that gets so over used it’s almost meaningless. What some people mean when they call PHP a glue language is that it can “glue” together functionality from various different C/C++ libraries
PHP “glues” together all those C libraries, and allows you to use their functionality from a single PHP program. C programmers call PHP a glue language because they see the “real work” of a programmer as writing C code, and then PHP lets users create new programs. Of course, the glue language itself has become complex enough that people use it to develop systems that are as complex as PHP. Programming is fractal like that, but that’s not why we’re here today.
OroCRM on Mac OS X
On some (maybe all) versions of Max OS X, installation of OroCRM via PHP composer fails with the following error message
symfony/icu v1.2.0-RC1 requires lib-icu >=4.4 -> the requested linked library icu has the wrong version installed or is missing from your system, make sure to have the extension providing it.
The acronym “ICU” stands for International Components for Unicode. This is a standard library for providing unicode and internationalization functionality in C/C++ (and Java) programs.
PHP’s internationalization extension (also called
intl) provides PHP programs access to functionality from the ICU library.
symfony/icu package uses the
intl extension, but requires a version of the library greater than version 4.4.
OroCRM requires the
Because Max OS X doesn’t ship with the ICU libraries, composer can’t install
symfony/icu. Since this is a required package, the installation fails.
Fixing the Problem
To fix this problem, we’ll need to install a version of the ICU libraries (
lib-icu) that are version 4.4 or greater, and then use
pecl to compile and install the internationalization extension. The order matters here. Remember, PHP extensions give us access to C programs and libraries. That means the C programs and libraries need to be present on our system before we compile and install the PHP extension.
Step one will be installing ICU. Step two will be installing the
intl PHP extension.
Let’s get started.
Normally, I use MacPorts to manage my unix dependencies on OS X. However, after running the
port install command
$ sudo port install icu
---> Computing dependencies for icu
---> Cleaning icu
I saw I was given version 4.3.4 of the ICU libraries.
$ ls -l /opt/local/lib/icu/
drwxr-xr-x 4 root admin 136 Aug 22 2012 4.3.4
lrwxr-xr-x 1 root admin 20 Aug 22 2012 Makefile.inc -> current/Makefile.inc
lrwxr-xr-x 1 root admin 5 Aug 22 2012 current -> 4.3.4
lrw-r--r-- 1 root admin 19 Aug 22 2012 pkgdata.inc -> current/pkgdata.inc
I believe this is because I’m running an older version of OS X, and the MacPorts maintainers have determined 4.3.4 is the last version of ICU they want to maintain for Mac OS 10.6. However, I don’t quite understand how all that works (which is why I use MacPorts), so that may be inaccurate.
Fortunately, the ICU project maintains a number of precompiled binaries, including packages for 64-bit Macs. You’ll want to download the ICU4C
icu4c-51_2-MacOSX64_GCC.tgz. This will contain a directory structure that mirrors
/usr/local on your own system. Move these files from the
tgz to your own system (Backup, Backup, Backup your system before doing this), and you’ll have a working version of the ICU libraries.
Compiling intl for PHP
Next, we need to compile and install the internationalization extension for PHP. There’s two ways to do this. The first is via
pecl, the second is via the
--enable-intl CLI flag when compiling PHP. We’re going to cover the former.
When you run the
$ sudo pecl install intl
pecl will download the extension source,
phpize it, and then prompt you for the ICU library location.
downloading intl-2.0.1.tgz ...
Starting to download intl-2.0.1.tgz (149,430 bytes)
.................................done: 149,430 bytes
111 source files, building
PHP Api Version: 20090626
Zend Module Api No: 20090626
Zend Extension Api No: 220090626
Specify where ICU libraries and headers can be found [DEFAULT] :
It’s important you not leave this as
DEFAULT, otherwise the compile will fail, (or worse, it will use the files in your MacPorts
/opt/local folder and confuse you for the afternoon. Hypothetically speaking. Really).
/usr/local, hit enter, and the compilation will finish.
Specify where ICU libraries and headers can be found [DEFAULT] : /usr/local
[... build text deleted ...]
Build process completed successfully
install ok: channel://pecl.php.net/intl-2.0.1
configuration option "php_ini" is not set to php.ini location
You should add "extension=intl.so" to php.ini
When you compile a PHP extension, you’re creating a
.so file. In our case, that file is
pecl post-compile process should place this file in the correct location for us (
/usr/lib/php/extensions), but if you’re running multiple PHP environments you’ll want to check this. Also, per the post-compile text, you may need to manually add
extension=intl.so to your
php.ini file. This tells PHP it should load the extension the next time PHP is run from the command line, or the next time the web server is started.
You can test that the extension in installed by looking for one of its built-in classes in a small script.
var_dump("We have intl!");
var_dump("There's no intl!");
With a working
intl extension that’s linked to a modern version of ICU, you should be able to finish your OroCRM install.
PHP made its bones, in part, by being a very easy to deploy language. “Drop a bunch of PHP files on a server, you’re done”. However, as the needs of modern programming frameworks expand, PHP’s “glue language” architecture starts to create complexities. These complexities are not necessarily in the deployment of your PHP application, but instead in the creation and maintenance of the environment you deploy you PHP code to.
I’ve seen lots of smart people solve this particular problem by installing versions of PHP using popular package management systems. While I’d never tell anyone not to do something that solves their immediate problem, part of being a PHP developer who’s in it for the long haul is understanding how PHP works, and being able to track down and solve these sorts of problems on your own. I hope this article has provided enough information for you to stop randomly typing in text from the internet, and start understanding what that random typing is actually doing.