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 ‘+=’.
TextMate
Download
You can download TextMate from here.
Feedback
You can use the TextMate mailing list or #textmate IRC channel on freenode.net for questions, comments, and bug reports.
You can also contact MacroMates.
Before you submit a bug report please read the writing bug reports instructions.
Screenshot
Building
Bootstrap
To bootstrap the build you need to run ./configure (in the root of the source tree). You can set a few (environment) variables read by this script that change the generated build file:
builddir— location of built files. Defaults to~/build/TextMate.identity— for Apple’scodesign. Defaults to ad-hoc signing, which does not use an identity at all.boostdir— location of boost includes. By default it will search various locations including MacPorts and Homebrew.sparsedir— location of sparsehash includes. By default it will search various locations including MacPorts and Homebrew.CCandCXX— C and C++ compiler.
In the simplest case (assuming Homebrew is installed) you would run:
brew install ragel boost multimarkdown hg ninja capnp google-sparsehash libressl
git clone --recursive https://github.com/textmate/textmate.git
cd textmate
./configure && ninja
If you're using MacPorts then instead run this line to install dependencies:
sudo port install ninja ragel boost multimarkdown mercurial sparsehash libressl
Unless you’re using Homebrew then Cap’n Proto must be manually installed. Feel free to submit a PR to update configure.
If port fails with a build error then likely you need to agree (system-wide) to Apple’s Xcode license:
sudo xcodebuild -license
Prerequisites
Building TextMate has the following dependencies:
- ninja — build system similar to
make - ragel — state machine compiler
- boost — portable C++ source libraries
- sparsehash — A cache friendly hash_map
- multimarkdown — marked-up plain text compiler
- mercurial — distributed SCM system
- Cap’n Proto — serialization library
- LibreSSL - OpenBSD fork of OpenSSL
In practice hg (mercurial) is only required for the SCM library’s tests so you can skip this dependency if you don’t mind a failing test.
If you want to avoid the libressl linker warnings about being built for different deployment target then run brew edit libressl and make the following change:
- system "./configure", *args
+ system "env", "LDFLAGS=-mmacosx-version-min=10.8", "CFLAGS=-mmacosx-version-min=10.8", "./configure", *args
Afterward you must rebuild using: brew reinstall --build-from-source libressl
Building from within TextMate
You should install the Ninja bundle which can be installed via Preferences → Bundles.
After this you can press ⌘B to build from within TextMate. In case you haven't already you also need to set up the PATH variable either in Preferences → Variables or ~/.tm_properties so it can find ninja and related tools; an example could be $PATH:/opt/local/bin.
The default target is TextMate/run. This will relaunch TextMate but when called from within TextMate, a dialog will appear before the current instance is killed. As there is full session restore, it is safe to relaunch even with unsaved changes.
If the current file is a test file then the target to build is changed to build the library to which the test belongs (this is done by setting TM_NINJA_TARGET in the .tm_properties file found in the root of the source tree).
Similarly, if the current file belongs to an application target (other than TextMate.app) then TM_NINJA_TARGET is set to build and run this application.
Build Targets
The build system classifies a target either as a library or an application. The latter can either be a bundled or non-bundled application. E.g. mate is non-bundled (just a mate executable) where TextMate.app is a bundled application.
For each output there are a few symbolic targets you can build. While the examples below refer to a specific library or application, they exist for all targets of same type.
For the io library:
ninja io # Build the io library and run tests.
ninja io/clean # Remove the build folder for the io library.
ninja io/headers # Copy exported headers to $builddir/include.
For the mate (non-bundled) application:
ninja mate # Build the mate executable.
ninja mate/run # Build and run the mate executable.
ninja mate/clean # Remove the build folder for the mate executable.
For the TextMate.app application:
ninja TextMate # Build and sign TextMate.app.
ninja TextMate/run # Build, sign, and run TextMate.app.
ninja TextMate/clean # Remove the build folder for TextMate.app.
ninja TextMate/dsym # Create a tarball with extracted dSYM files.
ninja TextMate/tbz # Create a tarball of TextMate.app. Also produce the dsym tarball.
ninja TextMate/deploy # Push a nightly build. Fails without proper credentials :)
Note that ninja TextMate/clean only cleans the TextMate build folder ($builddir/Applications/TextMate), but all libraries and applications it depends on are not cleaned.
To clean everything run:
ninja -t clean
Legal
The source for TextMate is released under the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
TextMate is a trademark of Allan Odgaard.
