Skip to content

Commit

Permalink
Update project for Xcode 12
Browse files Browse the repository at this point in the history
Also revised the documentation.
  • Loading branch information
d108 committed Oct 19, 2020
1 parent b1bf98d commit 729209c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 50 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ The MIT License

SetupXcodeDerivedDataRamDisk

Copyright (c) 2017 ikiApps LLC
Copyright (c) 2020 ikiApps LLC

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
40 changes: 21 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
# Get the Fastest Build Times in Xcode

Instead of having Xcode’s Derived Data be based in a spinning disk or solid-state drive, moving it to a RAM disk can make the performance of Xcode build operations *as fast as possible* and make it so that your Derived Data content is continually freshened.
Instead of having Xcode’s Derived Data based in a spinning disk or solid-state drive, move it to a RAM disk. Then, the performance of Xcode build operations run *as fast as possible.* A side benefit is the contents do not persist across reboots and, therefore, do not accumulate excessively.

I’ve crafted a script in Swift to perform the necessary configuration. I start the script in a launch agent that runs at startup so that my RAM disk is always available. Returning to a standard Xcode configuration simply requires ejecting the RAM disk.
I have crafted a script in Swift to perform the necessary configuration for you. It can automatically start using a launch agent at startup, so the RAM disk is always available. Returning to a standard Xcode configuration requires ejecting the RAM disk.

The reason this works is because the RAM disk is mounted to the default path for the DerivedData folder that Xcode uses. You can verify this path in Xcode under Locations in Preferences.
It works because the RAM disk mounts to the default path for the DerivedData folder that Xcode uses. You can verify this path in Xcode under Locations in Preferences. The RAM disk gets used by command-line builds and is thereby compatible with alternative IDEs such as AppCode.

## Installation

The install path is defined in the build settings under `INSTALL_DIR`. This is where the binary product will be copied every time the project is built. A default path of `$(HOME)/bin` has been set. This value is set by two settings in Xcode's build settings: `INSTALL_ROOT` and `INSTALL_PATH`.
Define the install path in the build settings under `INSTALL_DIR`. The binary product is copied to this location when building the project. A default path of `$(HOME)/bin` is set. Configuration of this value is by two settings in Xcode's build settings: `INSTALL_ROOT` and `INSTALL_PATH`.

**Therefore, the following steps should be completed to build and install the compiled version of the script.**
**Complete the following steps to build and install the compiled version of the script.**

* If needed, change the size of `RAMDISK_GB` in `main.swift`
* If needed, change the install path under Targets > SetupXcodeDerivedDataRamDisk > Build Settings > Installation Build Products Location + Installation Directory
* If needed, change the install path under Targets > SetupXcodeDerivedDataRamDisk > Build Settings > Installation Build Products Location + Installation Directory
* Build the project in Xcode

## Alternative installation

Copy `main.swift` to a local path of your choosing such as
Copy `main.swift` to a local path of your choosing, such as

~/bin/setupXcodeDerivedDataRAMDisk.swift

Make it executable using `chmod +x ~/bin/setupXcodeDerivedDataRAMDisk.swift`.
~/bin/setupXcodeDerivedDataRAMDisk.swift

Make it executable with

chmod +x ~/bin/setupXcodeDerivedDataRAMDisk.swift

## Run at startup

Create a file with the following content. **Edit it so that it fits your system. Replace ${INSERT_YOUR_USERNAME} with your username. Add `.swift` to the filename if using the text-based script.**
Create a file with the following content. **Edit it to fit your system. Replace ${INSERT_YOUR_USERNAME} with your username. Add `.swift` to the filename if using the text-based script.**

<?xml version=1.0 encoding=UTF-8?>
<!DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
Expand All @@ -46,14 +48,14 @@ Create a file with the following content. **Edit it so that it fits your system.
</dict>
</plist>

Give it a name like `com.ikiApps.setupXcodeDerivedDataRamDisk.plist` and copy it to
Give it a name, for example, `com.ikiApps.setupXcodeDerivedDataRamDisk.plist`, and copy it to

~/Library/LaunchAgents

User readable is the minimum permission for the property list. That corresponds to a permission value of 0400 for chmod.

~/Library/LaunchAgents

The minimum permission for this property list launch agent file is that it is readable by you. That corresponds to a permission value of 0400 in chmod terms.
Make sure Xcode is not running, and manually test starting the agent with the following command:

The agent can be started manually using
launchctl load com.ikiApps.setupXcodeDerivedDataRamDisk.plist

launchctl load com.ikiApps.setupXcodeDerivedDataRamDisk.plist

If everything went well, the script will now run every time you login. You can see the mounted RAM disk in the Finder when it is available. It will also be available in the list of mounts using the `mount` or `df` command.
If everything went well, the script should now run every time you log in. You can see the mounted RAM disk in the Finder when it is available. It will also be available in the list of mounts using the `mount` or `df` command.
12 changes: 9 additions & 3 deletions SetupXcodeDerivedDataRamDisk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = ikiApps;
TargetAttributes = {
65633CB31CA7AB9F0042FE05 = {
Expand All @@ -96,11 +96,11 @@
};
buildConfigurationList = 65633CAF1CA7AB9F0042FE05 /* Build configuration list for PBXProject "SetupXcodeDerivedDataRamDisk" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
mainGroup = 65633CAB1CA7AB9F0042FE05;
productRefGroup = 65633CB51CA7AB9F0042FE05 /* Products */;
Expand Down Expand Up @@ -128,6 +128,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand All @@ -147,6 +148,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -184,6 +186,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
Expand All @@ -203,6 +206,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -232,6 +236,7 @@
65633CBC1CA7AB9F0042FE05 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
DEPLOYMENT_LOCATION = YES;
DSTROOT = "$(HOME)";
INSTALL_PATH = /bin;
Expand All @@ -244,6 +249,7 @@
65633CBD1CA7AB9F0042FE05 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
DEPLOYMENT_LOCATION = YES;
DSTROOT = "$(HOME)";
INSTALL_PATH = /bin;
Expand Down
51 changes: 24 additions & 27 deletions SetupXcodeDerivedDataRamDisk/main.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/usr/bin/env xcrun swift

// SetupXcodeDerivedDataRamDisk 2.3.0
// SetupXcodeDerivedDataRamDisk 2.3.1
//
// Copyright (c) 2019 ikiApps LLC.
// Copyright (c) 2020 ikiApps LLC.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,40 +25,35 @@
import Foundation

/**
Create a Derived Data RAM disk for use by Xcode.
The regex matching is designed for English language systems.
Tested with macOS 10.14.3 (Mojave), Xcode 10.2 and Swift 5.0.
Create a Derived Data RAM disk for use by Xcode.
The regular expression matching is for English language systems.
This script got tested with macOS 10.15.7 (Catalina), Xcode 12.01, and Swift 5.3.

The disk is mounted into the default path for Xcode's Derived Data path and will
be used automatically by Xcode if the path is corresponds to the one set in
Xcode's preferences.
The disk is mounted into the default path for Xcode's Derived Data path and will be used
automatically by Xcode if it corresponds to the one set in Xcode's preferences.

The console app, built in Xcode, can be added as a startup agent inside
~/Library/LaunchAgents. The raw script itself can also be made executable like a
shell script.
The console app, built with Xcode, can be added as a startup agent inside `~/Library/LaunchAgents`.
The raw script itself can also be made executable like a shell script.

The path below refers to a bin directory contained in your home directory.
This folder needs to be created if it does not already exist.
The path below refers to a bin directory contained in your home directory.
Create this folder if it does not already exist.

The console app or script copied into that directory will need to have execute
(+x) permissions. The property list inside LaunchAgents only requires read (+r)
permissions to work. It is sufficient to simply copy the property list into the
LaunchAgents directory. The directory itself will have to be created if it does
not already exist.
The console app or script copied into that directory needs execute (+x) permissions. The property
list inside LaunchAgents only requires read (+r) permissions to work. It is sufficient to copy the
property list into the LaunchAgents directory. Create the directory if it does not already exist.

Here is the content of an example property list (plist) that will have the RAM
disk created at startup.
Here is the content of an example property list (plist) that will have the RAM disk created at startup.

** REMEMBER TO CHANGE THE USERNAME BELOW TO MATCH YOUR USERNAME. **
** REMEMBER TO CHANGE THE USERNAME BELOW TO MATCH YOUR USERNAME. **

filename: com.ikiapps.setupXcodeDerivedDataRamDisk.plist
Example filename: com.ikiApps.setupXcodeDerivedDataRamDisk.plist
-------------------------------------------------------------------
<?xml version=1.0 encoding=UTF-8?>
<!DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version=1.0>
<dict>
<key>Label</key>
<string>com.ikiapps.setupXcodeDerivedDataRamDisk.plist</string>
<string>com.ikiApps.setupXcodeDerivedDataRamDisk.plist</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/xcrun</string>
Expand All @@ -72,14 +67,15 @@ filename: com.ikiapps.setupXcodeDerivedDataRamDisk.plist
</plist>
-------------------------------------------------------------------

The launch agent can be tested with:
Manually test the launch agent with:

launchctl load ~/Library/LaunchAgents/com.ikiapps.setupXcodeDerivedDataRamDisk.plist
launchctl load ~/Library/LaunchAgents/com.ikiApps.setupXcodeDerivedDataRamDisk.plist

*/

/// File systems:
enum FileSystemType {
enum FileSystemType
{
case apfs
case hfsPlus
}
Expand All @@ -92,7 +88,8 @@ let encoding: String.Encoding = .utf8
let fileSystem = FileSystemType.apfs

/// Error cases:
enum RamDiskSetupError: Error {
enum RamDiskSetupError: Error
{
case taskFailed
}

Expand Down

0 comments on commit 729209c

Please sign in to comment.