-
Notifications
You must be signed in to change notification settings - Fork 474
Expand file tree
/
Copy pathMakefile
More file actions
290 lines (231 loc) · 9.23 KB
/
Makefile
File metadata and controls
290 lines (231 loc) · 9.23 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################
# User-servicable parts:
################################################################################
# C/C++ compiler; to use Clang, build with `make CC=clang CXX=clang++`
CXX ?= g++
CC ?= gcc
# coreutils `install` command
INSTALL ?= install
# The `help2man` command
HELP2MAN ?= help2man
# Directories to place installed files.
PREFIX ?= /usr/local
MAN1_DIR ?= man/man1
# Default optimisation level (override by passing OPT=... in the make invocation)
OPT ?= -O3
# Default flags (can be overriden by passing CXXFLAGS=... in the make invocation)
CXXFLAGS ?= -g $(OPT) -Wall -Wextra -Woverloaded-virtual -pedantic -fPIC
# Required flags (including -std=c++17)
CXXFLAGS += -std=c++17 -Iinclude -Ithird_party/md5 -Ithird_party/json -Ithird_party/rapidyaml/
# Default C compilation flags (can be overridden by passing CFLAGS=... in the make invocation)
CFLAGS ?= -g $(OPT) -Wall -Wextra -pedantic -fPIC
# Required C compilation flags (including -std=c99)
CFLAGS += -std=c99 -Iinclude
# Default flags for linking binaries
LDFLAGS ?=
# Default flags for linking .so shared objects
SHARED_LDFLAGS ?= -shared
###
# GoogleTest library, from the system.
#
GTEST_PKG := gtest_main
GTEST_FOUND := $(shell pkg-config --exists '$(GTEST_PKG)' && echo yes || echo no)
ifeq ($(GTEST_FOUND),yes)
GTEST_CXXFLAGS := $(shell pkg-config --cflags '$(GTEST_PKG)')
GTEST_LDFLAGS := $(shell pkg-config --libs '$(GTEST_PKG)')
endif
HELP2MAN_FOUND := $(shell command -v '$(HELP2MAN)' > /dev/null 2>&1 && echo yes || echo no)
ifneq ($(HELP2MAN_FOUND),yes)
$(warning help2man was not found under the name $(HELP2MAN); manpages will not be built.)
endif
ifeq ($(origin GTEST_ENABLED),undefined)
GTEST_ENABLED := $(GTEST_FOUND)
ifeq ($(GTEST_ENABLED),no)
$(warning GoogleTest package was not found on the system, some tests will be skipped.)
endif
else ifeq ($(GTEST_ENABLED),$(GTEST_FOUND))
# Desired state matches found state; we're fine.
else ifeq ($(GTEST_ENABLED),no)
# GoogleTest was explicitly disabled; that's fine.
else ifeq ($(GTEST_ENABLED),yes)
$(error GoogleTest was explicitly requested but is not found on the system.)
override GTEST_ENABLED := no
else
$(error GTEST_ENABLED was set to some invalid value, it must be unset, 'yes', or 'no')
endif
# --- End Google Test Integration ---
################################################################################
# End of user-servicable parts
################################################################################
# Disable all GNU Make builtin rules, we want to specify our own.
.SUFFIXES:
# Single sed invocation that finds and extracts the version from the libjsonnet.h header.
# Hash and Dollar characters use hex escapes to avoid angering the Makefile interpreter.
EXTRACT_VERSION_SED := /^[ \t]*\x23[ \t]*define[ \t]+LIB_JSONNET_VERSION[ \t]+["]v([0-9.]+(-?[a-z][a-z0-9]*)?)["][ \t]*\x24/ { s//\1/p; q; }
# Extract the library version from libjsonnet.h.
VERSION := $(shell sed -nE '$(EXTRACT_VERSION_SED)' include/libjsonnet.h)
SOVERSION := 0
ifeq ($(shell uname -s),Darwin)
SONAME_FLAG := -install_name
TEST_RPATH_FLAG := -Wl,-rpath,'@executable_path'
else # else assume Linux-like
SONAME_FLAG := -soname
TEST_RPATH_FLAG := -Wl,-rpath,'$$ORIGIN'
endif # platform switch
LIB_SRC := \
core/desugarer.cpp \
core/formatter.cpp \
core/lexer.cpp \
core/libjsonnet.cpp \
core/parser.cpp \
core/pass.cpp \
core/path_utils.cpp \
core/static_analysis.cpp \
core/string_utils.cpp \
core/vm.cpp \
third_party/md5/md5.cpp \
third_party/rapidyaml/rapidyaml.cpp
LIB_OBJ := $(addprefix .makebuild/,$(addsuffix .o,$(LIB_SRC)))
LIB_CPP_SRC := \
cpp/libjsonnet++.cpp
LIB_CPP_OBJ := $(LIB_OBJ) $(addprefix .makebuild/,$(addsuffix .o,$(LIB_CPP_SRC)))
BINS_SRC := \
cmd/utils.cpp \
cmd/jsonnetfmt.cpp \
cmd/jsonnet.cpp
BINS := \
jsonnet \
jsonnetfmt
MAN_PAGES := $(addprefix $(MAN1_DIR)/,$(addsuffix .1,$(BINS)))
LIBS := \
libjsonnet.so \
libjsonnet.so.$(SOVERSION) \
libjsonnet.so.$(VERSION) \
libjsonnet++.so \
libjsonnet++.so.$(SOVERSION) \
libjsonnet++.so.$(VERSION) \
PUBLIC_HEADERS := \
include/libjsonnet.h \
include/libjsonnet_fmt.h \
include/libjsonnet++.h
PLAIN_TEST_SRC := \
core/libjsonnet_file_test.c \
core/libjsonnet_native_callbacks_test.c
GTEST_TEST_SRC := \
cpp/libjsonnet_locale_test.cpp \
cpp/libjsonnet++_test.cpp \
core/libjsonnet_test.cpp \
core/lexer_test.cpp \
core/unicode_test.cpp \
core/parser_test.cpp
PLAIN_TEST_BINS := $(basename $(notdir $(PLAIN_TEST_SRC)))
GTEST_TEST_BINS := $(basename $(notdir $(GTEST_TEST_SRC)))
ALL_TEST_BINS := $(PLAIN_TEST_BINS) $(GTEST_TEST_BINS)
DEPS_FILES := $(addprefix .makebuild/,$(addsuffix .o.d,$(LIB_SRC) $(LIB_CPP_SRC) $(BINS_SRC) $(TEST_SRC)))
# Intermediate build output directories.
BUILD_DIRS := $(sort $(dir $(DEPS_FILES)) .makebuild/stdlib/)
ifeq ($(GTEST_ENABLED),yes)
ENABLED_TEST_BINS := $(ALL_TEST_BINS)
else
ENABLED_TEST_BINS := $(PLAIN_TEST_BINS)
endif
################################################################################
# Targets / Build rules
################################################################################
ALL := $(LIBS) $(BINS) $(MAN_PAGES) $(ENABLED_TEST_BINS)
.PHONY: default bins libs man all install dist clean
default: $(LIBS) $(BINS)
bins: $(BINS)
libs: $(LIBS)
man: $(MAN_PAGES)
all: $(ALL)
test: bins libs $(ENABLED_TEST_BINS)
./tests.sh
dist:
@{ >&2 echo "The dist target is no longer supported, please don't use it." ; exit 1 ; }
clean:
{ \
rm -df \
$(BINS) $(LIBS) $(MAN_PAGES) $(ALL_TEST_BINS) \
stdlib/to_c_array core/std.jsonnet.h \
&& rm -rf .makebuild ;\
}
install: bins libs man
{ \
$(INSTALL) -Dm 644 -t $(DESTDIR)$(PREFIX)/bin/ $(BINS) ;\
$(INSTALL) -Dm 644 -t $(DESTDIR)$(PREFIX)/lib/ $(LIBS) ;\
$(INSTALL) -Dm 644 -t $(DESTDIR)$(PREFIX)/include/ $(PUBLIC_HEADERS) ;\
$(INSTALL) -Dm 644 -t $(DESTDIR)$(PREFIX)/share/$(MAN1_DIR)/ $(MAN_PAGES) ;\
}
CC_DEPS_FLAGS = -MMD -MP -MF "$(addsuffix .d,$@)"
.makebuild/%.cpp.o: %.cpp
mkdir -p $(@D) && $(CXX) $(CC_DEPS_FLAGS) $(CXXFLAGS) -o $@ -c $<
.makebuild/%.c.o: %.c
mkdir -p $(@D) && $(CC) $(CC_DEPS_FLAGS) $(CFLAGS) -o $@ -c $<
%.so.$(SOVERSION): %.so.$(VERSION)
ln -sf $< $@
%.so: %.so.$(SOVERSION)
ln -sf $< $@
ifeq ($(HELP2MAN_FOUND),yes)
$(MAN_PAGES): $(MAN1_DIR)/%.1: % | $(MAN1_DIR)
$(HELP2MAN) --no-info --output=$@ ./$<
$(MAN1_DIR):
mkdir -p $@
else
.PHONY: $(MAN1_DIR) $(MAN_PAGES)
$(MAN1_DIR) $(MAN_PAGES):
@{ >&2 echo "Skipping $@: Cannot build manpages, help2man was not found." ; }
endif
jsonnet: .makebuild/cmd/jsonnet.cpp.o .makebuild/cmd/utils.cpp.o $(LIB_OBJ)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
jsonnetfmt: .makebuild/cmd/jsonnetfmt.cpp.o .makebuild/cmd/utils.cpp.o $(LIB_OBJ)
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
libjsonnet.so.$(VERSION): $(LIB_OBJ)
$(CXX) $(LDFLAGS) $(LIB_OBJ) $(SHARED_LDFLAGS) -Wl,$(SONAME_FLAG),libjsonnet.so.$(SOVERSION) -o $@
libjsonnet++.so.$(VERSION): $(LIB_CPP_OBJ)
$(CXX) $(LDFLAGS) $(LIB_CPP_OBJ) $(SHARED_LDFLAGS) -Wl,$(SONAME_FLAG),libjsonnet++.so.$(SOVERSION) -o $@
# std.jsonnet.h is a generated file so the first build will fail if it isn't
# specified as an explicit dependency (after that, deps are known from compiler output)
.makebuild/core/desugarer.cpp.o: core/std.jsonnet.h
# Encode standard library for embedding in C
.makebuild/stdlib/to_c_array: stdlib/to_c_array.cpp
mkdir -p $(@D) && $(CXX) $(CXXFLAGS) -o "$@" $^
core/%.jsonnet.h: stdlib/%.jsonnet .makebuild/stdlib/to_c_array
.makebuild/stdlib/to_c_array "$<" "$@"
# Plain-C tests (link to libjsonnet.so); don't use GoogleTest (which is C++ only)
libjsonnet_file_test libjsonnet_native_callbacks_test: %: .makebuild/core/%.c.o libjsonnet.so
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(TEST_RPATH_FLAG)
###
# Tests that use GoogleTest
#
ifeq ($(GTEST_ENABLED),yes)
# C++ lib tests (links to libjsonnet++.so)
libjsonnet_locale_test libjsonnet++_test: %: .makebuild/cpp/%.cpp.o libjsonnet++.so
$(CXX) $(CXXFLAGS) $(GTEST_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(GTEST_LDFLAGS) $(TEST_RPATH_FLAG)
# C++ tests of the C API (link to libjsonnet.so)
libjsonnet_test: %: .makebuild/core/%.cpp.o libjsonnet.so
$(CXX) $(CXXFLAGS) $(GTEST_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(GTEST_LDFLAGS) $(TEST_RPATH_FLAG)
# Core component unit tests (narrow deps)
lexer_test: %: .makebuild/core/%.cpp.o .makebuild/core/lexer.cpp.o
$(CXX) $(CXXFLAGS) $(GTEST_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(GTEST_LDFLAGS)
unicode_test: %: .makebuild/core/%.cpp.o
$(CXX) $(CXXFLAGS) $(GTEST_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(GTEST_LDFLAGS)
parser_test: %: .makebuild/core/%.cpp.o .makebuild/core/parser.cpp.o .makebuild/core/lexer.cpp.o
$(CXX) $(CXXFLAGS) $(GTEST_CXXFLAGS) -o $@ $^ $(LDFLAGS) $(GTEST_LDFLAGS)
endif # GTEST_ENABLED
#
###
-include $(DEPS_FILES)