Using TagLib in Xcode 7
Update 11/15/15: TagLib's C bindings are quite limited, as I found out after writing this article. I wrote a bit more about my experience in a follow-up post. The information here may be useful regardless, so I'm leaving it be.
I went looking for Mac OS X-compatible library for editing MP3 ID3v2 tags. TagLib 1.9.1 sounds fit for my purposes, but I ran into a few issues getting started with it.
Compilation
Their bootstrapping instructions are a little outdated, targeting Mac OS X 10.4. I replaced a few settings with modern equivalents for Mac OS X 10.11, for an updated CMake command:
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD\_FRAMEWORK=ON -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_OSX_SYSROOT=`xcode-select --print-path`/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 -DCMAKE_OSX_ARCHITECTURES="x86_64"
The CMake command creates a Makefile
which worked fine when I ran make
in the TagLib root directory.
Adding the generated taglib/tag.framework
and bindings/c/tag_c.framework
frameworks to an Xcode project results in linker errors, so minor modifications are still necessary. Xcode expects a particular directory structure in frameworks: first, a version of the framework and all it's files must be present in .framework/Versions/A
. Second, a symlink must exist at .framework/Versions/Current
that points to the current version of the framework. I have not seen any frameworks with multiple versions included, so I expect that making Current
a symlink to A
will work in more or less all cases. TagLib's generated frameworks include only one version. Renaming that version directory from the version number to A
, then re-creating the symlink using cd .framework/Versions && rm Current && mv A && ln -s A Current
. These changes may be performed either before or after adding the frameworks via Xcode.
After all of these steps, Xcode should no longer have additional errors or warnings due to TagLib.
Swift
Using TagLib from Swift requires yet another step. In the top level of tag_c.framework
1, create a directory Modules
and inside that directory, create a file module.modulemap
:
framework module tag_c { umbrella header "tag_c.h" }
After adding the module map, import TagLib using import tag_c
2 in Swift or @import tag_c
in Objective-C. Now tag away!
Swift currently does not support calling into C++ code, so TagLib must be used through its C bindings.↩
The name of the framework and the name of the module must match, hence the use of
tag_c
. Renamingtag_c.framework
toTagLib.framework
, and replacingframework module tag_c
withframework module TagLib
should allow the use ofimport TagLib
, if so desired.↩