Instantly share code, notes, and snippets.

@roop /makemake.pl
Last active Jun 19, 2017

Embed
What would you like to do?
Script to create a Makefile to build your Swift project
#!/usr/bin/perl -w
use strict;
# Makefile generator for quick compilation of Swift projects
# By: Roopesh Chander
# Thanks: Andy Matuschak
# Works only for swift-only projects.
# Usage:
# > perl makemake.pl
# > make
# More info: http://roopc.net/posts/2014/speeding-up-swift-builds/
my $APP_NAME = 'AppName'; # FIXME: Set project name here
my @SOURCES = (
'Path/To/File1.swift',
'Another/File2.swift',
# FIXME: Add swift files in your project here
# Escape spaces, if any:
'Somewhere\ else/Filename\ With\ Spaces.swift'
);
my $XCODE_DEV = "/Applications/Xcode.app/Contents/Developer";
my $SDK = "${XCODE_DEV}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.1.sdk";
my $XCTOOL_PATH = "${XCODE_DEV}/Toolchains/XcodeDefault.xctoolchain";
my $SWIFT = "${XCTOOL_PATH}/usr/bin/swift";
my $XCODE_DERIVED_DATA = "$ENV{HOME}/Library/Developer/Xcode/DerivedData";
my $OBJ = "${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/";
my $TARGET = "${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator/${APP_NAME}.app/${APP_NAME}";
my $common_compile = "-target x86_64-apple-ios8.0 -target-cpu core2 -sdk $SDK -I ${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -F ${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -g -module-cache-path ${XCODE_DERIVED_DATA}/ModuleCache -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/swift-overrides.hmap -Xcc -iquote -Xcc ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-generated-files.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-own-target-headers.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-all-target-headers.hmap -Xcc -iquote -Xcc ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-project-headers.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator/include -Xcc -I${XCODE_DEV}/Toolchains/XcodeDefault.xctoolchain/usr/include -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/DerivedSources/x86_64 -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/DerivedSources -Xcc -DDEBUG=1";
open (my $fh, ">", "Makefile")
or die "Cannot open Makefile for writing - $!\n";
print $fh <<END;
# Makefile for quick compilation of Swift projects
# Generated by $0
quick_compile: $TARGET
END
my @stubs = ();
foreach my $s (@SOURCES) {
my @p = split(/\//, $s);
my $f = $p[-1];
$f =~ s/\.swift$//;
my $other_sources = join(" ", grep { $_ ne $s } @SOURCES);
print $fh <<END;
$OBJ/${f}.o: $s
\t$SWIFT -frontend -c -primary-file $s $other_sources $common_compile -emit-module-doc-path $OBJ/${f}~partial.swiftdoc -Onone -module-name ${APP_NAME} -emit-module-path $OBJ/${f}~partial.swiftmodule -serialize-diagnostics-path $OBJ/${f}.dia -emit-dependencies-path $OBJ/${f}.d -o $OBJ/${f}.o
END
push @stubs, $f;
}
my $objs_str = join(" ", map { "$OBJ/${_}.o" } @stubs);
my $partmods_str = join(" ", map { "$OBJ/${_}~partial.swiftmodule" } @stubs);
my $common_merge = "-parse-as-library -target x86_64-apple-ios8.0 -target-cpu core2 -sdk $SDK -I ${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -F ${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -g -module-cache-path ${XCODE_DERIVED_DATA}/ModuleCache -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/swift-overrides.hmap -Xcc -iquote -Xcc ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-generated-files.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-own-target-headers.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-all-target-headers.hmap -Xcc -iquote -Xcc ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}-project-headers.hmap -Xcc -I${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator/include -Xcc -I${XCODE_DEV}/Toolchains/XcodeDefault.xctoolchain/usr/include -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/DerivedSources/x86_64 -Xcc -I${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/DerivedSources -Xcc -DDEBUG=1 -emit-module-doc-path ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/${APP_NAME}.swiftdoc -module-name ${APP_NAME} -emit-objc-header-path ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/${APP_NAME}-Swift.h";
print $fh <<END;
$OBJ/${APP_NAME}.swiftmodule: $objs_str
\t$SWIFT -frontend -emit-module $partmods_str $common_merge -o $OBJ/${APP_NAME}.swiftmodule
END
print $fh <<END;
$TARGET: $OBJ/${APP_NAME}.swiftmodule
\texport IPHONEOS_DEPLOYMENT_TARGET=8.0 && export PATH="${XCODE_DEV}/Platforms/iPhoneSimulator.platform/Developer/usr/bin:${XCODE_DEV}/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin" && ${XCTOOL_PATH}/usr/bin/clang -arch x86_64 -isysroot $SDK -L${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -F${XCODE_DERIVED_DATA}/Build/Products/Debug-iphonesimulator -filelist ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/${APP_NAME}.LinkFileList -Xlinker -rpath -Xlinker \@executable_path/Frameworks -Xlinker -objc_abi_version -Xlinker 2 -L${XCODE_DEV}/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator -Xlinker -add_ast_path -Xlinker ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/${APP_NAME}.swiftmodule -mios-simulator-version-min=8.0 -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/${APP_NAME}.app.xcent -Xlinker -dependency_info -Xlinker ${XCODE_DERIVED_DATA}/Build/Intermediates/${APP_NAME}.build/Debug-iphonesimulator/${APP_NAME}.build/Objects-normal/x86_64/${APP_NAME}_dependency_info.dat -o $TARGET
END
close $fh;
@NachoSoto

This comment has been minimized.

NachoSoto commented Dec 17, 2014

This is awesome, thank you so much!
The only issue I've found is that it assumes no spaces in filenames or paths. I tried adding quotes in each necessary place but my lack of Perl foo failed me :(

@roop

This comment has been minimized.

Owner

roop commented Dec 18, 2014

Thanks. Glad this is of help.

To handle spaces in the path or filename (which I hadn't thought of before), you can escape the spaces with a backslash, so the command line recognises that it's a single path. I've updated the script to illustrate this scenario.

@thewodros

This comment has been minimized.

thewodros commented Jan 28, 2015

Very nice, thanks for sharing!

I was wondering if this can be tweaked for a Swift/Objective-C mix project. Any pointer? :) Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment