This is required because copying an executable to the build directory now depends on its signature, but the signature’s date is always newer (or same) as the executable being copied, which leads to the target being considered out-of-date and thus rebuilt (copied again).
This may seem non-standard but since presence of a variable in our target file will drop a potential -D when, it does not make sense to have -D take precedence over what is in the target file.
Ideally we would have a section with “public” variables, but that will require making the format more complex, so for now, everything gets declared as a variable in the ninja build file, even though for now, we really just need to export APP_MIN_OS.
The signature step takes the bundle as input and therefore depends on this, but if the bundle does not already exist, ninja will (correctly) complain that there is no rule to create it.
For bundles the sequence is now the following:
- Copy/run depends on signature
- Signature depends on bundle
- Bundle depends on linked executable and all resources
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 compile all assets into one file that resides in the main app bundle so while we can have multiple asset catalogs (per Framework, etc.), individual assets should still be namespaced.
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.
This suppresses the below warning when compiling xibs with Xcode 7 or later.
warning: This file is set to build for a version older than the deployment target. Functionality may be limited. [9]
We should revisit this when we update our minimum deployment target to 10.8 or higher, as it may not be needed.
Running tests in parallel (which is the default)
results in spurious failures in the `scm` git tests,
probably due to an undiagnosed race condition.
This change lets tests run serially by default,
but provides a flag `-p` (or `--parallel`)
which enables running them in parallel again.
It also adds a variable `test_flags`
which is passed to each test run,
and which can be set by running
env test="-v" ./configure
The `gen_credits` scripts can spuriously fail
raising this error in the `user_by_email` method
NoMethodError: undefined method `[]' for nil:NilClass
when `YAML.load(response.body)` returns nil.
This change protects the build against these failures
by returning nil early.
This allowed framework headers to test whether they were build as part of the framework itself, or part of building something that depends on the framework.
Ideally though we should not need two different paths for those two cases, and we no longer have.
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.
The downside is that we no longer have our .o files depend on the compiler (so we need to do a clean build after upgrading the compiler) and if there is a space in the path to the compiler, it will fail.
The upside is that we can let CC/CXX be a command with arguments, e.g. ‘xcrun clang’.
Only values from the root target goes through this code, so it wasn’t causing a problem, as none of those keys had a multi-element array, but in ruby 2.0 embedding an array in a string seems to use inspect instead of to_s:
Ruby 1.8: "#{['foo']}" #=> foo
Ruby 2.0: "#{['foo']}" #=> ["foo"]