How to use vcpkg with universal binaries on macOS
Vcpkg is a great tool to build the dependencies for your cmake c++ project. Unfortunately - at the time of this writing - it does not support building libraries as universal binaries for macOS.
In this post, I will write about how I used the tool lipo-dir-merge together with vcpkg to install a universal binary version of libcurl. Then I’ll link a simple example app against it.
Installing libcurl via vcpkg
Vcpkg doesn’t support universal binaries yet. However, you can use it to build the x86 and the ARM version of libraries by specifying a triplet. Let’s use this to install the two versions of libcurl:
$ cd /path/to/vcpkg/
$ ./vcpkg install --triplet=x64-osx curl
... Lots of text ...
$ ./vcpkg install --triplet=arm64-osx curl
... Lots of text ...
Vcpkg will install each version of libcurl into a separate directory tree under installed
:
$ cd installed
$ ls -1
arm64-osx
vcpkg
x64-osx
Merging both versions into a universal binary
Using lipo-dir-merge, we can now merge the content of arm64-osx
and x64-osx
into a single directory containing the universal binary version of the libraries. lipo-dir-merge does so by traversing both directory trees, copying all files from the first tree. When a static library is encountered, it merges it with the one from the second tree.
While in the /path/to/vcpkg/installed
directory, run the following command:
$ python3 /path/to/lipo-dir-merge.py arm64-osx x64-osx uni-osx
Which will create a new uni-osx
directory:
$ ls -1
arm64-osx
uni-osx
vcpkg
x64-osx
How to use the universal library in a commandline app
This example uses the exmpl-cmake-universal-app project, which links against libcurl and simply prints the version of the curl library upon start.
After downloading it, you can use the standard cmake workflow to build the app. Just make sure to include the installed/uni-osx
directory in the CMAKE_PREFIX_PATH
and set the VCPKG_TARGET_TRIPLET
properly.
$ cd /path/to/exmpl-cmake-universal-app
$ mkdir build && cd build
$ cmake -DCMAKE_PREFIX_PATH=/path/to/vcpkg/installed/uni-osx -DVCPKG_TARGET_TRIPLET=uni-osx ..
$ make
$ lipo -info exmpl-app
Architectures in the fat file: exmpl-app are: x86_64 arm64
$ ./exmpl-app
CURL version is: libcurl/8.2.0-DEV SecureTransport zlib/1.2.13
As you can see from the lipo -info
command, the resulting binary is indeed universal.