FirebirdSQL / php-firebird

Firebird PHP driver
Other
66 stars 15 forks source link

Compile errors on M1 ARM Mac #32

Open janzikmund opened 2 years ago

janzikmund commented 2 years ago

On my old, Intel-based MacBook (BigSur, PHP7.4, Firebird 3.0.10), I managed to compile the driver just fine using the following steps:

  1. git clone https://github.com/FirebirdSQL/php-firebird.git
  2. cd php-firebird
  3. phpize
  4. CPPFLAGS=-I/Library/Frameworks/Firebird.framework/Versions/Current/Headers LDFLAGS=-L/Library/Frameworks/Firebird.framework/Versions/Current/Libraries ./configure
  5. make

This gave me the compiled modules/interbase.so file, which I then copied to my extension_dir and enabled in php.ini.

Now when attempting the same on the new M1 ARM MacBook with MacOS Monterey, it just fails on step 4 with the following: configure: error: libfbclient, libgds or libib_util not found! Check config.log for more information.

Unfortunately the log doesn't give me many pointers, but I have checked that /Library/Frameworks/Firebird.framework/Versions/Current/Libraries contains libfbclient.dylib and libib_util.dylib but libgds.dylib is missing, not sure how far that's an issue. I tried to look it up, but without success. I even replaced Firebird 3.0.10 by older 3.0.5 LIPO package from here , but even here the libgds is missing.

I found out that if I do step 4 with additionally passing architecture flag, it helps and the following compiles successfully: CFLAGS='-arch x86_64' CPPFLAGS=-I/Library/Frameworks/Firebird.framework/Headers LDFLAGS=-L/Library/Frameworks/Firebird.framework/Resources/lib ./configure

The problem is, that after moving the resulting interbase.so to php extension_dir, it just doesn't load and PHP states the following error, which is probably reasonable: Warning: PHP Startup: Unable to load dynamic library 'interbase.so' (tried: /opt/homebrew/lib/php/pecl/20190902/interbase.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/interbase.so, 0x0009): tried: '/opt/homebrew/lib/php/pecl/20190902/interbase.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))), /opt/homebrew/lib/php/pecl/20190902/interbase.so.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/interbase.so.so, 0x0009): tried: '/opt/homebrew/lib/php/pecl/20190902/interbase.so.so' (no such file))) in Unknown on line 0

.. where the important part imo is the mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e')

So I try from scratch and replace step 4 with CFLAGS='-arch arm64e' CPPFLAGS=-I/Library/Frameworks/Firebird.framework/Headers LDFLAGS=-L/Library/Frameworks/Firebird.framework/Resources/lib ./configure , but that terminates after a few lines of output with the following:

checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for a sed that does not truncate output... /opt/homebrew/bin/gsed
checking for pkg-config... no
checking for cc... cc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... configure: error: in /Users/ziki/Desktop/php-firebird:
configure: error: cannot run C compiled programs.
If you meant to cross compile, use --host.

I even tried with -arch arm64 instead of -arch arm64e, but in that case I just get the configure: error: libfbclient, libgds or libib_util not found! error again.

Has anyone managed to do it successfully? Only guidelines I found is this SO thread, but that suggests replacing PHP and other brew dependecies by 64bit versions, and I am not sure if that would work at all with my webserver (Laravel Valet).

MartinKoeditz commented 2 years ago

Warning: PHP Startup: Unable to load dynamic library 'interbase.so' (tried: /opt/homebrew/lib/php/pecl/20190902/interbase.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/interbase.so, 0x0009): tried: '/opt/homebrew/lib/php/pecl/20190902/interbase.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e'))), /opt/homebrew/lib/php/pecl/20190902/interbase.so.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/interbase.so.so, 0x0009): tried: '/opt/homebrew/lib/php/pecl/20190902/interbase.so.so' (no such file))) in Unknown on line 0 This can also indicate that the interbase.so file cannot find the fbclient.so. That seems to be a general problem on your system. Please check that the fbclient.so is locatable by your system.

mrotteveel commented 2 years ago

You need an M1 build of libfbclient before you would even be able to build a M1 build of php-firebird. As far as I'm aware, there is no M1 build of Firebird/libfbclient.

janzikmund commented 2 years ago

This can also indicate that the interbase.so file cannot find the fbclient.so. Please check that the fbclient.so is locatable by your system.

I don't see this file anywhere, doesn't look like being part of the Firebird or firebird-php install either. From my research looks like it should be part of firebird-dev package on Linux, but apparently there is nothing like it for MacOS.

You need an M1 build of libfbclient before you would even be able to build a M1 build of php-firebird. As far as I'm aware, there is no M1 build of Firebird/libfbclient.

Well I see libfbclient.dylib is included in /Library/Frameworks/firebird.framework/Versions/Current/Libraries/, so do you think this file currently doesn't support M1 and I have to wait for an upgrade? Or is there anything I can still do about it?

AlexPeshkoff commented 2 years ago

On 6/15/22 14:05, Jan Zikmund wrote:

Unfortunately the log doesn't give me many pointers, but I have checked that /Library/Frameworks/Firebird.framework/Versions/Current/Libraries contains |libfbclient.dylib| and |libib_util.dylib| but |libgds.dylib| is missing, not sure how far that's an issue. I tried to look it up, but without success. I even replaced Firebird 3.0.10 by older 3.0.5 LIPO package from here https://firebirdsql.org/en/firebird-3-0-5/ , but even here the |libgds| is missing.

|libgds.dylib should be a symbolic link to libfbclient.dylib, create it yourself and repeat build process

|

mrotteveel commented 2 years ago

I got the following from Paul Beach privately, because it seems he couldn't post it here (at least not by mail):

There is a "beta" version that I did for 3.0.8 that can be tested. It seems to work.

www.ibphoenix.com/downloads/Firebird-3.0.8-33398-M1.pkg

Maybe it can help.

janzikmund commented 2 years ago

There is a "beta" version that I did for 3.0.8 that can be tested.

Thanks, I have it installed in place of my original 3.0.10. When I now try to compile php-firebird using CPPFLAGS=-I/Library/Frameworks/Firebird.framework/Headers LDFLAGS=-L/Library/Frameworks/Firebird.framework/Resources/lib ./configure , the process finishes correctly, but when I then place interbase.so to the extension_dir, I get the following error:

PHP Startup: Unable to load dynamic library 'interbase.so' (tried: /opt/homebrew/lib/php/pecl/20190902/interbase.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/interbase.so, 0x0009): symbol not found in flat namespace '_PHP_MD5InitArgs'),

|libgds.dylib should be a symbolic link to libfbclient.dylib, create it yourself and repeat build process

I've tried that, both with 3.0.10 and the 3.0.8 M1, but unfortunately makes no difference.

janzikmund commented 2 years ago

An update for anyone interested:

The M1-compiled beta 3.0.8 linked above is not really usable, because it behaves very buggy on SQL queries where ORDER BY column doesn't have index on it. In DBeaver such a query just throws some unidentified Java errors, while when connecting from PHP the column in returned dataset just randomly contains NULL values instead of stored data. Took me a while to find out it's actually a bug in Firebird, then I returned back to latest 3.0.10, which has this misbehaviour fixed.

For the PHP connection itself, unfortunately no success, still having the errors as per above and I am just unable to crack this without the core team fixing it. So I rather focused on creating a Docker container with Debian version of PHP and that seems to be the correct way. I have it pretty much working, just need to fix a few things and then I will link it here as a walk-around solution until (if ever) is the driver issue for ARM Macs resolved.

janzikmund commented 2 years ago

Ok, here are the docker files. They just need to be placed in the project folder and then run using docker-compose up. This installs the Docker image with PHP 7.4, Apache webserver and some basic PHP modules. Then clones the php-firebird adapter, compiles it and installs it to PHP extensions. Once the container is installed, it proxies port :80 from container to :8080 on host machine, so all you need to do is visit your site on http://localhost:8080 and you will have the connection working.

That being said, it would still be nice to have a native adapter so if anyone reading this has an idea how to compile the native php-firebird extension on ARM, please share your findings.

# Dockerfile

FROM php:7.4-apache

# allows PHP to check the environment using <?php if(getenv('RUNNING_IN_DOCKER_CONTAINER')) { ...
ENV RUNNING_IN_DOCKER_CONTAINER=1

# Install Some Additional Packages
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    unzip \
    libaio1 \
    jpegoptim optipng pngquant gifsicle \
    curl \
    wget \
    git \
    firebird-dev

# Copy default php.ini
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

# Build firebird driver
RUN cd /tmp; \
    git clone -v https://github.com/FirebirdSQL/php-firebird.git; \
    cd php-firebird; \
    phpize; \
    CPPFLAGS=-I/usr/include/firebird ./configure ; \
    make; \
    make install; \
    echo "extension=interbase.so" > /usr/local/etc/php/conf.d/ext-interbase.ini;

# Remove Cache
RUN apt-get clean && rm -rf /var/lib/apt/lists*

# Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# PDO_Firebird (not necessary if we go with AdoDB)
RUN docker-php-ext-install pdo_firebird

# Restart apache
RUN apachectl -k restart;
# docker-compose.yaml

version: '3'

services: 
  web_app:
    container_name: my-app
    build: 
      context: .
      dockerfile: Dockerfile
    image: my-apache-php74-firebird
    tty: true
    ports:
      - "8080:80"
    working_dir: /var/www/html
    volumes:
      - .:/var/www/html/
e787 commented 1 year ago

That being said, it would still be nice to have a native adapter so if anyone reading this has an idea how to compile the native php-firebird extension on ARM, please share your findings.

Hi @janzikmund. In my experience, you must have an arm version of Firebird to successfully compile the extension on an arm mac.

Since Firebird 4.0.2, there is official support for mac arm, meaning you can compile the source following the build instructions in their GitHub workflows file main.yml (https://github.com/FirebirdSQL/firebird/blob/v4.0-release/.github/workflows/main.yml). I have no idea why there is no official binary, though.

Anyway, I'm attaching my compilation of version 4.0.2-2816. Hope it helps. Firebird-4.0.2-2816-ARM64.pkg.tar.gz

By the way, I use the same steps described in first post to compile php-firebird.

developerluanramos commented 5 months ago

@janzikmund very great solution! Solved my issue. I was trying to mount exactly that. Thank you !!