-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
132 lines (101 loc) · 4.7 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# Top-level makefile; includes all Module.mk files it can find in any of the
# subdirectories. Partly based on the non-recursive make from "Managing Projects With GNU
# Make". Written for GNU Make and not expected to be portable.
# Parameters controlling implicit rules (as listed in section 10.3 of the GNU Make Manual)
# or that the user can override with command options use upper case letters. Those
# serving internal purposes in this makefile use lower case letters. This practice is
# recommended in chapter 6 of the GNU Make Manual.
# "Every Makefile should contain this line..." - section 7.2.1 of the GNU Coding Standards
SHELL := /bin/sh
# Disable all built-in rules. See http://stackoverflow.com/q/4122831 and
# http://gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html.
MAKEFLAGS += --no-builtin-rules
# Clear the suffix list; no suffix rules in this makefile. See section 7.2.1 of the GNU
# Coding Standards.
.SUFFIXES:
CXX ?= g++
CPPFLAGS += -Wall -Wextra -pedantic -g -O
CXXFLAGS += -std=c++14 -Wold-style-cast
LDFLAGS += -g -O
LDLIBS +=
ARFLAGS := cs
##########################################################################################
# Taken from "Managing Projects With GNU Make".
subdirectory = $(patsubst %/Module.mk,%, \
$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
# See section 7.2.3 'Variables for Specifying Commands' of the GNU Coding Standards.
all_cppflags := $(CPPFLAGS)
all_cxxflags := $(CXXFLAGS) -c
all_ldflags := $(LDFLAGS)
all_ldlibs := $(LDLIBS)
all_arflags := r$(ARFLAGS)
# Collect information from each module in these variables. Explicitly initialize as
# simple variables as recursive ones are the default.
sources :=
libraries :=
programs :=
# Set the default target.
all:
include $(shell find -name 'Module.mk')
prereq_files := $(sources:.cpp=.d)
objects := $(sources:.cpp=.o)
# All whitespace-separated words in the working directory and its subdirectories that do
# match any of the pattern words $(prereq_files). File names shall not contain the "%"
# character.
existent_prereqs := \
$(filter $(prereq_files),$(shell find -regex '.*\.d$$' -printf '%P\n'))
# Was any goal (other than `clean`) specified on the command line? None counts as `all`.
ifneq ($(filter-out clean,$(or $(MAKECMDGOALS),all)),)
# Include existent makefiles of prerequisites. After reading in all those files none
# of them will have to be updated. Non-existent prerequisite files will be build along
# with their respective object files.
include $(existent_prereqs)
endif
.PHONY: all
all: $(programs) $(libraries)
.PHONY: clean
clean:
$(RM) $(prereq_files) $(objects) $(libraries) $(programs)
# Directories that will be included in development snapshot archives built by the snapshot
# target.
snapdirs := examples/ examples/humble/ src/
# Files included in snapshot archives.
snapfiles := COPYING INSTALL README Makefile
snapfiles += $(shell find $(snapdirs) -maxdepth 1 -regextype posix-extended \
-regex '.*\.(h|cpp)')
snapfiles += $(shell find $(snapdirs) -maxdepth 1 -name Makefile)
# Yields e.g. 19901229T1337Z.
date := $(shell date -u +%Y%m%dT%H%MZ)
snaproot := nutshell_dynamics-$(date)
snapdirs := $(snaproot) $(addprefix $(snaproot)/,$(snapdirs))
snaplinks := $(addprefix $(snaproot)/,$(snapfiles))
.PHONY: snapshot
# Build a development snapshot archive.
snapshot: $(snaproot).tar
$(snaproot).tar: $(snapdirs) $(snaplinks)
tar -cvf $(snaproot).tar $(snaproot)
$(RM) -r $(snaproot)
# Create hard links to all files that are required to build a source archive. Build
# $(snapdirs) first but don't rebuild $@ when any of those direcories has a later
# timestamp than $@. See section 4.3 of the GNU Make Manual.
$(snaplinks): | $(snapdirs)
@ln $(subst $(snaproot)/,,$@) $@
# Build the directory tree needed for the snapshot archive (as far as it doesn't exist
# already).
$(snapdirs):
mkdir -p $@
# If the target is not an existent file, then Make will imagine it to have been updated
# whenever this rule is run -- and the rule should only be run when the target is not an
# existent file.
# This way it is ensured that an object file corresponding to any of the targets of this
# rule (a makefile of prereq_files) will be updated, if the target does not exist. That
# file will be created along with the object file and included during the next invocation
# of make.
$(prereq_files):
# Enable the second expansion of prerequisites.
.SECONDEXPANSION:
# A call $(subst foo,bar,text) replaces each occurrence of 'foo' by 'bar' and does not
# substitute 'foo' for 'bar' as I tend to misunderstand it recurringly.
$(objects): $$(subst .o,.d,$$@)
$(CXX) -MMD $(all_cppflags) $(all_cxxflags) $(subst .o,.cpp,$@) -o $@
# vim: tw=90 ts=8 sts=-1 sw=3 noet