Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
218 lines (177 loc) · 8.42 KB
/
Copy pathMakefile
File metadata and controls
218 lines (177 loc) · 8.42 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
CXX := clang++
CXXFLAGS := -std=c++17 -Wall -Wextra -Wno-deprecated-register -Wno-unused-function
# Let the compiler record each object's header dependencies (build/*.d,
# included at the end of this file). The per-object prerequisite lists
# below were written by hand and were incomplete — lexer.o didn't depend on
# ast.h, codegen.o not on extdesc.h — so a header change could leave
# objects built against the old declarations. When a class's layout
# changed, that linked into an rpgc that crashed.
CXXFLAGS += -MMD -MP
# Platform-specific tool and library paths
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
BREW_PREFIX := $(shell brew --prefix 2>/dev/null || echo /opt/homebrew)
FLEX ?= $(BREW_PREFIX)/opt/flex/bin/flex
BISON ?= $(BREW_PREFIX)/opt/bison/bin/bison
ODBC_CFLAGS ?= -I$(BREW_PREFIX)/include
ODBC_LIBS ?= -L$(BREW_PREFIX)/lib -lodbc
else ifneq (,$(MSYSTEM))
# MSYSTEM is set by every MSYS2 shell (MINGW64, UCRT64, CLANGARM64, ...) —
# more reliable than grepping `uname -s`, which reports a different
# prefix per environment (e.g. CLANGARM64_NT-... on Windows ARM64) and
# would silently miss anything but literal "MINGW".
FLEX ?= flex
BISON ?= bison
ODBC_CFLAGS ?=
ODBC_LIBS ?= -lodbc32
# Static-link the C++ runtime so rpgc.exe doesn't depend on MSYS2's
# libc++.dll/libstdc++-6.dll/libwinpthread-1.dll being present on the
# target machine — the NSIS installer only ships the exe itself.
LDFLAGS ?= -static
ifeq ($(MSYSTEM),CLANGARM64)
CXX := clang++
else
CXX := g++
endif
else
FLEX ?= flex
BISON ?= bison
ODBC_CFLAGS ?=
ODBC_LIBS ?= -lodbc
CXX := g++
endif
SRCDIR := src
BUILDDIR := build
TARGET := rpgc
SRCS := $(BUILDDIR)/lexer.cpp \
$(BUILDDIR)/parser.cpp \
$(SRCDIR)/ast.cpp \
$(SRCDIR)/codegen.cpp \
$(SRCDIR)/sql_utils.cpp \
$(SRCDIR)/conf.cpp \
$(SRCDIR)/extdesc.cpp \
$(SRCDIR)/keyword_list.cpp \
$(SRCDIR)/fixed_reader.cpp \
$(SRCDIR)/fixed_cspec.cpp \
$(SRCDIR)/main.cpp
OBJS := $(BUILDDIR)/lexer.o \
$(BUILDDIR)/parser.o \
$(BUILDDIR)/ast.o \
$(BUILDDIR)/codegen.o \
$(BUILDDIR)/sql_utils.o \
$(BUILDDIR)/conf.o \
$(BUILDDIR)/extdesc.o \
$(BUILDDIR)/keyword_list.o \
$(BUILDDIR)/fixed_reader.o \
$(BUILDDIR)/fixed_cspec.o \
$(BUILDDIR)/main.o
VERSION ?= $(shell git describe --tags --always 2>/dev/null || echo "dev")
CXXFLAGS += -DRPGC_VERSION='"$(VERSION)"'
PREFIX ?= /usr/local
BINDIR := $(PREFIX)/bin
DATADIR := $(PREFIX)/share/rpgc/runtime
# Pass installed runtime path to main.cpp so rpgc can find headers after install
CXXFLAGS += -DRPGC_RUNTIME_DIR='"$(DATADIR)"'
# OpenDSPF is vendored as a git submodule at $(DSPF_DIR). Run
# `git submodule update --init` if it's empty. Both of these must be defined
# before the `all` rule below: make expands a rule's prerequisites as the
# makefile is read, so a variable assigned further down expands to nothing and
# the dependency silently disappears.
DSPF_DIR ?= OpenDSPF
DSPF_RUNTIME := runtime/rpg_dspf_runtime.h
all: $(TARGET) $(DSPF_RUNTIME)
$(BUILDDIR):
mkdir -p $(BUILDDIR)
$(BUILDDIR)/parser.cpp $(BUILDDIR)/parser.h: $(SRCDIR)/parser.y | $(BUILDDIR)
$(BISON) --defines=$(BUILDDIR)/parser.h -o $(BUILDDIR)/parser.cpp $<
$(BUILDDIR)/lexer.cpp: $(SRCDIR)/lexer.l $(BUILDDIR)/parser.h | $(BUILDDIR)
$(FLEX) -o $@ $<
$(BUILDDIR)/lexer.o: $(BUILDDIR)/lexer.cpp $(SRCDIR)/keyword_list.h $(SRCDIR)/cond_expr.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/keyword_list.o: $(SRCDIR)/keyword_list.cpp $(SRCDIR)/keyword_list.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
HDRS := $(SRCDIR)/ast.h $(SRCDIR)/codegen.h $(BUILDDIR)/parser.h
$(BUILDDIR)/ast.o: $(SRCDIR)/ast.cpp $(SRCDIR)/ast.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/codegen.o: $(SRCDIR)/codegen.cpp $(HDRS)
$(CXX) $(CXXFLAGS) $(ODBC_CFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/sql_utils.o: $(SRCDIR)/sql_utils.cpp $(SRCDIR)/ast.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/conf.o: $(SRCDIR)/conf.cpp $(SRCDIR)/conf.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/extdesc.o: $(SRCDIR)/extdesc.cpp $(SRCDIR)/extdesc.h $(SRCDIR)/conf.h
$(CXX) $(CXXFLAGS) $(ODBC_CFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/main.o: $(SRCDIR)/main.cpp $(SRCDIR)/ast.h $(SRCDIR)/codegen.h $(SRCDIR)/conf.h $(SRCDIR)/extdesc.h $(SRCDIR)/fixed_reader.h
$(CXX) $(CXXFLAGS) $(ODBC_CFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/parser.o: $(BUILDDIR)/parser.cpp $(SRCDIR)/ast.h $(SRCDIR)/free_bridge.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/fixed_reader.o: $(SRCDIR)/fixed_reader.cpp $(SRCDIR)/fixed_reader.h $(SRCDIR)/fixed_columns.h $(SRCDIR)/fixed_cspec.h $(SRCDIR)/free_bridge.h $(SRCDIR)/keyword_list.h $(SRCDIR)/ast.h $(SRCDIR)/cond_expr.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(BUILDDIR)/fixed_cspec.o: $(SRCDIR)/fixed_cspec.cpp $(SRCDIR)/fixed_cspec.h $(SRCDIR)/fixed_columns.h $(SRCDIR)/free_bridge.h
$(CXX) $(CXXFLAGS) -I$(SRCDIR) -I$(BUILDDIR) -c -o $@ $<
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) $(ODBC_CFLAGS) -o $@ $^ $(LDFLAGS) $(ODBC_LIBS)
clean:
rm -rf $(BUILDDIR) $(TARGET) $(DSPF_RUNTIME)
# rpgc compiles WORKSTN programs against runtime/rpg_dspf_runtime.h, but that
# file belongs to OpenDSPF. It used to be a second tracked copy kept in step by
# hand, which is exactly as reliable as it sounds: the two silently diverged,
# and a whole set of display-runtime changes was developed and tested against
# the copy here while the submodule — the one CI, install-dspf and the Windows
# installer ship — still had the old code.
#
# So it is generated, not tracked. There is one copy of this file under source
# control, in OpenDSPF, and `make` refreshes the build-time copy from whatever
# $(DSPF_DIR) points at. Override DSPF_DIR to build against a different
# OpenDSPF checkout.
#
# A copy rather than a symlink: git only checks symlinks out as symlinks when
# core.symlinks is on, which it is not by default on Windows, and this header
# is shipped by the NSIS installer.
# FORCE, and a content compare rather than a timestamp one: the target is
# generated and gitignored, so an edit made to it directly would leave it
# NEWER than its source and make would consider it up to date forever —
# precisely the stale copy this rule exists to prevent. cmp keeps the copy
# from running when the bytes already match, so nothing downstream rebuilds
# needlessly.
$(DSPF_RUNTIME): $(DSPF_DIR)/runtime/rpg_dspf_runtime.h FORCE
@cmp -s $< $@ 2>/dev/null || { echo "cp $< $@"; cp $< $@; }
FORCE:
$(DSPF_DIR)/runtime/rpg_dspf_runtime.h:
@echo "error: $(DSPF_DIR)/runtime/rpg_dspf_runtime.h is missing."; \
echo " OpenDSPF is a git submodule and has not been checked out."; \
echo " Run: git submodule update --init"; \
exit 1
install: $(TARGET)
install -d $(DESTDIR)$(BINDIR)
install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/$(TARGET)
install -d $(DESTDIR)$(DATADIR)
install -m 644 runtime/rpg_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_sql_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_call_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_regex_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_xml_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_json_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_csv_runtime.h $(DESTDIR)$(DATADIR)/
install -m 644 runtime/rpg_flatfile_runtime.h $(DESTDIR)$(DATADIR)/
$(DSPF_DIR)/dspfc:
$(MAKE) -C $(DSPF_DIR)
install-dspf: $(DSPF_DIR)/dspfc
install -m 755 $(DSPF_DIR)/dspfc $(DESTDIR)$(BINDIR)/dspfc
install -d $(DESTDIR)$(DATADIR)
install -m 644 $(DSPF_DIR)/runtime/rpg_dspf_runtime.h $(DESTDIR)$(DATADIR)/
install-all: install install-dspf
uninstall:
rm -f $(DESTDIR)$(BINDIR)/$(TARGET)
rm -rf $(DESTDIR)$(DATADIR)
uninstall-dspf:
rm -f $(DESTDIR)$(BINDIR)/dspfc
rm -f $(DESTDIR)$(DATADIR)/rpg_dspf_runtime.h
test: $(TARGET)
@bash tests/run_tests.sh
@bash tests/run_debug_tests.sh
update-expected: $(TARGET)
@bash tests/run_tests.sh --update
.PHONY: FORCE all clean install install-dspf install-all uninstall uninstall-dspf test update-expected
# Compiler-generated header dependencies (see -MMD above).
-include $(OBJS:.o=.d)