-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMakefile
More file actions
301 lines (274 loc) · 17.4 KB
/
Copy pathMakefile
File metadata and controls
301 lines (274 loc) · 17.4 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
291
292
293
294
295
296
297
298
299
300
301
TARGET=osp
#CXX_OPT=-march=native -flto -O2 -fprofile-arcs -ftest-coverage -fprofile-dir=/home/dv/src/my/openspaceprogram/data/pgo -fprofile-generate=/home/dv/src/my/openspaceprogram/data/pgo
#LD_OPT=-O2 -flto -fprofile-arcs
#SANITIZE=-g3 -fsanitize=address -fsanitize=leak -fsanitize=undefined
CXX= g++
# -MMD -MP emit a .d dependency file per object so a changed header (e.g. frame.h)
# forces a recompile of every TU that includes it. Without this, make only sees
# the .cpp prerequisite and silently links stale .o files with a mismatched
# struct layout -> heap corruption / segfault. The .d files are -included below.
CXXFLAGS=-O2 -MMD -MP $(CXX_OPT) $(SANITIZE) -Wall -Wextra -Wpedantic -Wno-unused-variable -Wno-unused-parameter -Wno-unused-but-set-variable -std=c++11 -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/imgui/ -I./middleware/ -I/usr/include/SDL2
LINKER=g++ -O2 $(LD_OPT) $(SANITIZE) -o
LDLIBS=-lSDL2_image -lSDL2 -lGLEW -lGL -lassimp
# Default to all cores: a plain `make` runs parallel (verified: MAKEFLAGS
# set in-file takes effect, and a command-line -jN still overrides it).
# $(shell ...) -- not $(nproc) -- because make 4.4 does not run the shell
# for an undefined variable; it would expand to empty, leaving a bare
# -j, which means *unlimited* jobs.
MAKEFLAGS += -j$(shell nproc)
# imgui submodule (pinned to a tagged release), built like everything else
# (the build rules are near the bottom, after the main target)
IMGUI_DIR=./middleware/imgui
IMGUI_OBJS=./obj/imgui/imgui.o ./obj/imgui/imgui_draw.o ./obj/imgui/imgui_widgets.o ./obj/imgui/imgui_tables.o ./obj/imgui/imgui_impl_sdl2.o ./obj/imgui/imgui_impl_opengl3.o
# implot submodule (pinned to a tagged release): plotting plugin that draws
# through the existing imgui renderer, so only its two .cpp files are built.
IMPLLOT_DIR=./middleware/implot
IMPLLOT_OBJS=./obj/implot/implot.o ./obj/implot/implot_items.o
# clone bullet3 in ./middleware
# cd ./middleware/bullet3
# ln -s bullet src
# build it with cmake with double precision enabled
BULLET3_OBJS=./middleware/bullet3/build/src/BulletDynamics/libBulletDynamics.a ./middleware/bullet3/build/src/BulletCollision/libBulletCollision.a ./middleware/bullet3/build/src/BulletSoftBody/libBulletSoftBody.a ./middleware/bullet3/build/src/Bullet3Geometry/libBullet3Geometry.a ./middleware/bullet3/build/src/BulletInverseDynamics/libBulletInverseDynamics.a ./middleware/bullet3/build/src/Bullet3Common/libBullet3Common.a ./middleware/bullet3/build/src/Bullet3Collision/libBullet3Collision.a ./middleware/bullet3/build/src/LinearMath/libLinearMath.a ./middleware/bullet3/build/src/Bullet3Serialize/Bullet2FileLoader/libBullet2FileLoader.a ./middleware/bullet3/build/src/Bullet3OpenCL/libBullet3OpenCL_clew.a ./middleware/bullet3/build/src/Bullet3Dynamics/libBullet3Dynamics.a
LFLAGS=$(LTO) -Wall $(LDLIBS) $(IMGUI_LIBS) $(BULLET3_OBJS)
SRCDIR=src
OBJDIR=obj
BINDIR=.
SOURCES := $(wildcard $(SRCDIR)/*.cpp)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
# Header dependency files (generated by -MMD). -include is silent when absent
# (first build), and pulls each .o's full include list into the dependency graph.
DEPS := $(OBJECTS:.o=.d) $(IMGUI_OBJS:.o=.d) $(IMPLLOT_OBJS:.o=.d)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS) $(IMGUI_OBJS) $(IMPLLOT_OBJS)
$(LINKER) $@ $(IMGUI_OBJS) $(IMPLLOT_OBJS) $(OBJECTS) $(LFLAGS)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -c $< -o $@
# The git version string into src/version.h (embedded in the main menu by
# gameui.cpp). `version` is phony, so its check re-runs on every build; it
# rewrites the header only when the string actually changed, so a quiet
# `make` stays quiet and gameui.o (which depends on the header file
# itself) is recompiled only when the version changes. A file target with
# no prerequisites (the old form) would be seen as up-to-date forever
# once the header existed, and the menu would keep the stale string.
# Note: make fixes its rebuild plan before recipes run, so a changed
# version lands on the build after the one that rewrote the header;
# `make clean && make` (the release flow) picks it up immediately.
# `make version` re-runs the check on demand (e.g. after adding a tag);
# `make version VERSION=1.0` overrides it outside a git checkout.
.PHONY: version
version:
@( VERSION_STRING="$(VERSION)"; \
[ -e "./.git" ] && GITVERSION=$$( git describe --tags --always --dirty --match "[0-9A-Z]*.[0-9A-Z]*" ) && VERSION_STRING=$$GITVERSION ; \
[ -e "src/version.h" ] && OLDVERSION=$$(grep VERSION src/version.h|cut -d '"' -f2) ; \
if [ "x$$VERSION_STRING" != "x$$OLDVERSION" ]; then echo "#define VERSION \"$$VERSION_STRING\"" | tee src/version.h ; fi \
)
src/version.h: version
$(OBJDIR)/gameui.o: src/version.h
./obj/imgui/imgui.o: $(IMGUI_DIR)/imgui.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/imgui/imgui_draw.o: $(IMGUI_DIR)/imgui_draw.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/imgui/imgui_widgets.o: $(IMGUI_DIR)/imgui_widgets.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/imgui/imgui_tables.o: $(IMGUI_DIR)/imgui_tables.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/imgui/imgui_impl_sdl2.o: $(IMGUI_DIR)/backends/imgui_impl_sdl2.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/imgui/imgui_impl_opengl3.o: $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp
@mkdir -p ./obj/imgui
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/implot/implot.o: $(IMPLLOT_DIR)/implot.cpp
@mkdir -p ./obj/implot
$(CXX) $(CXXFLAGS) -c $< -o $@
./obj/implot/implot_items.o: $(IMPLLOT_DIR)/implot_items.cpp
@mkdir -p ./obj/implot
$(CXX) $(CXXFLAGS) -c $< -o $@
# Unit tests for the pure-math core (reference frames, orbital math).
# These link against src/frame.cpp directly, so they need no rendering/Bullet.
test:
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet \
tests/test_frames.cpp src/frame.cpp -o test_frames
./test_frames
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet \
tests/test_spawn.cpp src/frame.cpp -o test_spawn
./test_spawn
# attitude law (pure C, no Bullet): the per-substep braking law
# main.cpp runs, pinned across the authority/warp grid.
$(CXX) -O2 -std=c++11 tests/test_attitude.cpp -o test_attitude
./test_attitude
# slew law in 3 DOF (pure C++, no Bullet/GL): the full-transverse law
# damps the "third-axis" spin the old slew-axis-only law left undamped
# (the prograde wobble), across spin magnitudes and warps; pins the
# non-vacuous guard (the old law must wobble) + the authority bound.
$(CXX) -O2 -std=c++11 tests/test_slew3d.cpp -o test_slew3d
./test_slew3d
# thrust fixes (substep delivery, fuel flow, SetMass inertia): links the
# real src/physics.cpp, so it pulls in the render chain + Bullet + GL libs.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/ -I/usr/include/SDL2 \
tests/test_thrust.cpp src/physics.cpp src/body.cpp src/shader.cpp src/camera.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_thrust
./test_thrust
# fuel drain (the real Vehicle::consumeResourceMass from src/vehicle.h
# + the real SetMass): pro-rata across the active stage's tanks (not
# first-tank-first), stage gating, no stranded fuel, no partial drain.
# Same real-Bullet link as test_thrust (no GL context needed).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/ -I/usr/include/SDL2 \
tests/test_fuel.cpp src/physics.cpp src/body.cpp src/shipdef.cpp src/shader.cpp src/camera.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_fuel
./test_fuel
# staging topology (Vehicle::droppedPartsAtStage from src/vehicle.h): a
# decoupler drops itself + its whole child-side subtree, a sibling branch
# sharing the stage NUMBER survives (the heavy_two rule), and nested /
# same-stage decouplers compose. Pure graph logic over Part::parent -- it
# reads no Bullet state -- but it links like test_fuel because vehicle.h's
# inline destructor references the physics teardown symbols.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/ -I/usr/include/SDL2 \
tests/test_staging.cpp src/physics.cpp src/body.cpp src/shipdef.cpp src/shader.cpp src/camera.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_staging
./test_staging
# ship mass properties (Vehicle::get_center_of_mass / getInertia from
# src/vehicle.h): golden values against an independent analytic
# parallel-axis assembly, incl. the products of inertia and rotated
# non-cubic parts. This is the tensor a reaction wheel's authority and
# the autopilot slew law divide by; nothing else pins it (test_attitude
# and test_slew3d simulate their own hardcoded Ix/Iz, and e2e 22 only
# checks ratios). Also pins the ship's single compound rigid body
# (Vehicle::rebuildCompound): the principal-axis transform's COM origin,
# its diagonalized inertia against that same analytic reference, the
# re-based child poses, and the part poses derived back out of the body
# at an arbitrary world pose. Headless: no world, no GL context.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/ -I/usr/include/SDL2 \
tests/test_inertia.cpp src/physics.cpp src/body.cpp src/shipdef.cpp src/shader.cpp src/camera.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_inertia
./test_inertia
# rotation model (physical wheel torque, per-substep law, torque
# delivery): same real-Bullet link as test_thrust.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/ -I/usr/include/SDL2 \
tests/test_rotation.cpp src/physics.cpp src/body.cpp src/shader.cpp src/camera.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_rotation
./test_rotation
# ship/part JSON data model (GL-free: catalog + ship-def parse/validate,
# part resolution, aggregates). Runs from the repo root (needs res/).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/ \
tests/test_shipload.cpp src/shipdef.cpp -o test_shipload
./test_shipload
# crew_capacity on the part catalog (GL-free: which parts are capsules
# and their seat count, the default-0 for everything else, error path).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/ \
tests/test_crew.cpp src/shipdef.cpp -o test_crew
./test_crew
# fleet JSON (GL-free: entry parse + defaults + error paths).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/ \
tests/test_fleet.cpp src/fleet.cpp -o test_fleet
./test_fleet
# home-planet calendar (src/calendar.h, header-only pure math): day/year
# from spin/orbit rates, 427-day snapped year, months, epoch year,
# tidally-locked + star edge cases. Pinned to the Eerbon JSON rates.
$(CXX) -O2 -std=c++11 -I./src tests/test_calendar.cpp -o test_calendar
./test_calendar
# two-body orbital elements + time-to-apsis (src/orbit.h, header-only
# pure math): elements, anomaly conversions, the ApT/PeT countdown fix,
# hyperbolic/parabolic handling, degenerate-plane guards.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_orbit.cpp -o test_orbit
./test_orbit
# orbit-sampling cache (src/orbitsample.h, header-only pure math): the
# map's per-orbit points, cached on the elements so coasting orbits are
# propagated once. Circular/eccentric radii, cache hit + invalidation,
# hyperbolic -> empty.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_orbitsample.cpp -o test_orbitsample
./test_orbitsample
# Lambert solver + min-dv planner (src/transfer.h, header-only pure
# math): Hohmann analytic reference, round-trip, hyperbolic leg.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_transfer.cpp -o test_transfer
./test_transfer
# porkchop 2-D sweep (src/transfer.h, header-only pure math): pinned to
# planTransfer (t_dep = 0 row) + the Hohmann analytic min + the no-
# solution (all-NaN) path + grid bookkeeping.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_porkchop.cpp -o test_porkchop
./test_porkchop
# surface map projection + terminator (src/surfmap.h, header-only pure
# math): the equirectangular pixel <-> direction round-trip, the
# lon/lat convention (lon 0 = +Z, north = +Y -- the same atan2(x, z) /
# asin(y) render.cpp uses), the shade range, the antimeridian wrap.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_surfmap.cpp -o test_surfmap
./test_surfmap
# EVA control-law geometry (src/evamath.h, header-only pure math): the
# Rodrigues rotation + axis-angle round-trip (incl. the 180-deg
# fallback), the camera/upright target bases, the screen-axis helpers.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_eva.cpp -o test_eva
./test_eva
# terrain core (src/terragen.h, header-only pure math): the height
# model (bounds, sea floor, the LOD band-limit fade), the surface
# color (sea, palette, gas-giant bands), and the grid builder
# (vertex/index counts, band-limited on-surface vertices, the skirt
# ring below the terrain).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_terrain.cpp -o test_terrain
./test_terrain
# background job runner (src/job.cpp): the worker/main-thread handoff --
# the body runs off the calling thread, the returned continuation runs on
# the poll() thread, jobs land in posted order, a throwing body does not
# kill the worker, busy()/poll() report the state + the running label.
$(CXX) -O2 -std=c++11 -I./src tests/test_jobs.cpp src/job.cpp -o test_jobs
./test_jobs
# orbital map projection (src/orbitmap.h, pure-math part): project() drops
# the map normal (+Y) and scales XZ by meters-per-pixel. Header-only, so
# the imgui include is headers-only (no imgui/Bullet/GL link needed).
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/imgui/ tests/test_orbitmap.cpp -o test_orbitmap
./test_orbitmap
# orbit camera (src/camera.cpp, pure math): pitching past the pole must
# keep the up vector continuous (no sudden roll) and the view NaN-free.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ tests/test_orbitcam.cpp src/camera.cpp -o test_orbitcam
./test_orbitcam
# picking (src/pick.cpp): pixel->ray round-trip through the camera's
# own view/projection (a point on the ray projects back to the pixel),
# then the real Bullet convex-cast hull ray-test (hit point/distance,
# a miss, translated + rotated bodies). pick.cpp includes game.h (the
# fleet), so the imgui include dir is needed for ui.h; and pickShipPart
# casts against a ship's compound children, which inlines Vehicle's
# pose accessors, so physics.cpp + body.cpp + shipdef.cpp link in.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/glm/ -I./middleware/bullet3/ -I./middleware/bullet3/bullet -I./middleware/imgui/ -I./middleware/ -I/usr/include/SDL2 \
tests/test_pick.cpp src/pick.cpp src/physics.cpp src/body.cpp src/shipdef.cpp src/camera.cpp src/frame.cpp src/shader.cpp src/mesh.cpp src/texture.cpp src/model.cpp src/gldebug.cpp \
$(BULLET3_OBJS) -lGL -lGLEW -lSDL2 -lSDL2_image -lassimp -o test_pick
./test_pick
# settings.json mapping (src/settings.cpp, nlohmann): the
# SettingsData <-> JSON round trip, absent-key tolerance (a field the
# file does not mention keeps the current value), mistyped-key
# tolerance, and the window-mode name mapping.
$(CXX) -O2 -std=c++11 -I./src -I./middleware/ \
tests/test_settings.cpp src/settings.cpp -o test_settings
./test_settings
# E2E battery: launch the built game under Xvfb and run the pass/fail cases
# in e2e/cases/ (see e2e/run.py). Needs the game binary, so it depends on
# $(TARGET). Runs headless via xvfb-run; on a machine with a real display it
# uses that instead. Stdlib Python only.
# Cases run in parallel (run.py --jobs, default 2); override with JOBS,
# e.g. `make e2e JOBS=4` or `make e2e JOBS=1` for serial.
JOBS ?=
E2E_JOBS = $(if $(JOBS),--jobs $(JOBS),)
.PHONY: e2e
e2e: $(TARGET)
python3 e2e/run.py $(E2E_JOBS)
# GL-context probe: on this Mesa 26 stack any draw (or vertex-attribute
# setup) made in the default VAO 0 fails with GL_INVALID_OPERATION — draws
# must happen inside a real glGenVertexArrays VAO (even an empty one for a
# vertex-less gl_VertexID quad). Needs an X display:
# DISPLAY=:99 make test-gl
test-gl:
$(CXX) -O2 -std=c++11 -I/usr/include/SDL2 tests/test_vertexless.c -lSDL2 -lGLEW -lGL -o test_gl_vao
./test_gl_vao
.PHONY: clean
clean:
$(rm) $(OBJECTS) $(OBJECTS:.o=.d)
.PHONY: remove
remove: clean
$(rm) $(BINDIR)/$(TARGET) test_frames test_spawn test_attitude test_slew3d test_thrust test_fuel test_staging test_inertia test_rotation test_shipload test_crew test_fleet test_calendar test_orbit test_orbitsample test_transfer test_porkchop test_orbitmap test_orbitcam test_pick test_surfmap test_terrain test_jobs test_settings test_eva test_gl_vao
# Pull in the generated header dependencies (see -MMD above). Silent if the
# .d files don't exist yet (fresh checkout / first build).
-include $(DEPS)