We don’t yet rely on any 10.12 specific API other than os_log which can be skipped without user impact.
Unfortunately when trying to build for 10.10 using latest Xcode/SDK the linker gives an error for missing symbol: _objc_loadClassref.
Going forward we will require 10.12 but as there is no non-beta build for 10.11 users yet, I wanted to make one.
The C++20 feature list has been frozen although clang (and libc++) doesn’t yet have full support and the clang option we are using is -std=c++2a to indicate that things may still change.
I’m keeping it in the sources though as it provides semantic value and may be required if the build system is updated, e.g. we may want to create static libraries for some targets and would thus need to know which symbols to export.
This changes a bunch of things:
1. Each framework now creates its own include directory for exported headers, and any target linking with this framework, gets that directory added to its include search path. This ensures deterministic behavior, unlike previously where a single shared directory was used, so even if target A did not explicitly link with target B, there was a reasonable chance that target B’s headers would be available when target A was built.
2. There is a new IMPORT keyword to indicate that a target depends on the headers of another framework but does not want to link with it. For example the `commit` shell command imports headers from the CommitWindow framework (related to their communications protocol) but linking with the CommitWindow framework would not be practical (as that would bring in all the resources of the CommitWindow).
3. All embedded targets are signed before being copied to their destination.
4. A new CS_ENTITLEMENTS keyword allows specifying `codesign` entitlements. Currently the hardened runtime is enabled, although this does make development problematic, as modifying files of a running instance (as done during rebuild) can cause TextMate to crash with EXC_BAD_ACCESS (Code Signature Invalid). Worse though, it seems the system has a cache of blacklisted executables indexed by inode. So if e.g. the embedded `mate` executable gets blacklisted, one has to manually remove and rebuild it, before it gets possible to use it again (by default, rebuilding causes the inode to be re-used, but I may change the build system to unlink before copy).
5. The build file no longer contains rules related to deployment. Instead variables are declared that a user build file can reference to extend the build with notarization/deployment rules (without having to hardcode build directory paths).
6. The code has been made modular with a Compiler super class that is subclassed to add support for file transformations (xib, ragel, asset catalogs, etc.) and a transformed file can have its own settings.
7. If target A links with target B, the linker flags of target B will now be included when linking target A.
8. Currently no indexing of help books. Unsure if this is actually useful.
9. Previously it was possible to have umbrella targets that would not generate any output, but just change settings for their sub-targets. This is no longer supported, as the implementation was arcane. I would like to introduce a different system for managing sectioned settings. Related to this; settings in target files are now always merged, regardless of whether using ‘=’ or ‘+=’.
We no longer build frameworks as standalone targets but instead link it all together, which also means resources from “frameworks” will end up in the main bundle.
Currently the new build file generator does not create test targets and changing linker settings in frameworks is not inherited by the main target (since there is no naive way to “merge” framework specific linker settings).
For custom library dependencies (capnp, kj, and libressl) we specify them via `LIBS` using `/path/to/libfoo.a` so that the root target will inherit these dependencies and using the absolute path ensures that we get the static (rather than dynamic) version.
Although we only use the headers in a single framework, we generally do not use per-framework include paths and furthermore, by having it as a “global” setting, it’s much easier to change how TextMate is built (w/o having to analyzer compiler flags like `-I`).
Not using any new C++17 (draft) features, but we may want to use std::variant as soon as it becomes available (as we currently use boost::variant), although std::variant will be a library feature.
When building with Xcode 8 beta (on my system at least), clang produced the following warning:
clang: warning: libstdc++ is deprecated; move to libc++ with a minimum deployment target of OS X 10.9
It appears clang will link with libstdc++ if present by default instead of libc++. This was verified using `otool -L bundles.dylib` which produce the following output prior to this change.
bundles.dylib:
@rpath/bundles.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/OakSystem.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/io.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/plist.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/regexp.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/scope.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/text.dylib (compatibility version 1.0.0, current version 1.0.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
With this change the output is now:
bundles.dylib:
@rpath/bundles.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/OakSystem.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/io.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/plist.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/regexp.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/scope.dylib (compatibility version 1.0.0, current version 1.0.1)
@rpath/text.dylib (compatibility version 1.0.0, current version 1.0.1)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1226.10.1)
With the boost thread helper we have to statically link to the boost libraries, which on most system is built against the latest version of the OS (instead of our current target 10.7). This doesn't seem to be an actual problem, but newer versions of clang issue warnings about it.
The new version of clang (Apple LLVM version 6.1.0) as shipped with Xcode 6.3, disabled TLS. According to http://clang.llvm.org/cxx_status.html, in order to support `thread_local`, the C++ runtime library from g++-4.8 or later is needed.
For now, we can use the boost `thread_specific_ptr`. This is probably a reasonable solution since 1) it should be portable with old and future versions of (Apple's) clang and 2) requires no additional dependencies.
This was just mirroring the last part of our version number so redundant and it wasn’t monotonically increasing as we switched from alpha.n → beta.1 (with n > 1), so it probably did more harm than good.
Set the `capnp_prefix` variable when calling ./configure.
E.g. build and install cap’n’proto in $HOME/build:
./configure --disable-shared --prefix="$HOME/build"
make -j6 check && make install
Then configure TextMate to find it there:
capnp_prefix="$HOME/build" ./configure
This option was removed in revision 191551 of clang (Sep 27, 2013).
Property synthesizing seems to now be default, it’s unclear to me what revision of clang made the behavior default, but since we require a fairly recent version for other things (like Cap’n’proto) I don’t think this change will cause a problem.
@executable_path is the originally-executed program, whereas @loader_path is the program that caused the load to occur (e.g. a Quick Look generator). @rpath can be changed at link time — a QL generator can specify a value that points to the enclosing app bundle’s Frameworks directory.
This is for oniguruma and ideally we would set this only for the oniguruma target, but then we need special precompiled headers for that target, so this is a practical way to achieve the goal (there are no other C sources in the build tree).
I never understood what this option was good for and now it gives a warning about being unused during compilation (even though it was set only during linking).
Basically libraries referenced indirectly will be setup as a requirement of the target and this option strips that. Doesn’t really matter, but enabling it rather than deleting the line (which was previously commented).
We now explicitly disable it for targets that hasn’t yet been upgraded to ARC. This way, it’s easier to get an overview of which targets hasn’t yet been upgraded and ensures new targets has ARC enabled.