diff options
Diffstat (limited to 'makefile')
-rw-r--r-- | makefile | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/makefile b/makefile new file mode 100644 index 0000000..5042b08 --- /dev/null +++ b/makefile | |||
@@ -0,0 +1,236 @@ | |||
1 | #### PROJECT SETTINGS #### | ||
2 | # The name of the executable to be created | ||
3 | BIN_NAME := moonc | ||
4 | # Compiler used | ||
5 | CXX ?= g++ | ||
6 | # Extension of source files used in the project | ||
7 | SRC_EXT = cpp | ||
8 | # Path to the source directory, relative to the makefile | ||
9 | SRC_PATH = ./src | ||
10 | # Space-separated pkg-config libraries used by this project | ||
11 | LIBS = | ||
12 | # General compiler flags | ||
13 | COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g | ||
14 | # Additional release-specific flags | ||
15 | RCOMPILE_FLAGS = -D NDEBUG -O3 | ||
16 | # Additional debug-specific flags | ||
17 | DCOMPILE_FLAGS = -D DEBUG | ||
18 | # Add additional include paths | ||
19 | INCLUDES = -I $(SRC_PATH) | ||
20 | # General linker settings | ||
21 | LINK_FLAGS = | ||
22 | # Additional release-specific linker settings | ||
23 | RLINK_FLAGS = | ||
24 | # Additional debug-specific linker settings | ||
25 | DLINK_FLAGS = | ||
26 | # Destination directory, like a jail or mounted system | ||
27 | DESTDIR = / | ||
28 | # Install path (bin/ is appended automatically) | ||
29 | INSTALL_PREFIX = usr/local | ||
30 | # Test | ||
31 | TEST_INPUT = ./spec/inputs | ||
32 | TEST_OUTPUT = ./spec/outputs | ||
33 | #### END PROJECT SETTINGS #### | ||
34 | |||
35 | # Optionally you may move the section above to a separate config.mk file, and | ||
36 | # uncomment the line below | ||
37 | # include config.mk | ||
38 | |||
39 | # Generally should not need to edit below this line | ||
40 | |||
41 | # Obtains the OS type, either 'Darwin' (OS X) or 'Linux' | ||
42 | UNAME_S:=$(shell uname -s) | ||
43 | |||
44 | # Function used to check variables. Use on the command line: | ||
45 | # make print-VARNAME | ||
46 | # Useful for debugging and adding features | ||
47 | print-%: ; @echo $*=$($*) | ||
48 | |||
49 | # Shell used in this makefile | ||
50 | # bash is used for 'echo -en' | ||
51 | SHELL = /bin/bash | ||
52 | # Clear built-in rules | ||
53 | .SUFFIXES: | ||
54 | # Programs for installation | ||
55 | INSTALL = install | ||
56 | INSTALL_PROGRAM = $(INSTALL) | ||
57 | INSTALL_DATA = $(INSTALL) -m 644 | ||
58 | |||
59 | # Append pkg-config specific libraries if need be | ||
60 | ifneq ($(LIBS),) | ||
61 | COMPILE_FLAGS += $(shell pkg-config --cflags $(LIBS)) | ||
62 | LINK_FLAGS += $(shell pkg-config --libs $(LIBS)) | ||
63 | endif | ||
64 | |||
65 | # Verbose option, to output compile and link commands | ||
66 | export V := false | ||
67 | export CMD_PREFIX := @ | ||
68 | ifeq ($(V),true) | ||
69 | CMD_PREFIX := | ||
70 | endif | ||
71 | |||
72 | # Combine compiler and linker flags | ||
73 | release: export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(RCOMPILE_FLAGS) | ||
74 | release: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(RLINK_FLAGS) | ||
75 | debug: export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(DCOMPILE_FLAGS) | ||
76 | debug: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(DLINK_FLAGS) | ||
77 | |||
78 | # Build and output paths | ||
79 | release: export BUILD_PATH := build/release | ||
80 | release: export BIN_PATH := bin/release | ||
81 | debug: export BUILD_PATH := build/debug | ||
82 | debug: export BIN_PATH := bin/debug | ||
83 | install: export BIN_PATH := bin/release | ||
84 | |||
85 | # Find all source files in the source directory, sorted by most | ||
86 | # recently modified | ||
87 | ifeq ($(UNAME_S),Darwin) | ||
88 | SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' | sort -k 1nr | cut -f2-) | ||
89 | else | ||
90 | SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' -printf '%T@\t%p\n' \ | ||
91 | | sort -k 1nr | cut -f2-) | ||
92 | endif | ||
93 | |||
94 | # fallback in case the above fails | ||
95 | rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) \ | ||
96 | $(filter $(subst *,%,$2), $d)) | ||
97 | ifeq ($(SOURCES),) | ||
98 | SOURCES := $(call rwildcard, $(SRC_PATH), *.$(SRC_EXT)) | ||
99 | endif | ||
100 | |||
101 | # Set the object file names, with the source directory stripped | ||
102 | # from the path, and the build path prepended in its place | ||
103 | OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o) | ||
104 | # Set the dependency files that will be used to add header dependencies | ||
105 | DEPS = $(OBJECTS:.o=.d) | ||
106 | |||
107 | # Macros for timing compilation | ||
108 | ifeq ($(UNAME_S),Darwin) | ||
109 | CUR_TIME = awk 'BEGIN{srand(); print srand()}' | ||
110 | TIME_FILE = $(dir $@).$(notdir $@)_time | ||
111 | START_TIME = $(CUR_TIME) > $(TIME_FILE) | ||
112 | END_TIME = read st < $(TIME_FILE) ; \ | ||
113 | $(RM) $(TIME_FILE) ; \ | ||
114 | st=$$((`$(CUR_TIME)` - $$st)) ; \ | ||
115 | echo $$st | ||
116 | else | ||
117 | TIME_FILE = $(dir $@).$(notdir $@)_time | ||
118 | START_TIME = date '+%s' > $(TIME_FILE) | ||
119 | END_TIME = read st < $(TIME_FILE) ; \ | ||
120 | $(RM) $(TIME_FILE) ; \ | ||
121 | st=$$((`date '+%s'` - $$st - 86400)) ; \ | ||
122 | echo `date -u -d @$$st '+%H:%M:%S'` | ||
123 | endif | ||
124 | |||
125 | # Version macros | ||
126 | # Comment/remove this section to remove versioning | ||
127 | USE_VERSION := false | ||
128 | # If this isn't a git repo or the repo has no tags, git describe will return non-zero | ||
129 | ifeq ($(shell git describe > /dev/null 2>&1 ; echo $$?), 0) | ||
130 | USE_VERSION := true | ||
131 | VERSION := $(shell git describe --tags --long --dirty --always | \ | ||
132 | sed 's/v\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)-\?.*-\([0-9]*\)-\(.*\)/\1 \2 \3 \4 \5/g') | ||
133 | VERSION_MAJOR := $(word 1, $(VERSION)) | ||
134 | VERSION_MINOR := $(word 2, $(VERSION)) | ||
135 | VERSION_PATCH := $(word 3, $(VERSION)) | ||
136 | VERSION_REVISION := $(word 4, $(VERSION)) | ||
137 | VERSION_HASH := $(word 5, $(VERSION)) | ||
138 | VERSION_STRING := \ | ||
139 | "$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH).$(VERSION_REVISION)-$(VERSION_HASH)" | ||
140 | override CXXFLAGS := $(CXXFLAGS) \ | ||
141 | -D VERSION_MAJOR=$(VERSION_MAJOR) \ | ||
142 | -D VERSION_MINOR=$(VERSION_MINOR) \ | ||
143 | -D VERSION_PATCH=$(VERSION_PATCH) \ | ||
144 | -D VERSION_REVISION=$(VERSION_REVISION) \ | ||
145 | -D VERSION_HASH=\"$(VERSION_HASH)\" | ||
146 | endif | ||
147 | |||
148 | # Standard, non-optimized release build | ||
149 | .PHONY: release | ||
150 | release: dirs | ||
151 | ifeq ($(USE_VERSION), true) | ||
152 | @echo "Beginning release build v$(VERSION_STRING)" | ||
153 | else | ||
154 | @echo "Beginning release build" | ||
155 | endif | ||
156 | @$(START_TIME) | ||
157 | @$(MAKE) all --no-print-directory | ||
158 | @echo -n "Total build time: " | ||
159 | @$(END_TIME) | ||
160 | |||
161 | # Debug build for gdb debugging | ||
162 | .PHONY: debug | ||
163 | debug: dirs | ||
164 | ifeq ($(USE_VERSION), true) | ||
165 | @echo "Beginning debug build v$(VERSION_STRING)" | ||
166 | else | ||
167 | @echo "Beginning debug build" | ||
168 | endif | ||
169 | @$(START_TIME) | ||
170 | @$(MAKE) all --no-print-directory | ||
171 | @echo -n "Total build time: " | ||
172 | @$(END_TIME) | ||
173 | |||
174 | # Create the directories used in the build | ||
175 | .PHONY: dirs | ||
176 | dirs: | ||
177 | @echo "Creating directories" | ||
178 | @mkdir -p $(dir $(OBJECTS)) | ||
179 | @mkdir -p $(BIN_PATH) | ||
180 | @mkdir -p $(TEST_OUTPUT) | ||
181 | |||
182 | # Installs to the set path | ||
183 | .PHONY: install | ||
184 | install: | ||
185 | @echo "Installing to $(DESTDIR)$(INSTALL_PREFIX)/bin" | ||
186 | @$(INSTALL_PROGRAM) $(BIN_PATH)/$(BIN_NAME) $(DESTDIR)$(INSTALL_PREFIX)/bin | ||
187 | |||
188 | # Uninstalls the program | ||
189 | .PHONY: uninstall | ||
190 | uninstall: | ||
191 | @echo "Removing $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME)" | ||
192 | @$(RM) $(DESTDIR)$(INSTALL_PREFIX)/bin/$(BIN_NAME) | ||
193 | |||
194 | # Removes all build files | ||
195 | .PHONY: clean | ||
196 | clean: | ||
197 | @echo "Deleting $(BIN_NAME) symlink" | ||
198 | @$(RM) $(BIN_NAME) | ||
199 | @echo "Deleting directories" | ||
200 | @$(RM) -r build | ||
201 | @$(RM) -r bin | ||
202 | @echo "Deleting generated Lua codes" | ||
203 | @$(RM) -r $(TEST_OUTPUT) | ||
204 | |||
205 | # Test Moonscript compiler | ||
206 | .PHONY: test | ||
207 | test: release | ||
208 | @echo "Compiling Moonscript codes..." | ||
209 | @./$(BIN_NAME) $(TEST_INPUT)/*.moon -a -s -t $(TEST_OUTPUT) | ||
210 | |||
211 | # Main rule, checks the executable and symlinks to the output | ||
212 | all: $(BIN_PATH)/$(BIN_NAME) | ||
213 | @echo "Making symlink: $(BIN_NAME) -> $<" | ||
214 | @$(RM) $(BIN_NAME) | ||
215 | @ln -s $(BIN_PATH)/$(BIN_NAME) $(BIN_NAME) | ||
216 | |||
217 | # Link the executable | ||
218 | $(BIN_PATH)/$(BIN_NAME): $(OBJECTS) | ||
219 | @echo "Linking: $@" | ||
220 | @$(START_TIME) | ||
221 | $(CMD_PREFIX)$(CXX) $(OBJECTS) $(LDFLAGS) -o $@ | ||
222 | @echo -en "\t Link time: " | ||
223 | @$(END_TIME) | ||
224 | |||
225 | # Add dependency files, if they exist | ||
226 | -include $(DEPS) | ||
227 | |||
228 | # Source file rules | ||
229 | # After the first compilation they will be joined with the rules from the | ||
230 | # dependency files to provide header dependencies | ||
231 | $(BUILD_PATH)/%.o: $(SRC_PATH)/%.$(SRC_EXT) | ||
232 | @echo "Compiling: $< -> $@" | ||
233 | @$(START_TIME) | ||
234 | $(CMD_PREFIX)$(CXX) $(CXXFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@ | ||
235 | @echo -en "\t Compile time: " | ||
236 | @$(END_TIME) | ||