-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
194 lines (168 loc) · 6.63 KB
/
Makefile
File metadata and controls
194 lines (168 loc) · 6.63 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
CXX = g++
CXXFLAGS = -std=c++20 -Wall -Wextra -Wno-deprecated-declarations -g -MMD -MP -D_XOPEN_SOURCE=600 -D_DARWIN_C_SOURCE
SRC_DIR = src
BUILD_DIR = build
SOURCES = $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SRC_DIR)/vm/*.cpp) $(wildcard $(SRC_DIR)/builtins/*.cpp)
OBJECTS = $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SOURCES))
DEPS = $(OBJECTS:.o=.d)
TARGET = praia
all: $(TARGET)
# Auto-detect readline/libedit support
HAVE_READLINE := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lreadline -o /dev/null 2>/dev/null && echo 1)
HAVE_EDIT := $(shell echo 'int main(){}' | $(CXX) -x c++ - -ledit -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_READLINE),1)
CXXFLAGS += -DHAVE_READLINE
LDLIBS = -lreadline
else ifeq ($(HAVE_EDIT),1)
CXXFLAGS += -DHAVE_READLINE
LDLIBS = -ledit
else
LDLIBS =
endif
# Auto-detect SQLite
HAVE_SQLITE := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lsqlite3 -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_SQLITE),1)
CXXFLAGS += -DHAVE_SQLITE
LDLIBS += -lsqlite3
endif
# Auto-detect OpenSSL (check standard path, then Homebrew)
HAVE_OPENSSL := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lssl -lcrypto -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_OPENSSL),1)
CXXFLAGS += -DHAVE_OPENSSL
LDLIBS += -lssl -lcrypto
else
# Try Homebrew OpenSSL paths (macOS)
OPENSSL_PREFIX := $(shell brew --prefix openssl 2>/dev/null)
ifneq ($(OPENSSL_PREFIX),)
HAVE_OPENSSL := 1
CXXFLAGS += -DHAVE_OPENSSL -I$(OPENSSL_PREFIX)/include
LDLIBS += -L$(OPENSSL_PREFIX)/lib -lssl -lcrypto
endif
endif
# Auto-detect utf8proc (Unicode grapheme/case support)
HAVE_UTF8PROC := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lutf8proc -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_UTF8PROC),1)
CXXFLAGS += -DHAVE_UTF8PROC
LDLIBS += -lutf8proc
else
UTF8PROC_PREFIX := $(shell brew --prefix utf8proc 2>/dev/null)
ifneq ($(UTF8PROC_PREFIX),)
HAVE_UTF8PROC := 1
CXXFLAGS += -DHAVE_UTF8PROC -I$(UTF8PROC_PREFIX)/include
LDLIBS += -L$(UTF8PROC_PREFIX)/lib -lutf8proc
endif
endif
# Auto-detect RE2 (safe regex engine — O(n) guaranteed, no catastrophic backtracking)
HAVE_RE2 := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lre2 -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_RE2),1)
CXXFLAGS += -DHAVE_RE2
LDLIBS += -lre2
else
RE2_PREFIX := $(shell brew --prefix re2 2>/dev/null)
ifneq ($(RE2_PREFIX),)
HAVE_RE2 := 1
CXXFLAGS += -DHAVE_RE2 -I$(RE2_PREFIX)/include
LDLIBS += -L$(RE2_PREFIX)/lib -lre2
# RE2 depends on Abseil on some platforms
ABSEIL_PREFIX := $(shell brew --prefix abseil 2>/dev/null)
ifneq ($(ABSEIL_PREFIX),)
CXXFLAGS += -I$(ABSEIL_PREFIX)/include
endif
endif
endif
# libresolv for DNS queries (net.query)
HAVE_RESOLV := $(shell echo 'int main(){}' | $(CXX) -x c++ - -lresolv -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_RESOLV),1)
LDLIBS += -lresolv
endif
# Auto-detect -ldl for dlopen (Linux needs it, macOS has it in libSystem)
HAVE_DL := $(shell echo 'int main(){}' | $(CXX) -x c++ - -ldl -o /dev/null 2>/dev/null && echo 1)
ifeq ($(HAVE_DL),1)
LDLIBS += -ldl
endif
# Export symbols so dlopen'd plugins can resolve types from the main binary
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
LDFLAGS += -rdynamic
endif
# Allow callers (release pipeline, packagers) to append extra flags without
# clobbering the auto-detected CXXFLAGS above. Common use: bake in PRAIA_LIBDIR
# for a release build via:
# make EXTRA_CXXFLAGS='-DPRAIA_LIBDIR="\"/usr/local/lib/praia\""'
CXXFLAGS += $(EXTRA_CXXFLAGS)
$(TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c -o $@ $<
-include $(DEPS)
$(BUILD_DIR):
mkdir -p $(BUILD_DIR) $(BUILD_DIR)/vm $(BUILD_DIR)/builtins
clean:
rm -rf $(BUILD_DIR) $(TARGET)
# ── Install / Uninstall ──
# Usage: make install PREFIX=/usr/local
# make install PREFIX=/usr LIBDIR=/usr/share/praia
#
# Paths:
# Binary: $(PREFIX)/bin/praia
# Grains: $(LIBDIR)/grains/ (LIBDIR defaults to $(PREFIX)/lib/praia)
# Sand: $(LIBDIR)/sand/
#
# LIBDIR is baked into the binary at compile time so grains resolve
# without relative path guessing. DESTDIR is supported for staging.
PREFIX ?= /usr/local
LIBDIR ?= $(PREFIX)/lib/praia
BINDIR = $(PREFIX)/bin
SAND_DIR = sand
install:
$(MAKE) BUILD_DIR=/tmp/praia-install-build CXXFLAGS='$(CXXFLAGS) -DPRAIA_LIBDIR="\"$(LIBDIR)\""'
install -d $(DESTDIR)$(BINDIR)
install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/$(TARGET)
install -d $(DESTDIR)$(LIBDIR)/include
cp $(SRC_DIR)/praia_plugin.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/value.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/builtins.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/interpreter.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/gc_heap.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/environment.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/ast.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/token.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/fiber.h $(DESTDIR)$(LIBDIR)/include/
cp $(SRC_DIR)/signal_state.h $(DESTDIR)$(LIBDIR)/include/
install -d $(DESTDIR)$(LIBDIR)/grains
cp -R grains/* $(DESTDIR)$(LIBDIR)/grains/
install -d $(DESTDIR)$(LIBDIR)/sand
cp -R $(SAND_DIR)/main.praia $(DESTDIR)$(LIBDIR)/sand/
cp -R $(SAND_DIR)/grains $(DESTDIR)$(LIBDIR)/sand/
cp -R $(SAND_DIR)/grain.yaml $(DESTDIR)$(LIBDIR)/sand/
@printf '#!/bin/sh\nexec "$(BINDIR)/praia" "$(LIBDIR)/sand/main.praia" "$$@"\n' > $(DESTDIR)$(BINDIR)/sand
chmod 755 $(DESTDIR)$(BINDIR)/sand
rm -rf /tmp/praia-install-build
@echo "Installed praia -> $(DESTDIR)$(BINDIR)/praia"
@echo "Installed sand -> $(DESTDIR)$(BINDIR)/sand"
@echo "Installed grains -> $(DESTDIR)$(LIBDIR)/grains/"
uninstall:
rm -f $(DESTDIR)$(BINDIR)/praia
rm -f $(DESTDIR)$(BINDIR)/sand
rm -rf $(DESTDIR)$(LIBDIR)
@echo "Uninstalled praia from $(DESTDIR)$(PREFIX)"
test: $(TARGET) test-input
./$(TARGET) test
# Integration test for sys.input — needs piped stdin, so runs outside `praia test`.
test-input: $(TARGET)
@out=$$(printf "Ada\ny\n" | ./$(TARGET) examples/input_demo.praia) && \
echo "$$out" | grep -q "Hello, Ada!" && \
echo "$$out" | grep -q "Onwards." && \
echo "sys.input: ok"
@out=$$(./$(TARGET) examples/input_demo.praia < /dev/null) && \
echo "$$out" | grep -q "No input" && \
echo "sys.input EOF: ok"
# ── Plugin build helper ──
# Usage: make plugin SRC=examples/plugins/mathext.cpp OUT=examples/plugins/mathext.dylib
PLUGIN_LDFLAGS =
ifeq ($(UNAME_S),Darwin)
PLUGIN_LDFLAGS = -undefined dynamic_lookup
endif
plugin:
$(CXX) -std=c++20 -shared -fPIC -I$(SRC_DIR) $(PLUGIN_LDFLAGS) -o $(OUT) $(SRC)
.PHONY: all clean install uninstall test test-input plugin