Merge pull request #378 from asarhaddon/test-macro-not-changing-function
[jackhill/mal.git] / swift / Makefile
CommitLineData
2539e6af
KR
1################################################################################
2#
3# Makefile for the Swift implementation of MAL.
4#
5# The MAL project consists of building up a dialect/subset of Clojure over a
6# series of steps. Each step implements a new feature or concept in an easily
7# understandable and approachable manner. Each step can be built on its own and
8# tested. Each step is built from a step-specific "step.swift" file and a set
9# of files common to all steps.
10#
11# The general approach in this file is to discover the set of "step" source
12# files (step0_repl.swift, etc.), and build corresponding executable files
13# (step0_repl, etc) from them and from the set of supporting Swift files.
14# Since the set of "step" files is discovered on-the-fly, the rules to make
15# those files are also generated on-the-fly using $(eval).
16#
17# The various "step0_repl.swift", etc., source files are actually generated
18# from a file called "templates/step.swift". Since each "step" file
19# incrementally builds towards the final, complete "step" file,
20# "templates/step.swift" is -- for the most part -- a copy of this final "step"
21# file with each line annotated with the step in which that line is introduced.
22# Through the use of a simple filter program, the "templates/step.swift" file
23# can then be processed to produce each intermediate "step" file. This Makefile
24# takes care of performing that processing any time "templates/step.swift"
25# changes.
26#
27# MAKE TARGETS:
28#
29# all:
30# Make all step targets, (re)generating source files if needed.
31# alls:
32# (Re)generate source files, if needed.
33# step0_repl, step1_read_print, etc.:
34# Make the corresponding step target.
35# s0...sN:
36# Shortcuts for the previous targets.
37# step0_repl.swift, step1_read_print.swift, etc.:
38# (Re)generate source files for the corresponding step target, if
39# needed.
40# ss0...ssN:
41# Shortcuts for the previous targets.
42# clean:
43# Delete all built executables. Generated source files are *not*
44# deleted.
45# dump:
46# Print some Make variables for debugging.
47#
48# TODO:
49# * Compile each .swift file into an intermediate .o file and link the .o
50# files, rather than performing a complete build of all files any time
51# any one of them is out-of-date. Here are the commands generated when
52# using `swiftc -v`:
53#
54# /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift \
55# -frontend \
56# -c \
57# -primary-file stepA_mal.swift \
58# ./core.swift \
59# ./env.swift \
60# ./main.swift \
61# ./printer.swift \
62# ./reader.swift \
63# ./readline.swift \
64# ./types.swift \
65# -target x86_64-apple-darwin14.1.0 \
66# -target-cpu core2 \
67# -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk \
68# -import-objc-header ./bridging-header.h \
69# -color-diagnostics \
70# -Onone \
71# -ledit \
72# -module-name stepA_mal \
73# -o /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/stepA_mal-e0a836.o
74# ... Similar for each source file...
75# /usr/bin/ld \
76# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/stepA_mal-e0a836.o \
77# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/core-28b620.o \
78# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/env-5d8422.o \
79# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/main-e79633.o \
80# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/printer-cdd3e5.o \
81# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/reader-bb188a.o \
82# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/readline-53df55.o \
83# /var/folders/dj/p3tx6v852sl88g79qvhhc2ch0000gp/T/types-7cb250.o \
84# -L /usr/lib \
85# -ledit \
86# -syslibroot \
87# /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk \
88# -lSystem \
89# -arch x86_64 \
90# -L /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx \
91# -rpath /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx \
92# -macosx_version_min 10.10.0 \
93# -no_objc_category_merging \
94# -o stepA_mal
95#
96# * Consider adding a clean-dist (or similar) that deletes the generated
97# "step" source files.
98#
99################################################################################
100
101#
102# Discover the set of "step" source files (those having the form
103# "step<#>_foo.swift")
104#
105SRCS := $(wildcard ./step*.swift)
106
107#
108# From the set of "step" source files, generate the set of executable files
109# (those having the form "step<#>_foo")
110#
111EXES := $(patsubst %.swift,%,$(SRCS))
112
425305df
KR
113#
114# Also generate references to any debug-symbol directories we may make when -g
115# is specified.
116#
117DSYMS := $(patsubst %.swift,%.dSYM,$(SRCS))
118
2539e6af
KR
119#
120# Given a name like "./step<#>_foo", return <#>.
121#
122# (Is there a better way to do this? $(patsubst) seems to be the most
123# appropriate built-in command, but it doesn't seem powerful enough.)
124#
125# (I've included a `sed` version in case relying on bash is contraindicated.)
126#
ea25808e
JM
127get_step_number = $(shell echo $(1) | sed -e "s/.*step\(.\).*/\1/")
128#get_step_number = $(shell [[ $(1) =~ step(.)_.* ]] ; echo $${BASH_REMATCH[1]})
2539e6af
KR
129
130#
131# Working from the list of discovered "step<#>_foo.swift" files, generate the
132# list of step numbers.
133#
134get_all_step_numbers = $(foreach SRC,$(SRCS),$(call get_step_number,$(SRC)))
135
136#
137# Generate the dependencies for the "all" target. This list has the form
138# "s0 s1 ... sN" for all N returned by get_all_step_numbers. That is:
139#
140# all: s0 s1 ... sN
141#
142# Also create an "alls" target that just regenerates all the "step" files from
143# the corresponding template file.
144#
145$(eval all: $(patsubst %,s%,$(call get_all_step_numbers)))
146$(eval alls: $(patsubst %,ss%,$(call get_all_step_numbers)))
147
148#
149# Generate the dependencies for the ".PHONY" target. That is:
150#
151# .PHONY: all clean dump s0 s1 ... sN
152#
153$(eval .PHONY: all clean dump $(patsubst %,s%,$(call get_all_step_numbers)))
154
155#
156# Define the "EZ" targets, where "s0" builds "step0_repl", "s1" builds
157# "step1_read_print", etc. That is:
158#
159# s0: step0_repl
160# s1: step1_read_print
161# ...
162# sN: stepN_foo
163#
164# Also create corresponding targets that rebuild the sources files:
165#
166# ss0: step0_repl.swift
167# ss1: step1_read_print.swift
168# ...
169# ssN: stepN_foo.swift
170#
171$(foreach EXE,$(EXES),$(eval s$(call get_step_number,$(EXE)): $(EXE)))
172$(foreach SRC,$(SRCS),$(eval ss$(call get_step_number,$(SRC)): $(SRC)))
173
174#
175# Various helpful variables.
176#
425305df 177DEV_DIR := $(firstword $(wildcard /Applications/Xcode-beta.app /Applications/Xcode.app))
ea25808e
JM
178SWIFT := $(shell DEVELOPER_DIR="$(DEV_DIR)" xcrun --find swiftc 2>/dev/null)
179SDKROOT := $(shell DEVELOPER_DIR="$(DEV_DIR)" xcrun --show-sdk-path 2>/dev/null)
2539e6af
KR
180STEP_TEMPLATE := ./templates/step.swift
181FILTER := ./templates/filter_steps.sh
182UTIL_SRC := $(filter-out $(STEP_TEMPLATE) $(SRCS),$(wildcard ./*.swift))
425305df
KR
183ifndef TYPES
184TYPES := CLASS
185endif
186ifeq ($(TYPES), ENUM)
187UTIL_SRC := $(filter-out ./types_class.swift,$(UTIL_SRC))
188else
189UTIL_SRC := $(filter-out ./types_enum.swift,$(UTIL_SRC))
190endif
191OPT := -Ounchecked -whole-module-optimization
2539e6af
KR
192DEBUG := #-g
193EXTRA := #-v
194COMMON := $(UTIL_SRC) $(OPT) $(DEBUG) $(EXTRA) -import-objc-header ./bridging-header.h -L /usr/lib -ledit -sdk $(SDKROOT)
195
196#
197# Build the executable from the input sources consisting of the appropriate
198# "step" file and the supporting files in $(UTIL_SRC).
199#
425305df 200$(EXES) : % : %.swift $(UTIL_SRC) ./Makefile
2539e6af
KR
201 @echo "Making : $@"
202 @$(SWIFT) $< $(COMMON) -o $@
203
204#
205# Build the "step" source file ("step<#>_foo.swift") from the step template
206# file that combines all the steps in one file.
207#
208$(SRCS) : % : $(STEP_TEMPLATE) ./Makefile
209 @echo "Generating: $@"
210 @$(FILTER) $(call get_step_number,$@) $< $@
211
212#
425305df 213# Delete all of the build output (other than generated "step" source files)
2539e6af
KR
214#
215clean:
425305df 216 @rm -rf $(EXES) $(DSYMS)
2539e6af
KR
217
218#
219# Display some variables for debugging.
220#
221dump:
222 @echo " SRCS = $(SRCS)"
223 @echo " EXES = $(EXES)"
425305df 224 @echo " DSYMS = $(DSYMS)"
2539e6af 225 @echo " UTIL = $(UTIL_SRC)"
425305df 226 @echo " SWIFT = $(SWIFT)"
2539e6af
KR
227 @echo "SDKROOT = $(SDKROOT)"
228 @echo " STEPS = $(call get_all_step_numbers)"