|
1 |
| -.PHONY: help clean spec mystspec |
| 1 | +# Because env `SHELL` might be |
| 2 | +# some extremely weird shell |
| 3 | +SHELL = bash |
2 | 4 |
|
3 |
| -spec: ## Runs all specs |
4 |
| - crystal spec |
5 |
| - crystal run src/myst_cli.cr -- spec/myst/spec.mt |
| 5 | +# Parse makefiles named *.mk in the dir `local` |
| 6 | +# for local extra makefile targets if wanted. |
| 7 | +# It is smart to set MYSTBUILD to your myst dev-build there |
| 8 | +-include local/*.mk |
6 | 9 |
|
7 |
| -myst-spec: ## Runs just the in-language specs |
8 |
| - crystal run src/myst_cli.cr -- spec/myst/spec.mt |
9 |
| - |
10 |
| -build: ## Builds myst into an executable |
11 |
| - shards build |
| 10 | +# https://www.gnu.org/software/make/manual/html_node/One-Shell.html |
| 11 | +.ONESHELL: |
12 | 12 |
|
13 |
| -check: ## Runs all crystal specs |
14 |
| - crystal spec/ |
| 13 | +# The docs says i should do this |
| 14 | +.SUFFIXES: .cr .mt |
15 | 15 |
|
16 |
| -clean: ## Cleans (deletes) docs and executables |
17 |
| - rm -rf docs |
18 |
| - rm bin/* |
| 16 | +MYST_CLI = src/myst_cli.cr |
19 | 17 |
|
20 |
| -# https://gist.github.com/prwhite/8168133 "Help target" |
21 |
| -help: ## Show this help. |
22 |
| - @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' |
| 18 | +MYST_INTERPRETER_SPEC = spec/all_spec.cr |
| 19 | +MYST_IN_LANG_SPEC = spec/myst/spec.mt |
| 20 | + |
| 21 | +SOURCE_FILES := $(shell find src -type f -name '*.cr') |
| 22 | +SPEC_FILES := $(shell find spec -type f -name '*.cr' -o -name '*.mt') |
| 23 | +STDLIB_FILES := $(shell find stdlib -type f -name '*.mt') |
| 24 | +ALL_FILES := $(SPEC_FILES) $(STDLIB_FILES) $(SOURCE_FILES) |
| 25 | + |
| 26 | +INSTALL_LOCATION ?= /usr/local/bin/myst |
| 27 | +MYSTBUILD ?= myst |
| 28 | + |
| 29 | +O ?= bin |
| 30 | + |
| 31 | +verbose ?= true |
| 32 | + |
| 33 | +# If another default is intentionally wished for, |
| 34 | +# set it in local/*.mk, like this: |
| 35 | +# .DEFAULT_GOAL = goal |
| 36 | +# |
| 37 | +.DEFAULT_GOAL ?= spec |
| 38 | + |
| 39 | +verbose_log = $(if $(subst false,,$(verbose)), $(info $(1))) |
| 40 | + |
| 41 | +.PHONY: spec |
| 42 | +spec: $(O)/myst $(O)/spec ## Runs all specs |
| 43 | + @$(call verbose_log,Running interpreter spec) |
| 44 | + $(O)/spec |
| 45 | + @$(call verbose_log,Running in-language spec) |
| 46 | + $(O)/myst $(MYST_IN_LANG_SPEC) |
| 47 | + |
| 48 | +myst-spec: $(O)/myst ## Runs just the in-language specs |
| 49 | + $(O)/myst $(MYST_IN_LANG_SPEC) |
| 50 | + |
| 51 | +.PHONY: install |
| 52 | +install: $(INSTALL_LOCATION) ## Install myst to INSTALL_LOCATION |
| 53 | + |
| 54 | +.PHONY: build |
| 55 | +build: $(O)/myst ## Builds myst into an executable |
| 56 | + |
| 57 | +.PHONY: myst-spec_with_build |
| 58 | +myst-spec_with_build: ## Runs the in-language specs with MYSTBUILD |
| 59 | + $(MYSTBUILD) $(MYST_IN_LANG_SPEC) |
| 60 | + |
| 61 | +$(O)/myst: $(SOURCE_FILES) |
| 62 | + @$(call verbose_log,Building myst...) |
| 63 | + @mkdir -p $(O) |
| 64 | + crystal build -o $(O)/myst $(MYST_CLI) |
| 65 | + |
| 66 | +$(O)/spec: $(ALL_FILES) |
| 67 | + @$(call verbose_log,Building specs...) |
| 68 | + @mkdir -p $(O) |
| 69 | + crystal build -o $(O)/spec $(MYST_INTERPRETER_SPEC) |
| 70 | + |
| 71 | +$(INSTALL_LOCATION): $(SOURCE_FILES) |
| 72 | + @mkdir -p $(dir $(INSTALL_LOCATION)) |
| 73 | + sudo crystal build --release -o $(INSTALL_LOCATION) $(MYST_CLI) |
| 74 | + |
| 75 | +.PHONY: clean |
| 76 | +clean: ## Cleans (deletes) docs and executables |
| 77 | +ifdef O |
| 78 | + @[ -f $(O)/myst ] && rm $(O)/myst |
| 79 | + @[ -f $(O)/spec ] && rm $(O)/spec |
| 80 | +endif |
| 81 | + @rm -rf docs |
| 82 | + |
| 83 | +# Thanks https://stackoverflow.com/questions/4219255/how-do-you-get-the-list-of-targets-in-a-makefile/26339924#26339924 |
| 84 | +define TARGET_LIST = |
| 85 | +$(shell \ |
| 86 | + $(MAKE) -pRrq -f $(MAKEFILE_LIST) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' |\ |
| 87 | + sort |\ |
| 88 | + egrep -v -e '^[^[a-zA-Z0-9]]' -e '^$@$$' |\ |
| 89 | + xargs ) |
| 90 | +endef |
| 91 | + |
| 92 | +# Used in help target |
| 93 | +list: |
| 94 | + @echo $(TARGET_LIST) |
| 95 | + |
| 96 | +HELP_INDENTATION ?= 2 |
| 97 | +HELP_NAME-DESC_SEP ?= 2 |
| 98 | + |
| 99 | +LENGTH_OF_LONGEST_TARGET_NAME = $(shell ruby -e 'puts ARGV.sort_by(&:size)[-1].size' $$(make list)) |
| 100 | + |
| 101 | +parse_help = perl -n -e \ |
| 102 | + 'if(/^(\S*)?(?=:).*$(HELP_MARK)\s*(.*)/){ \ |
| 103 | + print((" " x $(HELP_INDENTATION)) . "$$1" . (" " x ($(LENGTH_OF_LONGEST_TARGET_NAME) + $(HELP_NAME-DESC_SEP) - length($$1))) . "- $$2\n") \ |
| 104 | + }' $(1) |\ |
| 105 | + sort |
| 106 | + |
| 107 | +# Help target that reads text after two '#'s in a target definition and prints it after the target name |
| 108 | +.PHONY: help |
| 109 | +help: ## Show this help |
| 110 | + @echo "The main targets are:" |
| 111 | + @$(call parse_help, $(firstword $(MAKEFILE_LIST))); echo |
| 112 | + # Iterate through the extra optional makefiles |
| 113 | + @for makefile in $(wordlist 2, $(words $(MAKEFILE_LIST)), $(MAKEFILE_LIST)); do |
| 114 | + echo "Targets defined in $$makefile:" |
| 115 | + $(call parse_help, $$makefile) |
| 116 | + echo |
| 117 | + done |
| 118 | + @echo "The default target is '$(.DEFAULT_GOAL)'" |
| 119 | + |
| 120 | +define HELP_MARK |
| 121 | +## |
| 122 | +endef |
0 commit comments