Monday 1 June 2009

Trying to install a php extension without super user privileges

This morning I signed up with WebFaction for a month to test them out. I spent most of the day tying to install ImageMagick and the PECL Imagick PHP extension without sudo.

Installing ImageMagick was pretty easy, I just followed this guide: How do I install the latest ImageMagick and RMagick? (except without the gem install bit). I was a bit concerened that after doing that, when I did echo $PATH, $HOME/dir wasn't coming up. However, after restarting the Ubuntu Virtual Machine, $HOME/dir was included in $PATH when echoing it (this is at the terminal, not PHP).

After doing that I tried to install the Imagick php extension pecl install imagick. But that didn't work as it tries to install the extension to the php shared extensions directory, which is owned by root.

Googling revealed that you can't have more than one extensions directory. I thought that I should change the extension_dir in php.ini to point to a folder in my $HOME directory. Then I could either create a symlink in that directory that points to the shared extensions directory, e.g.
cd $HOME/php_ext
ln -s /usr/lib/php5/20060613+lfs shared
and then in my php.ini file, add 'shared/' in front of all the extensions currently loaded. Then I would be able to add new extensions in my $HOME/php_ext directory.

So next I looked at using phpize to compile the extension. But this seemed to automatically try and stick the extension in the php shared extensions directory, and I although I googled I couldn't see any way to make it put the compiled extension in my $HOME/php_ext directory. However, looking now I can see that I could have done ./configure --prefix=$HOME/php_ext --with-imagick=$HOME. Could have saved me a few hours if I'd known that!

Anyway, since I couldn't see how to make that work, I tried compiling php with the extension. According to my phpinfo(), I was using PHP 5.2.6.3. However, despite a lot of searching I couldn't find this anywhere, so I just downloaded the PHP 5.2.6 source.

I also had to refer to the PHP Manual page on Compiling PECL extensions statically into PHP for compiling ImageMagick into PHP. The first problem I had that took me ages to work out was that when I ran ./configure --with-imagick in the php source directory, it wanted to know where the ImageMagick installation directory was. Now when I installed ImageMagick into my home directory, it had created a few different folders: bin, include, lib, share.

And in those directories there were sub directories. So I had no idea which one would be regarded as the installation directory. After some googling on installation directories, it seems most Linux programs are installed to /usr/local/progName. So not useful in my situation. I tried the lib directory, but got an error about MagickWand-config not being found. I looked, and that was in the bin directory, so I used that as the ImageMagick installation parameter when running ./configure --with-imagick=$HOME/bin in the php source directory. But it still said the same thing, even though I could see MagickWand-config was there in the bin directory.

Eventually after trying lots of different things, I found that the installation directory parameter was just my $HOME directory, where all the bin, include, lib, share folders were that ImageMagick had created when I installed it. Doh!

After that I tried compiling the php extensions using make build-modules as suggested by a comment on the guide to compiling shared PHP modules I was using. Unfortunately, I just got a message that there weren't any modules to compile.

So I tried doing a full make, but after a bit got an error message:
/home/brighto/tarballs/php-5.2.6/ext/posix/posix.c: In function 'zif_posix_uname':
/home/brighto/tarballs/php-5.2.6/ext/posix/posix.c:471: error: 'struct utsname' has no member named 'domainname'


I did some googling, but didn't see any easy way to fix it, so I just commented out the offending lines like so:
/*#ifdef _GNU_SOURCE
add_assoc_string(return_value, "domainname", u.domainname, 1);
#endif*/
No idea if that does actually comment out the lines since I don't know any C.

I ran make clean, then make test and it took ages and had lots of errors. I did a make and it worked, but I didn't get any extensions created.

So I thought maybe I have to actually install php for it to create the extensions. So I created a directory for it to install into, ran make clean, then ./configure --prefix=$HOME/phpBuild --with-imagick=$HOME --with-mysqli. I hoped that by running it with mysqli I would be able to see the mysqli extension file easily if it worked. It installed php into the directory I'd specified, but still didn't seem to have any extensions created.

I thought maybe my commenting out of the problem lines in posix.c had broken it, so I uncommented them, ran
make clean
./configure --prefix=$HOME/phpBuild --disable-posix --with-imagick=$HOME --with-mysqli
make
make install

Again, the same thing happened - it installed php into the directory I'd specified, but still didn't seem to have any extensions created.

So after this I tried compiling the extension using phpize, but compiling it against my php I had just installed into my $HOME/phpBuild directory. I used the instructions in the comments on the PHP Manual page for Compiling shared PECL extensions with phpize.
cd $HOME/tarballs/php-5.2.6/ext/Imagick (this is where I had saved the Imagick php extension source)
$HOME/phpBuild/bin/phpize (this gave lots of errors)
./configure --with-php-config=$HOME/phpBuild/bin/php-config --with-imagick=$HOME
make
make install
(I didn't actually need to do make install, but I didn't realise this


Then the imagick extension was successfully created in $HOME/phpBuild/lib/php/extensions/no-debug-non-zts-20060613, so I copied it and pasted it in $HOME/php_ext, and when I ran phpinfo(), Imagick was listed. Wahoo! Then I hadn't actually configured my php.ini file to load the extensions in the shared extensions folder, so I had to do that.

As I said earlier, rather than messing around with the php source, all I needed to do actually was to download the PECL Imagick php extension source, configure it with ./configure --prefix=$HOME/php_ext --with-imagick=$HOME, then update my php.ini file. If only I had realised that earlier!

I sent a ticket off to WebFaction to see how to install a php extension on their Server, as they don't run PHP as cgi, so you can't just create a php.ini file and change the extension_dir. You can't change the php extension_dir via a .htaccess directive either. I did check my webspace with WebFaction, and couldn't see any pre-created php.ini file there (They could have setup the virtual host to point to a php.ini in the webspace). I also checked their PHP knowledgebase articles, and couldn't see anything about php.ini there.

I probably made myself look stupid on my ticket since I said about compiling the extension locally against the same version of php they have on the server, when in fact I should easily be able to compile the extension on the server. This was because I sent the ticket before I realised you could use --prefix-OUTPUT_DIR when compiling the extension. Still, me being stupid is the truth!

In the evening I watched Springwatch, and also went in the garden for a bit to try and take some photos. I saw a few flies, but all apart from Coenosia tigrina (which I already have 100s of pics of), flew away when I got near them.

The weather was nice and warm and sunny with no clouds again today.

Food
Breakfast: Bowl of Berry oat crunch cereal; cup o' tea.
Lunch: Peppered ham with sliced baby plum tomatoes; sliced raddish and iceberg lettuce sandwich; large satsuma; slice of home-made sultana flapjack; cup o' tea.
Dinner: Slice of Ham quiche; flavoured rice. Pudding was chocolate muffin. Coffee.
Supper: Fly biscuit; milk chocolate digestive; coffee.

No comments: