Unfortunately I tend to find myself compiling Linux apps for OSX more often then I’d like 😔

Anyway, say you’ve got a C++ binary compiled successfully on OSX, but now you want to distribute that binary as an OSX app. That’s easy, just create the .app folder structure, as documented all over the web. But what if it calls on some libraries and you want to package them with your app bundle so it works across any system without any external dependencies? There’s a few steps that you need to do and it’s not that difficult - but I’ll admit, it took me a while to figure it out (in my Hyne post, I mentioned I’d attempted to use install_name_tools but couldn’t get it to work… until now!). I’ll speak about dynamic libraries only here, although I think the same applies to Frameworks too. NOTE: It really helps if you’ve got as many of your library dependencies compiled statically, as you’ll see later.

Most people simply rely on XCode to do all this work for them (and there’s some wisdom in that as you’re about to discover), but in my case as I was using portable code, it wasn’t configured to use XCode, only standard configure/make, so I decided to do it manually steps. Anyway I prefer the CLI 😏

Step 0: how to reference another executable within your app bundle from code

The title of this post says “Binaries” - thats plural. If you just want to package a single executable into an app file you can skip this step; this is for those instances where you have multiple executables and you’d like to reference them within your main executable.

This commit shows how to do it. Few points:

  1. Notice the guard macro - if you want your code to be portable, make sure you include a guard macro so that all of this only compiles on OSX, as App bundles aren’t available on other systems!
  2. As of OSX 10.11, you need to add #include <CoreFoundation/CFBundle.h> for bundle related code to work.
  3. Use CFBundleCopyAuxiliaryExecutableURL to get a CFURLRef pointing to the binary (in this case, named “abgx360”). Don’t worry about how this is figured out automatically, OSX magic!
  4. Declare a char array - either calculate the size it should be somehow or make it real big in case the user places your app in a folder with a large path. Why char? Because we want the data usable in C++ code, assuming the rest of the code was written in standard C++, not Objective-C/C++.
  5. CFURLGetFileSystemRepresentation will convert your CFURLRef to string, storing result in the char array you declared previously. Notice reinterpret_cast<UInt8*>, because the function expects a UInt8 buffer, but thats Objective-C and we want to get to standard C++ to use with the rest of the program.
  6. The result will be a char array/buffer with the value of the absolute path to the other binary specified in CFBundleCopyAuxiliaryExecutableURL. But notice I did a if statement to check for the existence of '\0', the NULL terminator, in case there was an error in finding the path. Unfortunately checking for “NULL” return value from the OSX CoreFoundation calls won’t cut it.

Step 1: create app bundle folder structure and place binaries as appropriate

e.g.

MyApp.app
    --Contents              <-- REQUIRED
        --MacOS             <-- REQUIRED
            -MyApp          <-- REQUIRED - must be same name as the .app filename, unless using a Info.plist file
            -other_binary
        --Libraries
        --Frameworks
        --Resources
        ...

Step 2: figure out which libraries are being dynamically loaded, and are not part of the default system

cd MyApp.app/Contents/MacOS
otool -L MyApp

You’ll get an output like below:

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/usr/local/opt/libpng/lib/libpng16.16.dylib (compatibility version 41.0.0, current version 41.0.0)
/usr/local/opt/jpeg/lib/libjpeg.8.dylib (compatibility version 13.0.0, current version 13.0.0)
/usr/local/opt/libtiff/lib/libtiff.5.dylib (compatibility version 8.0.0, current version 8.4.0)
/System/Library/Frameworks/WebKit.framework/Versions/A/WebKit (compatibility version 1.0.0, current version 601.7.7)
/usr/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 8.0.0)

I can tell which are system provided libraries (anything in /System is a good bet, and /usr/lib too). As I use Homebrew, I know that the /usr/local/paths are all non-default, meaning I’ll have to distribute them with my app.

Step 3: copy non-default libraries to my “Libraries” folder in my app bundle

cp -R /usr/local/opt/libpng/lib/libpng16.16.dylib ../Libraries/
cp -R /usr/local/opt/jpeg/lib/libjpeg.8.dylib ../Libraries/
cp -R /usr/local/opt/libtiff/lib/libtiff.5.dylib ../Libraries/

Using the -R flag to copy recursively, including any symbolic links (doesn’t apply in my case as these are just single dylib files).

Step 4: tell my main binary to use the locally copied dylib files instead of the ones installed on my system

install_name_tool -change /usr/local/opt/libpng/lib/libpng16.16.dylib @executable_path/../Libraries/libpng16.16.dylib MyApp
install_name_tool -change /usr/local/opt/jpeg/lib/libjpeg.8.dylib @executable_path/../Libraries/libjpeg.8.dylib MyApp
install_name_tool -change /usr/local/opt/libtiff/lib/libtiff.5.dylib @executable_path/../Libraries/libtiff.5.dylib MyApp

-change flag, changes the paths that my binary will use for the 3 libraries. It’s important that the first parameter (/usr/local paths) are exactly the same as what was listed by otool previously. Otherwise it won’t find the reference.

Step 5: change my locally copied dylib files ids so that they’re “aware” that they are local copies

Yeah OK, I don’t understand exactly what this step does 😂, but its needed.

cd ../Libraries
sudo install_name_tool -id @executable_path/../Libraries/libpng16.16.dylib libpng16.16.dylib
sudo install_name_tool -id @executable_path/../Libraries/libjpeg.8.dylib libjpeg.8.dylib
sudo install_name_tool -id @executable_path/../Libraries/libtiff.5.dylib libtiff.5.dylib

Notice sudo this time, and the -id flag. You may not need sudo, but I did. I guess it’s because I’m changing a library that I don’t technically own (didn’t build myself)?

Step 6: now check my locally copied dylib files to see if THEY are referencing any non-default libraries, and copy those libraries and change references accordingly

Yes now you see why this is a long winded process. Basically recursively repeating the above steps for each library file that references yet another non-default library. Each time one is found (using otool -L) the referenced file needs to be copied locally, changed in the calling library (using -change flag), then updating the id (using -id flag) of the called library. Finally the newly copied library needs to be checked (using otool -L again) to see if it uses another library. And so on.

This is also why I mentioned it’s super handy to have built as many non-default libraries as possible statically - doing so prevents this at the cost of larger storage and memory space.

Anyway, luckily in my example I have only 1 local dylib file that refers to another library - which just so happens to be a library I already have locally!

otool -L libtiff.5.dylib

resulted in:

@executable_path/../Libraries/libtiff.5.dylib (compatibility version 8.0.0, current version 8.4.0)
/usr/local/opt/jpeg/lib/libjpeg.8.dylib (compatibility version 13.0.0, current version 13.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)

The first line, with @executable_path is the id of the current dylib file that I changed previously. Something similar will be there for all the other dylib files changed. It’s the second line that needs to be changed; as it refers to libjpeg.8.dylib which I have locally already, I just need to update the reference in this file to use the local copy too.

sudo install_name_tool -change /usr/local/opt/jpeg/lib/libjpeg.8.dylib @executable_path/../Libraries/libjpeg.8.dylib libtiff.5.dylib

So I’m (or rather, sudo is) telling libtiff.5.dylib to -change it’s reference of /usr/local/opt/jpeg/lib/libjpeg.8.dylib to @executable_path/../Libraries/libjpeg.8.dylib.

And fini! The app bundle should now work on a standard OSX install with all dependencies contained locally! 😁

Prologue

We’re currently in the process of doing some construction work in our house - a loft conversion and potential kitchen extension. A few weeks ago, a man named Kevin McCarthy contacted us offering his company’s services. Dressed in a formal suit, he explained that Signature Extensions Ltd was a construction company that he ran and offered us a great deal for the work to be carried out. It should be noted that this was significantly cheaper (£20k cheaper) than quotes we received from two other contractors. When my mum asked why it was so much cheaper, Mr McCarthy told us that it was because they would do only the construction work, not the furnishing - a pure bare-bones project only.

A Deal Too Good to be True

Obviously such a proposition was still very enticing for us - £20k savings would allow us to pay extra to someone else for furnishing and still have saved a decent chunk of change! Furthermore, Mr McCarthy’s professional manner - smartly dressed and well presented, along with a professional looking bounded booklet which specified exactly in detail what work would be carried out, the payment schedule, and listings of numerous (40+) other works that had been carried out around Essex, all served to impress. He stood out compared to the other 2 contractors that we had reached out to (who, when they came to our house, looked as if they had either been, or were on their way to, another construction site and simply sent us an email/letter summarising the work to be carried out and total cost of the work). He also gave us a contact number for one of the nearby property’s that he had finished work on so that we could arrange a visit to see his work and get feedback from. My mum did indeed contact this number and received a Glowing (yes with a capital G) recommendation of the Amazing work he had done and scheduled to go and see the property.

All seemed well and my mum felt convinced that we had found a great deal and nearly agreed to hire Kevin Mccarthy and his Signature Extensions Ltd firm. But the skeptic within me was not so sure - this was a classic case of a deal too good to be true. As non-builders we didn’t actually understand anything in the contract he proposed and a glowing review for a bare-bones construction work? I was not sold. So I decided to use my Google-Fu and see what I could find.

The Quest for Secrets

Firstly, buried deep in the interwebs. It’s worth noting the locations mentioned in the article - “Kevin McCarthy, of Great Notley, Braintree” and “McCarthy, who runs Pasture Construction, in Lodge Lane, Grays, operated across Essex, Kent, Hertfordshire and London”. Now, granted Kevin McCarthy is a common name and yes it’s perfectly possible for there to be more than one Kevin McCarthy who owns his own construction firm in Essex.

I then switched to the amazing online resource of the UK’s companies house registrar. Using this, I found the record of Signature Extensions Ltd (the company number from Mr McCarthy’s booklet confirmed that this is the same company) and thus the man who owns it. Seems OK, although the company’s registered location differed from the address in the booklet. Bit odd but I let it pass. Scrolling down, seems as if Mr McCarthy has been involved with a few other construction firms, including a firm Jardine Construction Ltd with a registered location of 49 Lodge Lane, Grays, England. Lodge Lane, Grays - the same street from the news article? Well looks like Jardine Construction Ltd was dissolved but he’s got another company currently active called Jardine Home Extensions Ltd - in other words a slight rename and relocation of the company (which is perfectly normal by the way). Registered location is interesting here too: “54 Petworth Close, Great Notley, Braintree, United Kingdom”. Great Notley… Braintree… again, same as the article.

The Truth Revealed?

Alarm bells were ringing everywhere for me now. I then did a search for Jardine Home Extensions Ltd and found this. There’s a single review by an anonymous user who says, quote:

Please do NOT use this company. We booked them to build a single storey extension is 2012 and it is still unfinished in 2014. Leaky skylights and other unfinished work, not sorted, as Mr McCarthy ignores any attempt to contact him. Not on site all the time as promised, can’t get building certificate as work not complete to standard. NOT RECOMMENDED!

Finally, I made a call to Citizens Advice Consumer Helpline and spoke to an advisor who couldn’t find any record of Signature Extensions Ltd in their trader approved database - the advisor mentioned that this is perfectly normal by the way, many reputable companies aren’t on their database for a number of reasons. However, a week later I got a letter from a Trading Standards Enforcement Officer from the London Borough of Barking and Dagenham, who informed me that Signature Extensions Ltd’s address from the booklet - the address that differed from the registered company address - is in fact a PO Box address and that there is no actual company office located here. The letter also mentioned that whilst they couldn’t pass opinions about traders, they had enclosed a press article for me to read from a few years ago - the same article that I posted above funnily enough.

Epilogue

I’ll leave you, reader, to make your own opinions about Mr Kevin McCarthy and Signature Extensions Limited, just as the trading enforcement officer had left me to make my own opinions. I’ll also pass on their advice to consider using approved traders via well known sites like Buy With Confidence, Consumer Codes Approval Scheme and Checkatrade. An even more interesting tip that the officer let me in on: as long as you pay £100+ on credit card then your credit card company is liable for any loss between £100 to £30k that you may incur - so if you’re planning building work for £20k for example, if you pay only £101 of a deposit for instance using your credit card, the full £20k work is insured by your credit card company! Apparently this is something the credit card companies keep quiet about and have even tried to have overturned in court many times since the Section 75 law was established in 1974 - they have thus far been unsuccessful.

Notes by the Author

Finally, my own advice - do your background research. You never know the stories you may uncover.

Hyne (forum/GitHub) is a cross-platform Final Fantasy 8 save game editor. It can import/export/convert game saves from the PSX/PC/Emulator versions of Final Fantasy 8, and it runs on Windows/OSX/Linux! The last binary release for OSX however was back in 2013 and there’s been several version updates since. Although the developer will release future versions automatically using Travis on GitHub, I figured this would be a good chance to experiment with compiling a QT app!

TL;DR to just get Hyne installed on OSX

QT is a well known cross-platform GUI library. I’ve experimented a bit, so this was a chance to learn a bit more about it. The key challenge here was to try and get the app built using the Homebrew-provided QT library. I’m a big fan of Homebrew on OSX and like to keep as much software as possible managed by it.

Step 1: install QT via Homebrew - Hyne uses QT5 specifically

brew install qt5

QT5 is keg-only. This explains what that means and has some guidance on what to do (hint: DON’T brew link --force as is commonly suggested on the Internet! It’s best to keep the QT5 installation segregated from the rest of the system to prevent future conflicts).

Step 2: extend system path to include the QT binaries location

export PATH=$(brew --prefix)/opt/qt5/bin:$PATH

(FYI $(brew --prefix) evaluates to /usr/local on my system.)

Now commands like qmake will work for the current shell only.

Next step is to run qmake. Now here’s where things get tricky. When I did step 1, Homebrew said this:

If you build your own software and it requires this
formula, you'll need to add to your build variables:

    LDFLAGS:  -L/usr/local/opt/qt5/lib
    CPPFLAGS: -I/usr/local/opt/qt5/include

Makes sense. But how do I pass these variables to the compiler since I’m not actually invoking the compiler directly? Like most C++ projects, Hyne uses a Makefile. But actually I’m not even writing my own Makefile, I’m using qmake to generate one for me! The Homebrew wiki I linked to earlier has an example of what to do if using a configure script, but what about when using qmake?

Well I could use qmake and then edit the Makefile and add the extra flags wherever needed. That’s a dirty hack though and it’s not going to be pretty in the long run as every time I run qmake, I’ll have to edit the Makefile manually again. What about editing the Hyne.pro file? (QT project file that qmake reads from). That could work, except then I’ve changed a file in the repository, meaning every time I pull from upstream I’ll have to fiddle around with merges and potential conflicts.

Turns out qmake does have variables that it can use to pass to the Makefile. But now another problem comes - the instructions tell me to use LDFLAGS and CPPFLAGS, and qmake doesn’t have either of those!

…or does it? QT docs says I can use QMAKE_LFLAGS for LDFLAGS (why they excluded the D is beyond me). CPPFLAGS was more tricky; turns out CPPFLAGS are usually passed to both the C and C++ compiler. So essentially, CPPFLAGS = CFLAGS + CXXFLAGS (C compiler and C++ compiler), which qmake has via QMAKE_CFLAGS and QMAKE_CXXFLAGS.

Step 3: run qmake, supplying the compiler flags to it, which will be passed to the Makefile

qmake "QMAKE_CFLAGS+=-I$(brew --prefix)/opt/qt5/include" "QMAKE_CXXFLAGS+=-I$(brew --prefix)/opt/qt5/include" "QMAKE_LFLAGS+=-L$(brew --prefix)/opt/qt5/lib"

Note the += to append the flags to whatever else may be in use, and no spaces. Finally now I have the Makefile.

Step 4: run make (j flag for multi-threading)

make -j5

In the case of the Hyne project, this will result in an OSX .app bundle. Now Hyne was developed in French, but luckily the translations have already been done and put in the QT language format, .ts files. However, just because they’re included in the TRANSLATIONS variable in the .pro file, doesn’t mean qmake and make include them in the final app. In the same shell (still need that path from step 2):

Step 5: create binary format for the English and Japanese translations

lrelease Hyne.pro

This will spit out 2 .qm files, which for Hyne, just have to copied to Hyne.app/Contents/MacOS/

I could have stopped here, but I also wanted to distribute the binary and be able to use it on a Mac without QT (specifically without QT5 via Homebrew) so I had to package the app to include a copy of the required QT frameworks, and modify the binaries to reference the local copies. This link explains it in full detail, but I’ll be honest, I followed the install_name_tool steps but couldn’t get it to work. At the end of that page though, it describes the Mac Deploy Tool which is honestly so much easier.

Step 6: package QT frameworks with .app bundle

macdeployqt Hyne.app

Voilà! So to summarise the steps:

brew install qt5
export PATH=$(brew --prefix)/opt/qt5/bin:$PATH
qmake "QMAKE_CFLAGS+=-I$(brew --prefix)/opt/qt5/include" "QMAKE_CXXFLAGS+=-I$(brew --prefix)/opt/qt5/include" "QMAKE_LFLAGS+=-L$(brew --prefix)/opt/qt5/lib"
make -j5
lrelease Hyne.pro
macdeployqt Hyne.app

TL;DR

The current version of Hyne is 1.9.1; to make it easier for people who just want the .app file, I added the release to Homebrew Cask. So just get Homebrew Cask set up, then:

brew cask install hyne
First Post - Creating a Website

I’ve been meaning to create a personal website for years. Finally with some spare time on my hands, I decided to give it a go. I’d done web design years ago, so I knew the basics - HTML / JS / CSS / PHP / SQL. But nowadays there’s all kinds of frameworks and tools out there and I’d not kept up with the latest trends.

Well it seems the latest trend is to recommend site builders like Wordpress / Squarespace / Wix.

…Yeah no thanks.

Call me old fashioned, but I like to see some CODE when I’m building a website. There’s a level of precision that you just can’t achieve with a ‘click and get rolling’ website, and whilst I’m not a web dev guru by any means, it’s nice to know that I won’t be limited now or in the future. A good old web server with some files to deploy for me please!

My cousin Viknesh recommended Adobe Muse. He’s a pretty good graphic designer so I gave it a go. Sadly it didn’t meet my expectations; I found it rather clunky and again, lacking in precision (but at least it spits out raw HTML / CSS / JS files which you can technically edit yourself, so thats a plus).

I asked my good friend Jayen, and he recommended Jekyll. There’s a bit of a learning curve and I wouldn’t call it beginner friendly, but so far I’m impressed! You write a few YAML, Ruby and HTML files that act as templates, and actual content as plain text files. Jekyll then merges the two together to generate the site. Combined with some open source themes, you can get a website rolled out pretty quickly but with the added advantage of it being fine controlled.

So yep, I’ll be using Jekyll + Sublime Text for the time being and probably in any future websites I create. Considering there’s nothing particularly unique about this site, I’m sure I could have just used a site builder, but… fine control. Or maybe I just like to edit files directly because it reminds me of the early 2000s, when I used to use Notepad for site building 😂