Build KeePassX In OSX Mountain Lion (without MacPorts!)

Recently, I wanted to try out an addition to KeePassX 2.0 that is currently sitting as a pull request on GitHub. I cloned the code, but quickly realized it wouldn’t be as easy as opening in Xcode and clicking ‘Run’ (yes, I’m spoiled :p).

I looked at the INSTALL file, which helpfully has a section called “Building on Mac OS X”. However, the first task gave me pause: install MacPorts. I won’t profess to have a lot of experience using MacPorts, but I’ve read some negative things regarding its complexity and brittleness. Not to mention I’m already knee-deep in brew kegs, which in my experience have been downright pleasing to install and use.

Naturally, I decided to try and get all of the dependencies from brew and build KeePassX without MacPorts.

Step 1: Prerequisites

This, surprisingly – or unsurprisingly if you have as much faith in brew as I do – was easy. I adapted the dependency install instructions from MacPorts to brew very easily (the only difference was qt-4mac became qt).

brew install cmake qt4 libgcrypt zlib

Might as well get into the build folder while we’re at it (this assumes you’re already in the KeePassX code root):

mkdir build
cd build

NOTE: Everything below this line is outdated and has been fixed in recent commits to the repo (the app can now be built with Clang!). To finish compilation, just run

cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64"
make package

I will leave the below instructions for posterity.


Step 2: cmake the makefile

Up front I should say I am a bit unfamiliar with makefiles and cmake and the like. As an iOS developer, I am mostly sheltered from that level of compiler interaction. So when I ran the command as given in INSTALL and got a strange error, I almost gave up. The error I got was:

-- Performing Test ZLIB_SUPPORTS_GZIP - Failed
CMake Error at CMakeLists.txt:181 (message):
  zlib 1.2.x or higher is required to use the gzip format

-- Configuring incomplete, errors occurred!

Googling was almost zero help, but I did find one mention of simply commenting out that test in CMakeLists.txt and moving on. So I did, by commenting the following three lines with a #:

#if(NOT ZLIB_SUPPORTS_GZIP)
#  message(FATAL_ERROR "zlib 1.2.x or higher is required to use the gzip format")
#endif()

I also decided to specify the location of the brew-installed zlib (instead of letting it use the OSX-supplied version), which according to brew was in /usr/local/opt/zlib/lib. So I added -DZLIB_ROOT=/usr/local/opt/zlib/lib to the call.

After doing these things, cmake completed successfully, but make package (the next step) failed rather quickly with a warning about unsupported compiler flags:

clang (LLVM option parsing): Unknown command line argument '-stack-protector-buffer-size=4'.  Try: 'clang (LLVM option parsing) -help'
clang (LLVM option parsing): Did you mean '-path-profile-verifier-file=4'?
make[2]: *** [src/http/qjson/CMakeFiles/qjson.dir/parser.cpp.o] Error 1
make[1]: *** [src/http/qjson/CMakeFiles/qjson.dir/all] Error 2
make: *** [all] Error 2

This is because cmake set up the makefile to use the system default compiler, which happens to be clang, while the build scripts are all expecting to use gcc. To change this, we pass a few extra command line options to cmake and explicitly tell it to use gcc and c++.

Here’s what the final cmake invocation looks like:

cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64" -DZLIB_ROOT=/usr/local/opt/zlib/lib -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++

Step 3: make package

… that’s it! If that completes successfully, you are left with a .pkg file that has KeePassX.app in it, ready to be put in /Applications and opened! Congrats!

Notes:

  • If you re-run cmake at any point, make sure you clear its cache by destroying and re-creating the build folder. If you don’t, strange things can happen.
  • If you don’t have gcc/g++ (run which gcc and see if there is output), download the Xcode Command Line Tools.

References: