1+ # Adapted from the generic cc65 makefile.
2+ # Notible exceptions:
3+ # - recursive dirs for src
4+ # - final files go into build/ directory instead of polluting root folder (e.g. lbl, com file etc)
5+
6+ # ##############################################################################
7+ # ## In order to override defaults - values can be assigned to the variables ###
8+ # ##############################################################################
9+
10+ # Space or comma separated list of cc65 supported target platforms to build for.
11+ TARGETS := atari
12+
13+ # Name of the final, single-file library.
14+ PROGRAM := fujinet-network.lib
15+
16+ # Path(s) to additional libraries required for linking the program
17+ # Use only if you don't want to place copies of the libraries in SRCDIR
18+ # Default: none
19+ LIBS :=
20+
21+ # Custom linker configuration file
22+ # Use only if you don't want to place it in SRCDIR
23+ # Default: none
24+ CONFIG :=
25+
26+ # Additional C compiler flags and options.
27+ # Default: none
28+ CFLAGS =
29+
30+ # Additional assembler flags and options.
31+ # Default: none
32+ ASFLAGS =
33+
34+ # Additional linker flags and options.
35+ # Default: none
36+ LDFLAGS =
37+
38+ # Path to the directory containing C and ASM sources.
39+ # Default: src
40+ SRCDIR :=
41+
42+ # Path to the directory where object files are to be stored (inside respective target subdirectories).
43+ # Default: obj
44+ OBJDIR :=
45+
46+ # Command used to run the emulator.
47+ # Default: depending on target platform. For default (c64) target: x64 -kernal kernal -VICIIdsize -autoload
48+ EMUCMD :=
49+
50+ # Build dir for putting final built program rather than cluttering root
51+ BUILD_DIR = build
52+
53+ # Options state file name. You should not need to change this, but for those
54+ # rare cases when you feel you really need to name it differently - here you are
55+ STATEFILE := Makefile.options
56+
57+ # Object Dir for writing compiled files to
58+ OBJDIR := obj
59+
60+ # ##################################################################################
61+ # ### DO NOT EDIT BELOW THIS LINE, UNLESS YOU REALLY KNOW WHAT YOU ARE DOING! ####
62+ # ##################################################################################
63+
64+ # ##################################################################################
65+ # ## Mapping abstract options to the actual compiler, assembler and linker flags ###
66+ # ## Predefined compiler, assembler and linker flags, used with abstract options ###
67+ # ## valid for 2.14.x. Consult the documentation of your cc65 version before use ###
68+ # ##################################################################################
69+
70+ # Compiler flags used to tell the compiler to optimise for SPEED
71+ define _optspeed_
72+ CFLAGS += -Oris
73+ endef
74+
75+ # Compiler flags used to tell the compiler to optimise for SIZE
76+ define _optsize_
77+ CFLAGS += -Or
78+ endef
79+
80+ # Compiler and assembler flags for generating listings
81+ define _listing_
82+ CFLAGS += --listing $(BUILD_DIR ) /$$(@:.o=.lst )
83+ ASFLAGS += --listing $(BUILD_DIR ) /$$(@:.o=.lst )
84+ REMOVES += $(addsuffix .lst,$(basename $(OBJECTS ) ) )
85+ endef
86+
87+ # Linker flags for generating map file
88+ define _mapfile_
89+ LDFLAGS += --mapfile $(BUILD_DIR ) /$$@ .map
90+ REMOVES += $(BUILD_DIR ) /$(PROGRAM ) .map
91+ endef
92+
93+ # Linker flags for generating VICE label file
94+ define _labelfile_
95+ LDFLAGS += -Ln $(BUILD_DIR ) /$$@ .lbl
96+ REMOVES += $(BUILD_DIR ) /$(PROGRAM ) .lbl
97+ endef
98+
99+ # Linker flags for generating a debug file
100+ define _debugfile_
101+ LDFLAGS += -Wl --dbgfile,$(BUILD_DIR ) /$$@ .dbg
102+ REMOVES += $(BUILD_DIR ) /$(PROGRAM ) .dbg
103+ endef
104+
105+ # ##############################################################################
106+ # ## Defaults to be used if nothing defined in the editable sections above ###
107+ # ##############################################################################
108+
109+ # Presume the C64 target like the cl65 compile & link utility does.
110+ # Set TARGETS to override.
111+ ifeq ($(TARGETS ) ,)
112+ TARGETS := c64
113+ endif
114+
115+ # Presume we're in a project directory so name the program like the current
116+ # directory. Set PROGRAM to override.
117+ ifeq ($(PROGRAM ) ,)
118+ PROGRAM := $(notdir $(CURDIR ) )
119+ endif
120+
121+ # Presume the C and asm source files to be located in the subdirectory 'src'.
122+ # Set SRCDIR to override.
123+ ifeq ($(SRCDIR ) ,)
124+ SRCDIR := src
125+ endif
126+
127+ TARGETOBJDIR := $(OBJDIR ) /$(TARGETS )
128+
129+ # On Windows it is mandatory to have CC65_HOME set. So do not unnecessarily
130+ # rely on cl65 being added to the PATH in this scenario.
131+ ifdef CC65_HOME
132+ CC := $(CC65_HOME ) /bin/cl65
133+ else
134+ CC := cl65
135+ endif
136+
137+
138+ # ##############################################################################
139+ # ## The magic begins ###
140+ # ##############################################################################
141+
142+ # The "Native Win32" GNU Make contains quite some workarounds to get along with
143+ # cmd.exe as shell. However it does not provide means to determine that it does
144+ # actually activate those workarounds. Especially does $(SHELL) NOT contain the
145+ # value 'cmd.exe'. So the usual way to determine if cmd.exe is being used is to
146+ # execute the command 'echo' without any parameters. Only cmd.exe will return a
147+ # non-empy string - saying 'ECHO is on/off'.
148+ #
149+ # Many "Native Win32" prorams accept '/' as directory delimiter just fine. How-
150+ # ever the internal commands of cmd.exe generally require '\' to be used.
151+ #
152+ # cmd.exe has an internal command 'mkdir' that doesn't understand nor require a
153+ # '-p' to create parent directories as needed.
154+ #
155+ # cmd.exe has an internal command 'del' that reports a syntax error if executed
156+ # without any file so make sure to call it only if there's an actual argument.
157+ ifeq ($(shell echo) ,)
158+ MKDIR = mkdir -p $1
159+ RMDIR = rmdir $1
160+ RMFILES = $(RM ) $1
161+ else
162+ MKDIR = mkdir $(subst /,\,$1)
163+ RMDIR = rmdir $(subst /,\,$1)
164+ RMFILES = $(if $1,del /f $(subst /,\,$1) )
165+ endif
166+ COMMA := ,
167+ SPACE := $(N/A ) $(N/A )
168+ define NEWLINE
169+
170+
171+ endef
172+ # Note: Do not remove any of the two empty lines above !
173+
174+ rwildcard =$(wildcard $(1 )$(2 ) )$(foreach d,$(wildcard $1* ) , $(call rwildcard,$d/,$2) )
175+
176+ TARGETLIST := $(subst $(COMMA ) ,$(SPACE ) ,$(TARGETS ) )
177+
178+ ifeq ($(words $(TARGETLIST ) ) ,1)
179+
180+ # Strip potential variant suffix from the actual cc65 target.
181+ CC65TARGET := $(firstword $(subst .,$(SPACE ) ,$(TARGETLIST ) ) )
182+
183+ # Set PROGRAM to something like 'myprog.c64'.
184+ override PROGRAM := $(PROGRAM ) .$(TARGETLIST )
185+
186+ # Set SOURCES to something like 'src/foo.c src/bar.s'.
187+ # Use of assembler files with names ending differently than .s is deprecated!
188+
189+ # Add to SOURCES something like 'src/c64/me.c src/c64/too.s'.
190+ # Use of assembler files with names ending differently than .s is deprecated!
191+ # Recursive files
192+ SOURCES += $(call rwildcard,$(TARGETLIST ) /$(SRCDIR ) /,* .s)
193+ SOURCES += $(call rwildcard,$(TARGETLIST ) /$(SRCDIR ) /,* .c)
194+
195+ # remove trailing and leading spaces.
196+ SOURCES := $(strip $(SOURCES ) )
197+
198+ # Set OBJECTS to something like 'obj/c64/foo.o obj/c64/bar.o'.
199+ # convert from src/your/long/path/foo.[c|s] to obj/your/long/path/foo.o
200+ OBJ1 := $(SOURCES:.c=.o )
201+ OBJECTS := $(OBJ1:.s=.o )
202+ OBJECTS := $(OBJECTS:$(TARGETLIST ) /$(SRCDIR ) /%=$(OBJDIR ) /$(TARGETLIST ) /% )
203+
204+ # Set DEPENDS to something like 'obj/c64/foo.d obj/c64/bar.d'.
205+ DEPENDS := $(OBJECTS:.o=.d )
206+
207+ # Add to LIBS something like 'src/foo.lib src/c64/bar.lib'.
208+ LIBS += $(wildcard $(TARGETLIST ) /$(SRCDIR ) /* .lib)
209+
210+ ASFLAGS += --asm-include-dir common/inc --asm-include-dir $(TARGETLIST ) /$(SRCDIR ) /inc
211+ CFLAGS += --include-dir common/inc --include-dir $(TARGETLIST ) /$(SRCDIR ) /inc
212+
213+ CHANGELOG = Changelog.md
214+
215+ VERSION_FILE = version.txt
216+ VERSION_STRING := $(file < $(VERSION_FILE ) )
217+
218+ FN_NW_HEADER = fujinet-network.h
219+ FN_NW_INC = fujinet-network.inc
220+
221+ .SUFFIXES :
222+ .PHONY : all clean dist fujinet-network.lib.$(TARGETLIST )
223+
224+ all : fujinet-network.lib.$(TARGETLIST )
225+
226+ -include $(DEPENDS )
227+ -include $(STATEFILE )
228+
229+ # If OPTIONS are given on the command line then save them to STATEFILE
230+ # if (and only if) they have actually changed. But if OPTIONS are not
231+ # given on the command line then load them from STATEFILE. Have object
232+ # files depend on STATEFILE only if it actually exists.
233+ ifeq ($(origin OPTIONS ) ,command line)
234+ ifneq ($(OPTIONS),$(_OPTIONS_))
235+ ifeq ($(OPTIONS),)
236+ $(info Removing OPTIONS)
237+ $(shell $(RM) $(STATEFILE))
238+ $(eval $(STATEFILE ) :)
239+ else
240+ $(info Saving OPTIONS=$(OPTIONS))
241+ $(shell echo _OPTIONS_=$(OPTIONS) > $(STATEFILE))
242+ endif
243+ $(eval $(OBJECTS ) : $(STATEFILE ) )
244+ endif
245+ else
246+ ifeq ($(origin _OPTIONS_),file)
247+ $(info Using saved OPTIONS=$(_OPTIONS_))
248+ OPTIONS = $(_OPTIONS_ )
249+ $(eval $(OBJECTS ) : $(STATEFILE ) )
250+ endif
251+ endif
252+
253+ # Transform the abstract OPTIONS to the actual cc65 options.
254+ $(foreach o,$(subst $(COMMA),$(SPACE),$(OPTIONS)),$(eval $(_$o_)))
255+
256+ $(OBJDIR ) :
257+ $(call MKDIR,$@ )
258+
259+ $(TARGETOBJDIR ) :
260+ $(call MKDIR,$@ )
261+
262+ $(BUILD_DIR ) :
263+ $(call MKDIR,$@ )
264+
265+ SRC_INC_DIRS := \
266+ $(sort $(dir $(wildcard $(TARGETLIST ) /$(SRCDIR ) /* ) ) )
267+
268+ # $(info $$SOURCES = ${SOURCES})
269+ # $(info $$OBJECTS = ${OBJECTS})
270+ # $(info $$SRC_INC_DIRS = ${SRC_INC_DIRS})
271+ # $(info $$ASFLAGS = ${ASFLAGS})
272+ # $(info $$TARGETOBJDIR = ${TARGETOBJDIR})
273+ # $(info $$TARGETLIST = ${TARGETLIST})
274+
275+ vpath % .c $(SRC_INC_DIRS )
276+
277+ $(TARGETOBJDIR ) /% .o : % .c | $(TARGETOBJDIR )
278+ @$(call MKDIR,$(dir $@ ) )
279+ $(CC ) -t $(TARGETLIST ) -c --create-dep $(@:.o=.d ) $(CFLAGS ) -o $@ $<
280+
281+ vpath % .s $(SRC_INC_DIRS )
282+
283+ $(TARGETOBJDIR ) /% .o : % .s | $(TARGETOBJDIR )
284+ @$(call MKDIR,$(dir $@ ) )
285+ $(CC ) -t $(TARGETLIST ) -c --create-dep $(@:.o=.d ) $(ASFLAGS ) -o $@ $<
286+
287+ $(BUILD_DIR ) /$(PROGRAM ) : $(OBJECTS ) | $(BUILD_DIR )
288+ ar65 a $@ $(OBJECTS )
289+
290+ $(PROGRAM ) : $(BUILD_DIR ) /$(PROGRAM ) | $(BUILD_DIR )
291+
292+ clean :
293+ $(call RMFILES,$(OBJECTS ) )
294+ $(call RMFILES,$(DEPENDS ) )
295+ $(call RMFILES,$(REMOVES ) )
296+ $(call RMFILES,$(BUILD_DIR ) /$(PROGRAM ) )
297+ $(call RMFILES,dist/* )
298+
299+ dist : $(PROGRAM )
300+ $(call MKDIR,dist/)
301+ $(call RMFILES,dist/fujinet-network-$(TARGETLIST ) -* .lib)
302+ cp build/$(PROGRAM ) dist/fujinet-network-$(TARGETLIST ) _$(VERSION_STRING ) .lib
303+ cp $(FN_NW_HEADER ) dist/
304+ cp $(FN_NW_INC ) dist/
305+ cp $(CHANGELOG ) dist/
306+ cd dist && zip fujinet-network-$(TARGETLIST ) _$(VERSION_STRING ) .zip $(CHANGELOG ) fujinet-network-$(TARGETLIST ) _$(VERSION_STRING ) .lib * .h * .inc
307+ $(call RMFILES,dist/fujinet-network-$(TARGETLIST ) _* .lib)
308+ $(call RMFILES,dist/$(CHANGELOG ) )
309+ $(call RMFILES,dist/* .h)
310+ $(call RMFILES,dist/* .inc)
311+
312+ else # $(words $(TARGETLIST)),1
313+
314+ all :
315+ $(foreach t,$(TARGETLIST ) ,$(MAKE ) TARGETS=$t clean all dist$(NEWLINE ) )
316+
317+ endif # $(words $(TARGETLIST)),1
318+
319+
320+ # ##################################################################
321+ # ## Place your additional targets in the additional Makefiles ###
322+ # ## in the same directory - their names have to end with ".mk"! ###
323+ # ##################################################################
324+ -include *.mk
0 commit comments