1 | # Central makefile for building the OS2/GCC C runtime
|
---|
2 | #
|
---|
3 | # InnoTek Systemberatung GmbH
|
---|
4 | #
|
---|
5 | # Copyright (c) 1994-1995 by Eberhard Mattes
|
---|
6 | # Copyright (c) 2003 InnoTek Systemberatung GmbH
|
---|
7 | #
|
---|
8 | # Author: Andrew Zabolotny <zap@cobra.ru>
|
---|
9 | # $Id: Makefile 1218 2004-02-11 09:54:54Z bird $
|
---|
10 | #
|
---|
11 | # All Rights Reserved
|
---|
12 | #
|
---|
13 | # Requires GNU Make.
|
---|
14 | # In fact, this build system could be entitled "GNU Make Unleashed"
|
---|
15 | #
|
---|
16 | # For a brief description of how build system works please read build.txt
|
---|
17 | #
|
---|
18 | # Bootstrapping sequence using EMX gcc compiler:
|
---|
19 | #
|
---|
20 | # 1. Backup include/ctype.h and rename include/ctype.h-bootstrap to
|
---|
21 | # include/ctype.h
|
---|
22 | # 2. Run 'make os2', put the resulting library os2.a to emx/lib as _os2.a,
|
---|
23 | # and convert it to .lib with emxomf: 'emxomf _os2.a'
|
---|
24 | # 3. Now compile everything you wish this way: 'make LIBS=-l_os2'
|
---|
25 | #
|
---|
26 |
|
---|
27 | # Build type control variables. You can set them right from command line,
|
---|
28 | # e.g "make MODE=dbg"
|
---|
29 |
|
---|
30 | # Build mode: opt (optimization), dbg (debug)
|
---|
31 | MODE = dbg
|
---|
32 | # Base output directory
|
---|
33 | OUT = out/
|
---|
34 | # Base installation directory
|
---|
35 | INS = out/$(MODE)/install/
|
---|
36 | # CPU type (pretend we are portable ;-)
|
---|
37 | CPU = 386
|
---|
38 | # Name of this makefile
|
---|
39 | ifndef MAKEFILE
|
---|
40 | MAKEFILE = Makefile
|
---|
41 | endif
|
---|
42 |
|
---|
43 | # Actual output directory (referenced with $.)
|
---|
44 | . = $(OUT)$(MODE)/
|
---|
45 |
|
---|
46 | # overrides from the environment.
|
---|
47 | ifdef PATH_OBJ
|
---|
48 | ifndef PATH_OBJD
|
---|
49 | PATH_OBJD := $(shell echo $(PATH_OBJ)|sed 's/^[a-zA-Z]://')
|
---|
50 | endif
|
---|
51 | OUT = $(PATH_OBJD)/emx/
|
---|
52 | INS = $(PATH_OBJD)/builttools/
|
---|
53 | . = $(OUT)
|
---|
54 | endif
|
---|
55 |
|
---|
56 | ifdef BUILD_MODE
|
---|
57 | ifeq ($(BUILD_MODE),RELEASE)
|
---|
58 | MODE = opt
|
---|
59 | endif
|
---|
60 | endif
|
---|
61 |
|
---|
62 | # Check if MODE has a valid value
|
---|
63 | ifneq ($(filter-out /opt/ /dbg/ /prf/,/$(MODE)/),)
|
---|
64 | $(error MODE should have one of the following values: opt, dbg, prf)
|
---|
65 | endif
|
---|
66 |
|
---|
67 | # The object file format to use for tools (emxomf, ld and friends)
|
---|
68 | TOOLFMT.dbg = omf
|
---|
69 | TOOLFMT.opt = omf
|
---|
70 | TOOLFMT.prf = omf
|
---|
71 | TOOLFMT = $(TOOLFMT.$(MODE))
|
---|
72 |
|
---|
73 | # Use ash.exe which is quite fast (comparable to cmd.exe) but has more features
|
---|
74 | SHELL := ash.exe
|
---|
75 |
|
---|
76 | # Source base directory.
|
---|
77 | srcdir := $(shell pwd)
|
---|
78 |
|
---|
79 | # File name extensions
|
---|
80 | # Executable files -- xxx$E
|
---|
81 | E = .exe
|
---|
82 | # DLL files --- xxx$D
|
---|
83 | D = .dll
|
---|
84 | # Library files --- xxx$A
|
---|
85 | A = .$(if $(findstring omf,$(.TKIND)),lib,a)
|
---|
86 |
|
---|
87 | # Use the tool we built.
|
---|
88 | GETTOOL ?= $.$(TOOLFMT)/$1$E
|
---|
89 | # Use the tool we built if present
|
---|
90 | GETTOOL2 ?= `test -f '$.$(TOOLFMT)/$1$E' && echo '$.$(TOOLFMT)/'`$1$E
|
---|
91 |
|
---|
92 | # The C compiler
|
---|
93 | CC = gcc -c -Zmt -fmessage-length=150
|
---|
94 | # The C compiler flags
|
---|
95 | ifndef NO_LOCAL_HEADERS
|
---|
96 | CFLAGS.INC += -Iinclude
|
---|
97 | endif
|
---|
98 | CFLAGS.INC += -Isrc/include
|
---|
99 | CFLAGS = -Wall -Wmissing-prototypes -mstack-arg-probe $(CFLAGS.INC) $(CFLAGS.$(MODE)) $(CFLAGS.KIND)
|
---|
100 | # The additional C compiler flags for different build modes
|
---|
101 | CFLAGS.opt = -g -O3
|
---|
102 | CFLAGS.dbg = -g -DDEBUG
|
---|
103 | CFLAGS.prf = -g -O3 -pg
|
---|
104 | CFLAGS.aout = -Zaout
|
---|
105 | CFLAGS.omf = -Zomf
|
---|
106 | CFLAGS.prof = -pg
|
---|
107 | CFLAGS.log = -DDEBUG_LOGGING
|
---|
108 | # The object files are put in subdirectory objectformat-targetkind,
|
---|
109 | # we decompose object file name back and pick appropiate $CFLAGS
|
---|
110 | CFLAGS.KIND = $(foreach x,$(subst -, ,$(firstword $(subst /, ,$(subst $.,,$@)))),$(CFLAGS.$x))
|
---|
111 | # How to compile a .c file
|
---|
112 | DO.COMPILE.c = $(CC) -std=gnu99 $(strip $(CFLAGS) $1) -o $@ $(srcdir)/$< -I$(dir $<)
|
---|
113 | # '-std=gnu99' doesn't work with '-x assembler-with-cpp', therefor no $(call DO.COMPILE.c).
|
---|
114 | DO.COMPILE.s = $(CC) -x assembler-with-cpp $(strip $(CFLAGS) $1) -o $@ $(srcdir)/$< -I$(dir $<)
|
---|
115 |
|
---|
116 | # The linker
|
---|
117 | LD = gcc
|
---|
118 | # Linker flags
|
---|
119 | LDFLAGS = $(LDFLAGS.$(MODE)) $(LDFLAGS.KIND) -Zmap -Zstack 1024 -Zhigh-mem $(LIBS)
|
---|
120 | LDFLAGS.DLL = $(LDFLAGS) -Zdll
|
---|
121 | # Linker flags for different build modes
|
---|
122 | LDFLAGS.opt = -g -Zcrtdll=c_dll
|
---|
123 | LDFLAGS.prf = -g -Zcrtdll=c_dll -lkProfile -LG:/kTaskMgr/Tree/lib/debug
|
---|
124 | LDFLAGS.dbg = -g
|
---|
125 | LDFLAGS.aout = -Zaout
|
---|
126 | LDFLAGS.omf = -Zomf -Zlinker /PM:VIO -Zlinker /LINENUMBERS
|
---|
127 | LDFLAGS.prof = -pg
|
---|
128 | # Linker flags for different kinds of target
|
---|
129 | LDFLAGS.KIND = $(foreach x,$(subst -, ,$(firstword $(subst /, ,$(subst $.,,$@)))),$(LDFLAGS.$x))
|
---|
130 | # How to link a .exe file
|
---|
131 | DO.LINK.exe = $(LD) $(strip $(LDFLAGS) $(filter-out -l%,$1)) -o $@ $(^O) $(^DEF) $(^LIB) $(filter -l%,$1)
|
---|
132 | # How to link a .dll file
|
---|
133 | DO.LINK.dll = $(LD) $(strip $(LDFLAGS.DLL) $(filter-out -l%,$1)) -o $@ $(^O) $(^DEF) $(^LIB) $(filter -l%,$1)
|
---|
134 |
|
---|
135 | # Pack executables and DLLs right after they are linked
|
---|
136 | # bird: I don't care about space, only performance. So, we will only use
|
---|
137 | # lxlite for stripping and sector aligning.
|
---|
138 | # <rant> My explanation is that anything which is used frequently
|
---|
139 | # enough will be in one of the caches, so unpacking the datasegment
|
---|
140 | # for each new process is a waste of time. The code segment is
|
---|
141 | # shared, data segment is not shared, but must be reloaded page by page
|
---|
142 | # from the executable in new processes.
|
---|
143 | # For further optimzations, we align pages on 4kb boundaries since this
|
---|
144 | # is the JFS block size and thus should be most the efficient unit to read. </rant>
|
---|
145 | # URG! we must not do this for ldstub.bin!
|
---|
146 | ifeq ($(MODE),opt)
|
---|
147 | LXLITE.FLAGS = /F+ /AP:4096 /MRN /MLN /MF1
|
---|
148 | DO.LINK.exe += $(if $(findstring .exe,$@), $(NL)cp $@ $(basename $@).dbg $(NL)lxlite /X /AS $(subst /,\\,$@))
|
---|
149 | DO.LINK.dll += $(NL)cp $@ $(basename $@).dbg $(NL)lxlite $(LXLITE.FLAGS) $(subst /,\\,$@)
|
---|
150 | endif
|
---|
151 |
|
---|
152 | # emxbind tool
|
---|
153 | EMXBIND = $(call GETTOOL2,emxbind)
|
---|
154 | # emxbind flags
|
---|
155 | EMXBINDFLAGS = -bq $(EMXBINDFLAGS.$(MODE))
|
---|
156 | EMXBINDFLAGS.opt = -s
|
---|
157 | EMXBINDFLAGS.prf =
|
---|
158 | EMXBINDFLAGS.dbg =
|
---|
159 | # Flags for emxbind
|
---|
160 | DO.EMXBIND = $(EMXBIND) $(EMXBINDFLAGS) -o $@ $1
|
---|
161 |
|
---|
162 | # The macro assembler
|
---|
163 | ifdef PATH_TOP
|
---|
164 | ASM = $(PATH_TOP)/tools/x86.os2/masm/v6.0/binp/ml.exe -c
|
---|
165 | else
|
---|
166 | ASM = ml -c
|
---|
167 | endif
|
---|
168 | ASMFLAGS = -Cp -W3 -WX -VM -nologo
|
---|
169 | # How to compile an .asm file
|
---|
170 | DO.COMPILE.asm = $(ASM) $(ASMFLAGS) $1 -Fo$@ $<
|
---|
171 |
|
---|
172 | # The tool to create an archive
|
---|
173 | AR = $(if $(findstring .lib,$@), $(call GETTOOL2,emxomfar),ar)
|
---|
174 | ARFLAGS = crs
|
---|
175 | DO.LIBRARY = $(call RM,$@); $(AR) $(ARFLAGS)$1 $@ $(^O)
|
---|
176 |
|
---|
177 | # The tool to extract exports from object files and archives,
|
---|
178 | # removing unused stuff (like empty lines and comments)
|
---|
179 | # and sorting alphabetically (looks nicer).
|
---|
180 | EMXEXP = $(call GETTOOL2,emxexp)
|
---|
181 | EMXEXPFLAGS = -u
|
---|
182 | DO.EMXEXP = $(EMXEXP) $(strip $(EMXEXPFLAGS) $1) | sed -e "/^$$/d" -e "/^ *;/d" | sort -d >>$2
|
---|
183 |
|
---|
184 | # The tool to create import libraries
|
---|
185 | IMPLIB = $(call GETTOOL2,emximp)
|
---|
186 | IMPLIBFLAGS.prof = -m
|
---|
187 | IMPLIBFLAGS.KIND = $(foreach x,$(subst -, ,$(firstword $(subst /, ,$(subst $.,,$@)))),$(IMPLIBFLAGS.$x))
|
---|
188 | DO.IMPLIB = $(IMPLIB) -o $@ $(strip $1 $(IMPLIBFLAGS.KIND)) $(^I)\
|
---|
189 | $(if $(^O),$(NL)$(AR) rs $@ $(^O))
|
---|
190 |
|
---|
191 | # How to create dependencies
|
---|
192 | MAKEDEP = makedep
|
---|
193 | MAKEDEPFLAGS = $(CFLAGS.INC)
|
---|
194 | DO.DEPS = $(MAKEDEP) $(MAKEDEPFLAGS) \
|
---|
195 | -I$(subst $(SPACE), -I,$(sort $(dir $^))) -I$. -p$(@D)/ -c -S -f$@ $^
|
---|
196 |
|
---|
197 | # How to convert an a.out file to the OMF format
|
---|
198 | # Emxomf depends on two libs, we have to detect wethere or not emxomf is built
|
---|
199 | # or not. Unfortunately make isn't up to the job of figuring this out, so we
|
---|
200 | # must use the shell.
|
---|
201 | EMXOMF = $(call GETTOOL2,emxomf)
|
---|
202 | DO.EMXOMF = $(EMXOMF) $(strip $1 -o) $@ $(if $<,$<, $(subst /omf/,/aout/,$(@:.obj=.o)) )
|
---|
203 |
|
---|
204 | # How to copy some file to installation directory
|
---|
205 | # In optimize mode we have to strip the libraries after copying
|
---|
206 | INSTALL=$(call CP,$1,$2)
|
---|
207 | ifeq ($(MODE),opt)
|
---|
208 | INSTALL += $(if $(filter-out %.a,$2),$(NL)strip --strip-debug $2)
|
---|
209 | INSTALL += $(if $(filter-out %.lib,$2),$(NL)emxomf -s $2)
|
---|
210 | endif
|
---|
211 |
|
---|
212 | # How to filter just the object files from $^
|
---|
213 | ^O = $(filter %.o,$^)
|
---|
214 | # Just the .imp files from $^
|
---|
215 | ^I = $(filter %.imp,$^)
|
---|
216 | # How to filter just the .def files from $^
|
---|
217 | ^DEF = $(filter %.def,$^)
|
---|
218 | # How to filter the libraries from $^
|
---|
219 | ^LIB = $(strip $(filter %.a,$^) $(filter %.lib,$^))
|
---|
220 |
|
---|
221 | # A newline
|
---|
222 | define NL
|
---|
223 |
|
---|
224 |
|
---|
225 | endef
|
---|
226 | # Opening and closing brackets (for use inside variable expansions)
|
---|
227 | OB := (
|
---|
228 | CB := )
|
---|
229 | COMMA := ,
|
---|
230 | SPACE := $(EMPTY) $(EMPTY)
|
---|
231 | # Text output separator (cannot begin with '-', echo thinks its a switch)
|
---|
232 | SEP := ==========================================================================
|
---|
233 |
|
---|
234 | # How to remove one or more files without questions
|
---|
235 | RM = rm -f $1
|
---|
236 | # How to remove one or more directories without questions
|
---|
237 | RMDIR = rm -rf $1
|
---|
238 | # How to copy several files to a directory
|
---|
239 | CP = cp $1 $2
|
---|
240 | # Miscelaneous tools
|
---|
241 | MKDIR = mkdir.exe -p $1
|
---|
242 | # How to update a file only if it has been changed
|
---|
243 | UPDATE = (cmp -s $1 $2 || mv -f $1 $2) && rm -f $1
|
---|
244 | # How to touch a file
|
---|
245 | TOUCH = touch $1
|
---|
246 | # Re-build the original string including the ',' between args. Also escape
|
---|
247 | # dollars since otherwise ash would expand them.
|
---|
248 | ECHOIZE = $(subst $$,\$$,$1$(strip $(subst $(SPACE)$(COMMA),$(COMMA),$(foreach x,2 3 4 5 6 7 8 9,$(if $($x),$(COMMA) $($x))))))
|
---|
249 | # How to output a text string (with appended newline)
|
---|
250 | ECHO = echo "$(call ECHOIZE,$1,$2,$3,$4,$5,$6,$7,$8,$9)"
|
---|
251 | # Same but append the text to a file (given with first argument)
|
---|
252 | FECHO = echo "$(call ECHOIZE,$2,$3,$4,$5,$6,$7,$8,$9)" >> "$1"
|
---|
253 | # How to replace the source file extension with a .o extension
|
---|
254 | OBJEXT = $(patsubst %.s,%.o,$(patsubst %.asm,%.o,$(patsubst %.c,%.o,$1)))
|
---|
255 | # Compute object file path given source file path (except the $. prefix)
|
---|
256 | OBJFILE = $(addprefix $(.TKIND.DIR),$(call OBJEXT,$1))
|
---|
257 |
|
---|
258 | #------------ Variables appended by submakefiles ------------
|
---|
259 | # The list of available modules
|
---|
260 | MODULES :=
|
---|
261 | # The help text for module list
|
---|
262 | DO.HELP.MODULES :=
|
---|
263 | # The help about public makefile variables
|
---|
264 | DO.HELP.VARS := $(call ECHO, MODE={dbg|opt|prf} - choose between debug, optimized and profiled build modes.)$(NL)
|
---|
265 | DO.HELP.VARS += $(call ECHO, OBJF={omf|aout} - build object files in omf or a.out format.)$(NL)
|
---|
266 | # The list of work directories needeed for building all targets
|
---|
267 | TARGDIRS :=
|
---|
268 | # Build rules (_@_ replaced by name of generated makefile)
|
---|
269 | RULES :=
|
---|
270 | # The list of dependency files
|
---|
271 | TARGDEPEND :=
|
---|
272 | # The list of installed files
|
---|
273 | INS.FILES :=
|
---|
274 |
|
---|
275 | .PHONY: default help all libs tools clean install install cleandep \
|
---|
276 | cleandepend dep depend depdone
|
---|
277 | .SUFFIXES:
|
---|
278 | .SUFFIXES: .c .cpp .asm .s .o .exe .dll .a .lib .obj
|
---|
279 |
|
---|
280 | # Default target
|
---|
281 | default: help
|
---|
282 |
|
---|
283 | #------------ Submakefiles ------------
|
---|
284 | ifndef SUBMAK
|
---|
285 | SUBMAK := version.smak $(wildcard src/*/*.smak) include/include.smak $(wildcard bsd/*/*.smak) $(wildcard gnu/*/*.smak)
|
---|
286 | endif
|
---|
287 |
|
---|
288 | # include template rules
|
---|
289 | include templates.smak
|
---|
290 |
|
---|
291 | # Include all submakefiles
|
---|
292 | -include $(SUBMAK)
|
---|
293 |
|
---|
294 | # Sort and remove duplicate directories
|
---|
295 | TARGDIRS := $(sort $(TARGDIRS))
|
---|
296 | # Find out which directories are needed for installation
|
---|
297 | INSDIRS := $(sort $(dir $(INS.FILES)))
|
---|
298 |
|
---|
299 | #------------ Global targets ------------
|
---|
300 | help:
|
---|
301 | @$(call ECHO,$(SEP))
|
---|
302 | @$(call ECHO,Welcome to $(PACKAGE) version $(VERSION) build system!)
|
---|
303 | @$(call ECHO,$(COPYRIGHT))
|
---|
304 | @$(call ECHO,To build something, type 'make {target} {vars}', where {target} is one of:)
|
---|
305 | @$(call ECHO, all - build all available modules)
|
---|
306 | @$(call ECHO, {module-name} - build just a particular module)
|
---|
307 | @$(call ECHO, tools - build just the tools)
|
---|
308 | @$(call ECHO, libs - build all libraries)
|
---|
309 | @$(call ECHO, clean - remove all generated files (remove all built files))
|
---|
310 | @$(call ECHO, install - generate a installation tree in $(INS))
|
---|
311 | @$(call ECHO, dep - generate dependency files for all changed targets)
|
---|
312 | @$(call ECHO, cleandep - remove all dependency file)
|
---|
313 | @$(call ECHO,$(SEP))
|
---|
314 | @$(call ECHO,There are a number of variables than can be set in the make)
|
---|
315 | @$(call ECHO,command line to control various aspects of compilation:)
|
---|
316 | @$(DO.HELP.VARS)
|
---|
317 | @$(call ECHO,$(SEP))
|
---|
318 | @$(call ECHO,The following modules are included in this package:)
|
---|
319 | @$(DO.HELP.MODULES)
|
---|
320 | @$(call ECHO,$(SEP))
|
---|
321 |
|
---|
322 | all: $(MODULES)
|
---|
323 |
|
---|
324 | clean:
|
---|
325 | $(call RMDIR,$(OUT))
|
---|
326 |
|
---|
327 | cleandep cleandepend:
|
---|
328 | $(call RM,$(TARGDEPEND))
|
---|
329 |
|
---|
330 | dep depend:
|
---|
331 | @$(MAKE) --no-print-directory BUILD_DEPS=1 depdone
|
---|
332 |
|
---|
333 | depdone:
|
---|
334 | @$(call ECHO,Dependency files succesfully updated)
|
---|
335 |
|
---|
336 | install: all $(INSDIRS) $(INS.FILES)
|
---|
337 |
|
---|
338 | $. $(INSDIRS) $(TARGDIRS):
|
---|
339 | $(call MKDIR,$@)
|
---|
340 |
|
---|
341 | # bird: add rule for forcibly re-generating the rules.
|
---|
342 | rules:
|
---|
343 | @$(call ECHO,smak don't generate rules anylonger!)
|
---|
344 |
|
---|
345 | # The general a.out -> OMF conversion rule for object files
|
---|
346 | $.omf/%.obj:
|
---|
347 | $(call DO.EMXOMF)
|
---|
348 |
|
---|
349 | # The general a.out -> OMF conversion rule for libraries
|
---|
350 | $.omf%.lib:
|
---|
351 | $(call DO.EMXOMF)
|
---|
352 |
|
---|