aboutsummaryrefslogtreecommitdiff
path: root/makefile
diff options
context:
space:
mode:
Diffstat (limited to 'makefile')
-rw-r--r--makefile236
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
3BIN_NAME := moonc
4# Compiler used
5CXX ?= g++
6# Extension of source files used in the project
7SRC_EXT = cpp
8# Path to the source directory, relative to the makefile
9SRC_PATH = ./src
10# Space-separated pkg-config libraries used by this project
11LIBS =
12# General compiler flags
13COMPILE_FLAGS = -std=c++17 -Wall -Wextra -g
14# Additional release-specific flags
15RCOMPILE_FLAGS = -D NDEBUG -O3
16# Additional debug-specific flags
17DCOMPILE_FLAGS = -D DEBUG
18# Add additional include paths
19INCLUDES = -I $(SRC_PATH)
20# General linker settings
21LINK_FLAGS =
22# Additional release-specific linker settings
23RLINK_FLAGS =
24# Additional debug-specific linker settings
25DLINK_FLAGS =
26# Destination directory, like a jail or mounted system
27DESTDIR = /
28# Install path (bin/ is appended automatically)
29INSTALL_PREFIX = usr/local
30# Test
31TEST_INPUT = ./spec/inputs
32TEST_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'
42UNAME_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
47print-%: ; @echo $*=$($*)
48
49# Shell used in this makefile
50# bash is used for 'echo -en'
51SHELL = /bin/bash
52# Clear built-in rules
53.SUFFIXES:
54# Programs for installation
55INSTALL = install
56INSTALL_PROGRAM = $(INSTALL)
57INSTALL_DATA = $(INSTALL) -m 644
58
59# Append pkg-config specific libraries if need be
60ifneq ($(LIBS),)
61 COMPILE_FLAGS += $(shell pkg-config --cflags $(LIBS))
62 LINK_FLAGS += $(shell pkg-config --libs $(LIBS))
63endif
64
65# Verbose option, to output compile and link commands
66export V := false
67export CMD_PREFIX := @
68ifeq ($(V),true)
69 CMD_PREFIX :=
70endif
71
72# Combine compiler and linker flags
73release: export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(RCOMPILE_FLAGS)
74release: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(RLINK_FLAGS)
75debug: export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(DCOMPILE_FLAGS)
76debug: export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(DLINK_FLAGS)
77
78# Build and output paths
79release: export BUILD_PATH := build/release
80release: export BIN_PATH := bin/release
81debug: export BUILD_PATH := build/debug
82debug: export BIN_PATH := bin/debug
83install: export BIN_PATH := bin/release
84
85# Find all source files in the source directory, sorted by most
86# recently modified
87ifeq ($(UNAME_S),Darwin)
88 SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' | sort -k 1nr | cut -f2-)
89else
90 SOURCES = $(shell find $(SRC_PATH) -name '*.$(SRC_EXT)' -printf '%T@\t%p\n' \
91 | sort -k 1nr | cut -f2-)
92endif
93
94# fallback in case the above fails
95rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) \
96 $(filter $(subst *,%,$2), $d))
97ifeq ($(SOURCES),)
98 SOURCES := $(call rwildcard, $(SRC_PATH), *.$(SRC_EXT))
99endif
100
101# Set the object file names, with the source directory stripped
102# from the path, and the build path prepended in its place
103OBJECTS = $(SOURCES:$(SRC_PATH)/%.$(SRC_EXT)=$(BUILD_PATH)/%.o)
104# Set the dependency files that will be used to add header dependencies
105DEPS = $(OBJECTS:.o=.d)
106
107# Macros for timing compilation
108ifeq ($(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
116else
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'`
123endif
124
125# Version macros
126# Comment/remove this section to remove versioning
127USE_VERSION := false
128# If this isn't a git repo or the repo has no tags, git describe will return non-zero
129ifeq ($(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)\"
146endif
147
148# Standard, non-optimized release build
149.PHONY: release
150release: dirs
151ifeq ($(USE_VERSION), true)
152 @echo "Beginning release build v$(VERSION_STRING)"
153else
154 @echo "Beginning release build"
155endif
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
163debug: dirs
164ifeq ($(USE_VERSION), true)
165 @echo "Beginning debug build v$(VERSION_STRING)"
166else
167 @echo "Beginning debug build"
168endif
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
176dirs:
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
184install:
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
190uninstall:
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
196clean:
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
207test: 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
212all: $(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)