Firebird 3 was released almost a year ago and it has already got two minor releases. But there is still no official packages for MacOS. So this post is about my humble attempt to build it on MacOs from source code. Most of the instructions are taken from Paul Beach’s Firebird Devel list post or from his blog.

This area is not my expertise so there may be inefficient or even wrong approaches  so use it on your own risk and any suggestions, corrections and improvements are always welcomed.

When building needed libraries and Firebird source code, my working directory was /Users/ct/prj so when you see these directory in code blocks below you have change it to your working directory name.

First we should stop firebird service if it is installed:

>sudo launchctl unload /Library/LaunchDaemons/org.firebird.gds.plist

Building ICU

Firs step is downloading and building ICU library. I’ve used version 54.1, but I think more recent versions can also be used without problem. After downloading and extracting ICU, we have to modify icu/source/config/mh-darwin config file

Edit lines 30-35 from this

## Compiler switches to embed a library name and version information
ifeq ($(ENABLE_RPATH),YES)
LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(libdir)/$(notdir $(MIDDLE_SO_TARGET))
else
LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(notdir $(MIDDLE_SO_TARGET))
endif

to this (note the install path change of LD_SONAME) :

## Compiler switches to embed a library name and version information
ifeq ($(ENABLE_RPATH),YES) 
LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name $(libdir)/$(notdir $(MIDDLE_SO_TARGET))
else
LD_SONAME = -Wl,-compatibility_version -Wl,$(SO_TARGET_VERSION_MAJOR) -Wl,-current_version -Wl,$(SO_TARGET_VERSION) -install_name /Library/Framework/Firebird.framework/Versions/A/Libraries/$(notdir $(MIDDLE_SO_TARGET))
endif

then we can build icu.

cd icu/source
./configure --enable-renaming=no
make
sudo make install

Building Firebird

Download Firebird source code and extract it

cd ~/prj
tar -xzf Firebird-3.0.2.32703-0.tar.bz2
cd Firebird-3.0.2.32703-0

File Modifications

I’ve made below modifications to source files in order to get rid of build errors

builds/posix/prefix.darwin_x86_64

Change line #22 from this

DYLD_LIBRARY_PATH=$(HOME)/icu54/icu/source/lib

to this

DYLD_LIBRARY_PATH=$(HOME)/prj/icu/source/lib

extern/cloop/src/tests/test1/CTest.c

Change line #23 to prevent malloc import error from this

#include <malloc.h>

to this

#include <malloc/malloc.h>

src/common/os/darwin/mod_loader.cpp

Change lines 45-47 from this

DlfcnModule(void* m)
        : module(m)
    {}

to this :

DlfcnModule(MemoryPool& pool, const Firebird::PathName& aFileName, void* m)
            : ModuleLoader::Module(pool, aFileName),
              module(m)
    {}

Also change line 100 from this

return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(module);

to this :

return FB_NEW_POOL(*getDefaultMemoryPool()) DlfcnModule(*getDefaultMemoryPool(), modPath, module);

src/remote/SockAddr.h

Change lines 91-95 from this

#define AF_INET6_POSIX     10
#define AF_INET6_WINDOWS   23

inline void SockAddr::checkAndFixFamily()
{
#if AF_INET6 == AF_INET6_POSIX
    if (data.sock.sa_family == AF_INET6_WINDOWS)
#elif AF_INET6 == AF_INET6_WINDOWS
    if (data.sock.sa_family == AF_INET6_POSIX)

to this

#define AF_INET6_POSIX     10
#define AF_INET6_WINDOWS   23
#define AF_INET6_DARWIN         30

inline void SockAddr::checkAndFixFamily()
{
#if AF_INET6 == AF_INET6_POSIX
    if (data.sock.sa_family == AF_INET6_WINDOWS)
#elif AF_INET6 == AF_INET6_WINDOWS
    if (data.sock.sa_family == AF_INET6_POSIX)
#elif AF_INET6 == AF_INET6_DARWIN
    if (data.sock.sa_family == AF_INET6_WINDOWS)

Firebird needs libtommath to get built which is also distrubuted with Firebird source, but I’ve preferred pre-built library which can be installed via macports as

sudo port install libtommath

After this we can start to build Firebird, first configure

./autogen.sh CFLAGS="-I/Users/ct/prj/icu/source/common -I/opt/local/include/libtommath" LDFLAGS="-L/Users/ct/prj/icu/source/lib -L/opt/local/lib" --enable-raw-devices=no

then make

class="wrap:true">make CXXFLAGS="-I/Users/ct/prj/icu/source/common -I/Users/ct/prj/icu/source/i18n -I/usr/include/malloc/malloc.h -I/opt/local/include/libtommath -msse4.2"

Installing

At this point you should have compiled binaries in gen/Release/firebird directory. As I do not know how to make a pkg file for MacOs I’ve manually copied files to Library/Frameworks folder and made setup operations manually as :

sudo cp -r gen/Release/firebird /Library/Frameworks/

sudo cp builds/install/misc/firebird.conf.in /Library/Frameworks/firebird/firebird.conf
sudo cp builds/install/misc/fbintl.conf /Library/Frameworks/firebird/intl/

sudo ln -s /Library/Frameworks/firebird/lib/libfbclient.dylib /usr/local/lib/Firebird.dylib

sudo /Library/Frameworks/firebird/bin/gsec -add sysdba -pw masterkey -user sysdba

If you have not installed firebird from an official package then your system does not have firebird user and group. To create them we can use copy user creation code from builds/install/arch-specific/darwin/install-script. Let’s create a temp script file :

nano /tmp/create_fb_users.sh

copy and paste below code block :

#!/bin/sh

# Now create the firebird group
echo "Create the Firebird group 10.7+"
if dscl localhost -read /Local/Default/Groups/firebird 2&>1 /dev/null; then
    echo "Group Found" 
else
gid=501
dscl localhost -search /Local/Default/Groups PrimaryGroupID $gid | grep $gid 
while [ "$?" = "0" ]; do 
    let "gid =$gid+1"
    dscl localhost -search /Local/Default/Groups PrimaryGroupID $gid | grep $gid
done
    dscl localhost -create /Local/Default/Groups/firebird
    dscl localhost -create /Local/Default/Groups/firebird Password "*"
    dscl localhost -create /Local/Default/Groups/firebird PrimaryGroupID $gid
    dscl localhost -create /Local/Default/Groups/firebird RecordName firebird
fi

# Now create the firebird user
echo "Create the Firebird user 10.7+"
if dscl localhost -read /Local/Default/Users/firebird 2&>1 /dev/null; then
    echo "User Found"
else
ugid=501
dscl localhost -search /Local/Default/Users UniqueID $ugid | grep $ugid 
while [ "$?" = "0" ]; do 
    let "ugid=$ugid+1"
    dscl localhost -search /Local/Default/Users UniqueID $ugid | grep $ugid 
done
echo "create the firebird user 10.7+"
    dscl localhost -create /Local/Default/Users/firebird
    dscl localhost -create /Local/Default/Users/firebird NFSHomeDirectory /Library/Frameworks/firebird
    dscl localhost -create /Local/Default/Users/firebird Password "*"
    dscl localhost -create /Local/Default/Users/firebird UserShell /bin/tcsh
    dscl localhost -create /Local/Default/Users/firebird RecordName firebird
    dscl localhost -create /Local/Default/Users/firebird PrimaryGroupID $gid 
    dscl localhost -create /Local/Default/Users/firebird UniqueID $ugid
    dscl localhost -create /Local/Default/Users/firebird RealName "Firebird Database"
fi

Save file and

sudo sh /tmp/create_fb_users.sh

As we manually copied binary files we have to modify service loading script too.

sudo nano /Library/LaunchDaemons/org.firebird.gds.plist

Edit file contents as :


<plist version="1.0">
<dict>
<key>Label</key>
<string>org.firebird.gds</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Frameworks/firebird/bin/fbguard</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>

Now we can start Firebird service :

sudo launchctl load /Library/LaunchDaemons/org.firebird.gds.plist

You should check /Library/Frameworks/firebird/firebird.log file for any error messages.

As I’ve stated above, although these steps let me build Firebird on MacOs they may not be a hundred percent correct so if you think they should be corrected in any way please do leave a comment.