This repository has been archived by the owner on Aug 29, 2024. It is now read-only.
forked from abodelot/sfml-widgets
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMakefile
302 lines (255 loc) · 12.5 KB
/
Makefile
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
302
#-----------------------------------------------------------------------------
# GNU Makefile for GCC/CLANG -- on both "native GNU" (i.e. Linux etc.) and
# Windows (i.e. MinGW, w64devkit or compatible)
#
# Dependencies:
# - GNU make 4.3 (4.4 if .WAIT is used; not available on Ubuntu 22!)
# - SFML (pre-3.0 "master"): should be preinstalled locally (i.e. manually,
# or with the help of tooling/sfml-setup (which is for Linux only))
# - OpenGL & other platform deps (see AUXLIBS): should be provided by the host
# system (e.g. the GHA job installs them before launching the build)
# - freetype: provided by the host for shared builds, or bundled with SFML
# for static linking [!! Mentioned separately from the rest because I had
# issues with shared-linking it on a WSL Debian, but can't recall what exactly...]
#-----------------------------------------------------------------------------
include tooling/build/Make-toolcfg.inc
#-----------------------------------------------------------------------------
# Build options...
#
# - LIB_MODE: static (shared (would mean DLL on windows) not yet supported)
# - DEBUG: 0 (default) or 1 (also selects the SFML debug libs if 1!)
# - CC: g++ (default) or clang++
# - SFML_DIR: pre-built SFML package dir for the current toolchain
# - SFML_LINKMODE: static (default for windows) or shared (default for linux)
#!! Note: With GCC/Clang there seems to be no need to compile separately for SFML
#!! shared vs. static mode, so enough to just dispatch for DEBUG there!
#!! ?? Was this also true on native Linux, or was it only tested with W64devkit?!
#!! ?? And what about Clang?
#!! (I vaguely recall the separation only relevant for Windows DLLs, so likely
#!! both true (and then the VPAT/VTAG logic should obey!), but be sure + explicit!)
# - CRT_LINKMODE: static (default) or shared (MSVC CRT lib; i.e. CL /MT or /MD)
#!! ?? Again, how does this translate to GCC/Clang?
#-----------------------------------------------------------------------------
LIB_MODE ?= static
DEBUG ?= 0
SFML_DIR ?= extern/sfml/$(TOOLCHAIN)
SFML_LINKMODE ?= $(if $(findstring linux,$(TOOLCHAIN)),shared,static)
#!! Only used for MSVC currently (to select -MD/-MT):
CRT_LINKMODE ?= static
#-----------------------------------------------------------------------------
# Project layout...
#-----------------------------------------------------------------------------
NAME := sfw
LIBNAME := $(NAME)
# What to run for the `test` rule:
TEST = $(TEST_DIR)/main
#TEST = $(TEST_DIR)/smoke
LIBDIR := lib/$(TOOLCHAIN)
SRCDIR := src
#! Direct subdirs of $(SRCDIR) with explicitly supported different build semantics:
LIB_TAGDIR := lib
TESTS_TAGDIR := test
EXAMPLES_TAGDIR := example
# Note the `=` below (and also that `tmp` is project-local):
OUTDIR = tmp/build/$(VROOT)
OBJDIR = $(OUTDIR)/o#!!... $(objext) <-- but this already has a dot prefix! :-/
TEST_DIR := test
DEMO_DIR := .
#!!TODO
#!! Make sure none of the ...DIR macros are empty (to avoid $(...DIR)/thing bugs)!
#!!TODO
#=============================================================================
# Workaround for #346
ifeq "$(CC)" "clang++"
GHA_OLD_CLANG_WORKAROUND := -stdlib=libc++
endif
#=============================================================================
CFLAGS_COMMON += -I$(SFML_DIR)/include $(GHA_OLD_CLANG_WORKAROUND)
#!! This may also be needed on Debian (not on Ubuntu) -- but just compiled it on my WSL Bullseye without it, so WTF?? --:
#!! LDFLAGS := -pthread $(LDFLAGS)
# Switch various params. according to the host platform (i.e. the list
# of "auxilary" libs for static build, terminal control etc.)
#!!Incorrectly merged condition of build (host) platform and toolchain!
ifneq "$(BUILDENV_OS)" "windows"
# --- Not Windows (assuming "Linux-like & GCC-like"):
TERM_YELLOW := \033[1;33m
TERM_GREEN := \033[1;32m
TERM_NO_COLOR := \033[0m
AUXLIBS := -lGL -lX11 -lXrandr -lXcursor -ludev
LDFLAGS += -L./$(LIBDIR) -l$(LIBNAME) -L$(SFML_DIR)/lib
else
# --- Windows:
TERM_YELLOW :=
TERM_GREEN :=
TERM_NO_COLOR :=
ifneq "$(TOOLCHAIN)" "msvc"
AUXLIBS := -lopengl32 -lwinmm -lgdi32
LDFLAGS += -L./$(LIBDIR) -l$(LIBNAME) -L$(SFML_DIR)/lib
else
# --- MSVC:
AUXLIBS := user32.lib kernel32.lib gdi32.lib winmm.lib advapi32.lib opengl32.lib
LDFLAGS += /LIBPATH:./$(LIBDIR) $(LIBFILE_STATIC) /LIBPATH:$(SFML_DIR)/lib
endif
endif
#-----------------------------------------------------------------------------
# Prepare the artifact lists...
#-----------------------------------------------------------------------------
#!! Only *.cpp yet!...
#! Note: that cd is to omit the $(SRCDIR) root from the results for easier mapping to $(OBJDIR).
LIBSRC := $(shell $(CD) "$(SRCDIR)"; $(FIND) "$(LIB_TAGDIR)" -name "*.cpp" -type f) # ... -not \( -path "$(EXCLUDE_SRCDIR)*" -type d -prune \) ...
#$(info LIBSRC = $(LIBSRC))
TESTSRC := $(shell $(CD) "$(SRCDIR)"; $(FIND) "$(TESTS_TAGDIR)" -name "*.cpp" -type f)
#$(info TESTSRC = $(TESTSRC))
EXAMPLESRC := $(shell $(CD) "$(SRCDIR)"; $(FIND) "$(EXAMPLES_TAGDIR)" -name "*.cpp" -type f)
#$(info EXAMPLESRC = $(EXAMPLESRC))
#$(error x)
TEST_SRCDIR := $(SRCDIR)/$(TESTS_TAGDIR)
EXAMPLES_SRCDIR := $(SRCDIR)/$(EXAMPLES_TAGDIR)
# Tag the executables with "-mingw", or nothing, respectively:
#!!OLD: TOOLCHAIN_TAG := $(if $(findstring linux,$(TOOLCHAIN)),-linux,-mingw)
TOOLCHAIN_TAG := -$(TOOLCHAIN)
# Mind the `=` vs. `:=` in the section below...
VROOT = $(TOOLCHAIN)/v.$(FILE_SUFFIX)#!! ...$(DIR_SUFFIX) <-- Use dots and/or subdirs instead of [-...[-...]]
#!!??VDIR = ...$(TOOLCHAIN_TAG)$(FILE_SUFFIX)
VTAG = $(TOOLCHAIN_TAG)$(FILE_SUFFIX)
VTAG_NOTC = $(FILE_SUFFIX)
LIBOBJ = $(LIBSRC:%.cpp=$(OBJDIR)/%$(objext))
#!! These aren't derived directly from ...SRC to allow decoupling the exes from single source files later:
_test_srcs = $(shell $(FIND) $(TEST_SRCDIR) -not \( -path "*/.*" -type d -prune \) -name "*.cpp" -type f)
TEST_EXES = $(_test_srcs:$(TEST_SRCDIR)/%.cpp=$(TEST_DIR)/%$(TOOLCHAIN_TAG)$(FILE_SUFFIX)$(exeext))
_example_srcs = $(shell $(FIND) $(EXAMPLES_SRCDIR) -not \( -path "*/.*" -type d -prune \) -name "*.cpp" -type f)
EXAMPLE_EXES = $(_example_srcs:$(EXAMPLES_SRCDIR)/%.cpp=$(DEMO_DIR)/%$(TOOLCHAIN_TAG)$(FILE_SUFFIX)$(exeext))
#!! This junk is needed to stop GNU make automatically deleting the object files! :-o
#!! (Except it didn't work; see comments at the "Main rules" section!...)
_test_objs = $(_test_srcs:$(TEST_SRCDIR)/%.cpp=$(OBJDIR)/$(TESTS_TAGDIR)/%$(objext))
_example_objs = $(_example_srcs:$(EXAMPLES_SRCDIR)/%.cpp=$(OBJDIR)/$(EXAMPLES_TAGDIR)/%$(objext))
#!!FILE_SUFFIX_DEBUG_1 := -DBG
#!!DIR_SUFFIX_DEBUG_1 := .DBG
FILE_SUFFIX_SFML_LINKMODE_shared_DEBUG_1 := -d
FILE_SUFFIX_SFML_LINKMODE_static_DEBUG_0 := -s
FILE_SUFFIX_SFML_LINKMODE_static_DEBUG_1 := -s-d
_sfml_lib_names := sfml-graphics sfml-window sfml-system
_sfml_lib_names_static := $(patsubst %,%-s,$(_sfml_lib_names))
_sfml_lib_names_debug := $(patsubst %,%-d,$(_sfml_lib_names))
_sfml_lib_names_static_debug := $(patsubst %,%-s-d,$(_sfml_lib_names))
CC_FLAGS_SFML_LINKMODE_static_DEBUG_0 := -DSFML_STATIC
CC_FLAGS_SFML_LINKMODE_static_DEBUG_1 := -DSFML_STATIC
CC_FLAGS_SFML_LINKMODE_shared_DEBUG_0 :=
CC_FLAGS_SFML_LINKMODE_shared_DEBUG_1 :=
LINK_FLAGS_SFML_LINKMODE_static_DEBUG_0 := $(patsubst %,-l%,$(_sfml_lib_names_static)) -lfreetype $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_static_DEBUG_1 := $(patsubst %,-l%,$(_sfml_lib_names_static_debug)) -lfreetype $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_shared_DEBUG_0 := $(patsubst %,-l%,$(_sfml_lib_names)) $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_shared_DEBUG_1 := $(patsubst %,-l%,$(_sfml_lib_names_debug)) $(AUXLIBS)
ifeq "$(TOOLCHAIN)" "msvc"
# Add an extra -s to the static libs for my custom SFML build for MSVC/CRTstatic!...
ifeq "$(CRT_LINKMODE)" "static"
_s := -s
endif
LINK_FLAGS_SFML_LINKMODE_static_DEBUG_0 := $(patsubst %,%$(_s).lib,$(_sfml_lib_names_static)) freetype.lib $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_static_DEBUG_1 := $(patsubst %,%$(_s)-d.lib,$(_sfml_lib_names_static)) freetype.lib $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_shared_DEBUG_0 := $(patsubst %,%.lib,$(_sfml_lib_names)) $(AUXLIBS)
LINK_FLAGS_SFML_LINKMODE_shared_DEBUG_1 := $(patsubst %,%.lib,$(_sfml_lib_names_debug)) $(AUXLIBS)
endif
# If MSVC then add -MD for shared CRT, -MT for static CRT.
ifeq "$(TOOLCHAIN)" "msvc"
_crtmode_tag := $(if $(findstring static,$(CRT_LINKMODE)),-MT,-MD)
endif
FILE_SUFFIX := $(_crtmode_tag)$(FILE_SUFFIX_SFML_LINKMODE_$(SFML_LINKMODE)_DEBUG_$(DEBUG))
CFLAGS_COMMON += $(CC_FLAGS_SFML_LINKMODE_$(SFML_LINKMODE)_DEBUG_$(DEBUG))
LDFLAGS += $(LINK_FLAGS_SFML_LINKMODE_$(SFML_LINKMODE)_DEBUG_$(DEBUG))
LIBNAME := $(LIBNAME)$(VTAG_NOTC)
LIBFILE_STATIC := $(LIBDIR)/$(libname_prefix)$(LIBNAME)$(libext_static)
#!!LIBFILE_SHARED := ...
#-----------------------------------------------------------------------------
define link_cmd =
@echo "$(TERM_YELLOW)Linking $@$(TERM_NO_COLOR)"
$(MUTE)$(LINKER) $< $(LDFLAGS)
endef
#!! Wow, couldn't just comment out the last line of link_cmd, so moved here:
# @echo "$(TERM_GREEN)Done.$(TERM_NO_COLOR)"
#-----------------------------------------------------------------------------
# Main rules...
#-----------------------------------------------------------------------------
# Stop GNU make butchering incremental builds by default:
OBJS = $(LIBOBJ) $(_test_objs) $(_example_objs)
#$(info OBJS = $(OBJS))
#!! Didn't work:
#.PRECIOUS: $(OBJS)
#!! Also didn't work:
#.SECONDARY: $(OBJS)
# This finally did:
.SECONDARY:
$(info Build option DEBUG = $(DEBUG))
$(info Build option SFML_LINKMODE = $(SFML_LINKMODE))
$(info Build option CRT_LINKMODE = $(CRT_LINKMODE))
#$(info TEST_EXES = $(TEST_EXES))
#$(info EXAMPLE_EXES = $(EXAMPLE_EXES))
$(info Extra compiler flags (CFLAGS_) = $(CFLAGS_))
.PHONY: lib test_exes examples run_tests clean
all: lib test_exes examples #run_test
lib: $(LIBFILE_STATIC)
test_exes: $(TEST_EXES)
examples: $(EXAMPLE_EXES)
$(LIBFILE_STATIC): $(LIBOBJ)
@$(ECHO) "$(TERM_YELLOW)Creating library$(TERM_NO_COLOR) $@"
@$(MKDIR) $(LIBDIR)
@$(LIBTOOL_STATIC) $(LIBTOOL_STATIC_FLAGS) $^
# @ar crvf $@ $^
run_tests: test_exes
@$(ECHO) "$(TERM_YELLOW)Running tests...$(TERM_NO_COLOR) $(TEST_EXE)"
@$(TEST_EXE)
#!! OBSOLETE:
#clean:
# @echo "$(TERM_YELLOW)Removing$(TERM_NO_COLOR) $(OBJDIR) & $(LIBFILE_STATIC)"
# -@rm -r $(OBJDIR)
# -@rm -r $(LIBFILE_STATIC)
#
#mrproper: clean
# @echo "$(TERM_YELLOW)Removing$(TERM_NO_COLOR) $(DEMO_EXE)"
# -@rm $(DEMO_EXE)
# @echo "$(TERM_YELLOW)Removing$(TERM_NO_COLOR) $(TEST_EXE)"
# -@rm $(TEST_EXE)
# @echo "$(TERM_YELLOW)Removing$(TERM_NO_COLOR) $(SMOKE_TEST_EXE)"
# -@rm $(SMOKE_TEST_EXE)
#-----------------------------------------------------------------------------
# Inference rules...
#-----------------------------------------------------------------------------
# Compile units for the lib
#! Done separately (see below), as they (may) need different options.
#! (E.g. no default lib vs. -MT[d]/-MD[d] etc.; see CLIBFLAGS vs. CEXEFLAGS.)
$(OBJDIR)/$(LIB_TAGDIR)/%$(objext): $(SRCDIR)/$(LIB_TAGDIR)/%.cpp
@$(ECHO) "$(TERM_YELLOW)Compiling$(TERM_NO_COLOR) $<"
@$(MKDIR) $(shell dirname $@)
$(MUTE)$(CXX) $(CXXFLAGS) $(CLIBFLAGS) -c $<
# Compile the rest (i.e. tests or examples):
#!! Could split this too by TESTS_TAGDIR/EXAMPLES_TAGDIR:
$(OBJDIR)/%$(objext): $(SRCDIR)/%.cpp
@$(ECHO) "$(TERM_YELLOW)Compiling$(TERM_NO_COLOR) test/example: $<"
@$(MKDIR) $(shell dirname $@)
$(MUTE)$(CXX) $(CXXFLAGS) $(CEXEFLAGS) -c $<
# Link each test source (via its .o) into a separate executable:
$(TEST_DIR)/%$(VTAG)$(exeext): $(OBJDIR)/$(TESTS_TAGDIR)/%$(objext) $(LIBFILE_STATIC)
@$(MKDIR) $(shell dirname $@)
$(link_cmd)
# Link each example source (via its .o) into a separate executable:
$(DEMO_DIR)/%$(VTAG)$(exeext): $(OBJDIR)/$(EXAMPLES_TAGDIR)/%$(objext) $(LIBFILE_STATIC)
@$(MKDIR) $(shell dirname $@)
$(link_cmd)
#-----------------------------------------------------------------------------
# Header dependencies...
#-----------------------------------------------------------------------------
-include $(OBJS:%$(objext)=%.d)
# Hack to deal with stale dependencies (adopted from the DarkPlaces Quake clone makefile):
%.h%: #!! Also adding `%.hpp %.inl` didn't work: just made all the EXISTING headers trigger this rule!... :-o
@echo "NOTE: Ignoring missing '$@' mentioned in dependencies..."
# @echo "HINT: consider 'make clean'"
# @echo
%.inl:
@echo "NOTE: Ignoring missing '$@' mentioned in dependencies..."
ifeq "1" "0"
$(info VROOT: $(VROOT))
$(info VTAG: $(VTAG))
$(info OBJDIR: $(OBJDIR))
$(info LIBNAME: $(LIBNAME))
$(error ABORT)
endif