-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
271 lines (241 loc) · 12.6 KB
/
Copy pathMakefile
File metadata and controls
271 lines (241 loc) · 12.6 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
# MagicMenu - AmigaOS 3.x / m68k cross-build with vbcc.
#
# WHY vbcc and not GCC: a Bebbo-GCC/libnix build of the MagicMenu commodity
# crashed at boot every time, in the libnix program startup before main().
# The identical source built with vbcc (its own startup, absolute addressing)
# runs. See the "Amiga build" section of the top-level developer notes.
#
# Toolchain layout (override TOOLCHAIN to relocate), same as wet7/Makefile.cross:
# $(TOOLCHAIN)/bin vc, vbccm68k, vasmm68k_mot, vlink
# $(TOOLCHAIN)/config/aos68k vbcc target config
# $(TOOLCHAIN)/ndk39/NDK_3.9 AmigaOS 3.9 NDK
# $(TOOLCHAIN)/mui5/SDK/MUI/C/include MUI 5 SDK, MagicMenuPrefs only
#
# The commodity needs no MUI SDK: "make MagicMenu" builds with MUIINC unset.
# The host-side steps need tools of their own - awk and a host cc for the
# catalogs, python3 for the readme, jlha for the archive.
#
# make build both binaries into release/
# make MagicMenu the commodity only
# make MagicMenuPrefs the editor only
# make catalogs compile locale/*.ct into release/Catalogs/
# make dist assemble the archive tree under build/dist/
# (or under /tmp when the repository is on a Windows mount)
# make archive pack that tree into release/MagicMenu_3.lha
# make readme regenerate install/MagicMenu.readme from README.md
# make checkcatalogs verify the built catalogs against the header
# make bannertest verify the built-in banner's chunky-to-planar pass
# make bannerdata regenerate src/bannerdata.c from the banner PNG
# make clean
TOOLCHAIN ?= $(HOME)/amiga-toolchain
HOSTPATH := $(PATH)
export VBCC := $(TOOLCHAIN)
export PATH := $(TOOLCHAIN)/bin:$(PATH)
NDK := $(TOOLCHAIN)/ndk39/NDK_3.9/Include/include_h
ASMINC := $(TOOLCHAIN)/ndk39/NDK_3.9/Include/include_i
# MUI 5 SDK headers - MagicMenuPrefs' GUI is MUI (min runtime 3.8/V19);
# the commodity never touches MUI, the include path is merely visible.
MUIINC := $(TOOLCHAIN)/mui5/SDK/MUI/C/include
CC := vc +aos68k
AS := vasmm68k_mot
CFLAGS := -c99 -O2 -Isrc -Iinclude -I$(NDK) -I$(MUIINC)
ASFLAGS := -Fhunk -quiet -nowarn=62 -I$(ASMINC)
LIBS := -lamiga
BUILD := build
# Everything shippable goes here: the two binaries, the compiled catalogs,
# and the .lha archives built from them. $(BUILD) keeps only intermediates -
# objects, the generated catalog header, the host-side ct2catalog - so that
# release/ can be packed as it stands.
RELEASE := release
CATALOG := src/locale/magicmenu.h
# The patch stubs and the remapper are original SAS/C-era Motorola assembler;
# vasm assembles them directly (stubs.a was adjusted to read the saved vectors
# as absolute _Old<name>, since vbcc does not use the a4 small-data model).
MAIN_C := main.c misc.c data.c wedge.c windowglyphs.c memory.c menuboxes.c \
dointuimenu.c sendintuimessage.c storage.c
PREFS_C := edit.c prefsgui.c demoimagedata.c storage.c banner.c bannerdata.c
# NOT built: src/Assert.c. It is only referenced when DEBUG is defined (see
# src/Assert.h); enabling that means adding Assert.c to the lists above, or
# the link fails on unresolved symbols.
# Every object depends on every header. There is no -MMD dependency
# generation here, and the failure it prevents is not a link error: a
# prefs.h change that grows struct MMPrefs would otherwise link objects
# compiled against the old size against ones compiled against the new,
# silently corrupting memory in a resident commodity.
HDRS := $(wildcard src/*.h) $(CATALOG)
MAIN_OBJ := $(addprefix $(BUILD)/,$(MAIN_C:.c=.o)) $(BUILD)/stubs.o $(BUILD)/remap.o
PREFS_OBJ := $(addprefix $(BUILD)/,$(PREFS_C:.c=.o)) $(BUILD)/remap.o
# awk truncates its output before it runs, and cd2h.awk can exit non-zero;
# without this a failed generation leaves a truncated header that looks
# up to date.
.DELETE_ON_ERROR:
# The three program targets name the binary but build it into $(RELEASE),
# so the file they are named after never appears - they must be phony or
# every make relinks.
.PHONY: all clean gccwarn catalogs checkcatalogs readme dist archive MagicMenu MagicMenuPrefs bannerdata bannertest
all: MagicMenu MagicMenuPrefs
# Generated by tools/cd2h.awk (CatComp replacement - CatComp is an Amiga binary).
$(CATALOG): locale/MagicMenu.cd tools/cd2h.awk
@mkdir -p $(dir $@)
LC_ALL=C awk -v SRC=$< -f tools/cd2h.awk $< > $@
$(BUILD)/%.o: src/%.c $(HDRS) | $(BUILD)
$(CC) $(CFLAGS) -c -o $@ $<
$(BUILD)/%.o: src/%.a | $(BUILD)
$(AS) $(ASFLAGS) -o $@ $<
$(BUILD) $(RELEASE):
@mkdir -p $@
MagicMenu: $(MAIN_OBJ) | $(RELEASE)
$(CC) -o $(RELEASE)/$@ $(MAIN_OBJ) $(LIBS)
MagicMenuPrefs: $(PREFS_OBJ) | $(RELEASE)
$(CC) -o $(RELEASE)/$@ $(PREFS_OBJ) $(LIBS)
# The built-in banner. src/bannerdata.c is generated and COMMITTED, so the
# ordinary build needs neither python3 nor the PNG; remake it only when the
# image changes. bannertest compiles src/banner.c on the host and checks its
# chunky-to-planar pass against bitplanes png2banner.py computes by a
# different route from the same PNG.
BANNER_PNG := graphics/banner/magicmenuprefs.png
bannerdata:
python3 tools/png2banner.py $(BANNER_PNG) src/bannerdata.c
bannertest: | $(BUILD)
python3 tools/png2banner.py --planar $(BANNER_PNG) $(BUILD)/banner-expected.bin
$(HOSTCC) -O2 -DBANNER_HOST_TEST -Isrc -o $(BUILD)/bannertest tools/bannertest.c
$(BUILD)/bannertest $(BUILD)/banner-expected.bin
clean:
rm -rf $(BUILD) $(RELEASE) $(dir $(CATALOG)) $(STAGE)
# A second-opinion warning pass with Bebbo's amiga-gcc. GCC does NOT build
# this project - see the header for the crash that settled that - but it is
# the only compiler here that offers -Wall -Wextra, and it has found real
# bugs the shipped toolchain says nothing about. Nothing is linked and no
# object is written; this target only ever prints.
#
# Two shims make it work, both outside the vbcc path, both there because
# without them GCC cannot parse a single file and the tool silently stops
# being available:
# tools/gccwarn-bases.h forced into prefsgui.c alone; __NOLIBBASE__
# plus GCC's real-function inlines reference the
# library bases while proto/muimaster.h is being
# parsed, before the file declares them
#
# The NDK is NOT passed here: Bebbo's GCC has its own NDK headers wired in,
# and adding $(NDK) on top of them collides.
AMIGAGCC ?= /opt/amiga/bin/m68k-amigaos-gcc
GCCWARN_FLAGS := -Wall -Wextra -fsyntax-only -Wno-attributes \
-Isrc -Iinclude -I$(MUIINC)
gccwarn: $(CATALOG)
@for f in $(sort $(MAIN_C) $(PREFS_C)); do \
echo "=== $$f"; \
if [ "$$f" = "prefsgui.c" ]; then \
$(AMIGAGCC) $(GCCWARN_FLAGS) -include tools/gccwarn-bases.h src/$$f || true; \
else \
$(AMIGAGCC) $(GCCWARN_FLAGS) src/$$f || true; \
fi; \
done
# Compiled message catalogs. tools/ct2catalog replaces
# `catcomp <cd> catalog <lang>/<name>.catalog <ct>`: the NDK CatComp is an
# AmigaOS binary and FlexCat is not installed here. It is built with the HOST
# compiler, not the cross one - it runs on the build machine.
#
# The output drawer is named after the .ct FILE, not after its "## language"
# line, and deliberately so: LZH stores a file name as raw bytes and the
# archivers within reach mangle or drop anything that is not ASCII, so
# "fran\347ais" cannot survive packing. install/Install copies each drawer to
# its real language name on the way to LOCALE:Catalogs. The two have to be
# kept in step by hand - a language added here needs a line added there.
# Resolved against the PATH as it was BEFORE the cross-toolchain was prepended
# above: ct2catalog runs on the build machine, and a "cc" inside the toolchain
# would produce a 68k binary that cannot run here.
HOSTCC ?= $(shell PATH="$(HOSTPATH)" command -v cc || echo cc)
CT2CAT := $(BUILD)/ct2catalog
$(CT2CAT): tools/ct2catalog.c | $(BUILD)
$(HOSTCC) -O2 -o $@ $<
catalogs: $(CT2CAT) $(wildcard locale/*.ct) locale/MagicMenu.cd | $(RELEASE)
@rm -rf $(RELEASE)/Catalogs
@for ct in locale/*.ct; do \
lang=`basename $$ct .ct`; \
mkdir -p $(RELEASE)/Catalogs/$$lang; \
$(CT2CAT) locale/MagicMenu.cd $$ct \
$(RELEASE)/Catalogs/$$lang/MagicMenu.catalog || exit 1; \
done
@echo "catalogs in $(RELEASE)/Catalogs/"
# The distributable. Assembles release/MagicMenu/ in the layout the Install
# script expects - WBStartup/ and Prefs/ mirror where the files end up, so the
# archive reads as its own documentation - and packs it with lha.
#
# The archive name is a literal, not derived from the version: it ships as
# MagicMenu_3.lha because that is the name it is known by. To name a build
# after its version instead, derive it from src/MagicMenu_rev.h rather than
# typing it twice.
# Staged away from "release/MagicMenu", which is already the commodity binary.
#
# The staging tree must sit on a filesystem that keeps bytes in file names.
# A Windows drive mounted into WSL (v9fs, drvfs) does not: it stores names as
# UTF-16, so a Latin-1 byte in "fran\347ais" or "espa\361ol" is rewritten to
# U+FFFD and the catalog drawer ends up called "fran?ais". locale.library
# looks a catalog up by that drawer name and would never find it again.
# Detect such a mount and stage in /tmp instead. Since the drawers are named
# after the .ct files this cannot bite today; it is kept because the moment
# anything stages a real language name, it would.
#
# "stat -f -c" is GNU coreutils; on BSD and macOS it fails, which takes the
# else branch - staging in the build tree, the safe answer. The temporary
# path carries the uid so two users on one machine cannot collide in a
# directory the build removes and then writes into.
STAGE := $(shell if stat -f -c %T . 2>/dev/null | grep -qE 'v9fs|drvfs|9p|cifs|fuseblk|vfat|msdos'; then echo $${TMPDIR:-/tmp}/magicmenu-dist-`id -u`; else echo $(BUILD)/dist; fi)
DIST := $(STAGE)/MagicMenu
# The installed "lha" here is Lhasa, which only extracts. jlha (jlha-utils)
# is the one that can create an archive Lhasa and the Amiga can both read.
LHA ?= jlha
# Staging is a target of its own so the tree can be inspected before anything
# is packed.
dist: all catalogs
@rm -rf $(STAGE)
@mkdir -p $(DIST)/WBStartup $(DIST)/Prefs $(DIST)/Icons
@cp install/Install $(DIST)/
@cp install/MagicMenu.readme $(DIST)/
@cp graphics/icons/Ken/MagicMenu.readme.info $(DIST)/
# The Install icon has to be one set or the other before the user has
# chosen: Ken's, matching the default the script offers. Both sets keep
# their own copy under Icons/ for anyone who wants to swap it.
@cp graphics/icons/Ken/Install.info $(DIST)/
@cp AUTHORS ChangeLog LICENSE $(DIST)/
@cp $(RELEASE)/MagicMenu $(DIST)/WBStartup/
@cp $(RELEASE)/MagicMenuPrefs $(DIST)/Prefs/
# The banner is compiled into MagicMenuPrefs and is NOT shipped as a file.
# A magicmenuprefs.pic that the user drops beside the editor
# replaces it; shipping one would mean the built-in image never appeared.
# Generated straight into the staging tree rather than copied from
# $(RELEASE)/Catalogs. On a Windows mount those drawer names have already
# lost their accents by the time they exist, and copying only carries the
# damage along; ct2catalog writing them here puts the right bytes down on a
# filesystem that keeps them.
@for ct in locale/*.ct; do \
lang=`basename $$ct .ct`; \
mkdir -p "$(DIST)/Catalogs/$$lang"; \
$(CT2CAT) locale/MagicMenu.cd $$ct \
"$(DIST)/Catalogs/$$lang/MagicMenu.catalog" || exit 1; \
done
@cp -r graphics/icons/Ken $(DIST)/Icons/DualPNG
@cp -r graphics/icons/original $(DIST)/Icons/MagicWB
@rm -f $(DIST)/Icons/DualPNG/MagicMenuDrawer.info \
$(DIST)/Icons/MagicWB/MagicMenuDrawer.info
# The drawer icon belongs BESIDE the drawer, not inside it, and it has
# to be named after it. Ken's again, to match the Install icon.
@cp graphics/icons/Ken/MagicMenuDrawer.info $(STAGE)/MagicMenu.info
@echo "staged in $(DIST)"
archive: dist
@rm -f $(RELEASE)/MagicMenu_3.lha
@cd $(STAGE) && $(LHA) a $(CURDIR)/$(RELEASE)/MagicMenu_3.lha MagicMenu MagicMenu.info
@cp install/MagicMenu.readme $(RELEASE)/MagicMenu_3.readme
@echo "$(RELEASE)/MagicMenu_3.lha"
# The archive readme is generated, not written: it and README.md drifted apart
# once already. README.md is the source; install/aminet-header.txt supplies the
# machine-readable fields Aminet reads. Not part of the default build, so the
# build itself keeps needing nothing but the cross-toolchain.
readme:
@MAGICMENU=$(CURDIR)/ python3 tools/mkreadme.py
# The acceptance test for the catalogs. It was written and then wired into
# nothing, which is how a test stops being run. It proves the id in every
# catalog is the id cd2h.awk gives the same symbol - the one thing that,
# if wrong, mistranslates silently rather than failing.
checkcatalogs: catalogs
@MAGICMENU=$(CURDIR)/ python3 tools/checkcatalogs.py