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.