.gitignore += vim swap files
[winelib-gnu-make.git] / Winemake.include
blob796529864ef32ec16d5943dc758d9b4656b032d9
1 # =============================================================================
2 # GNU make based build system for Winelib applications
3 # Some of ideas taken from Kbuild, Wine build system & Automake
5 # Started: 2007 Kirill Smelkov <kirr@mns.spb.ru>
8 # Do not:
9 # o  use make's built-in rules and variables
10 #    (this increases performance and avoid hard-to-debug behavior);
11 # o  print "Entering directory ...";
12 # XXX As it is, MAKEFLAGS affects only the next-level invocations of make.
13 # XXX At least .SUFFIXES: clear built-in rules for top-level.
14 MAKEFLAGS += -rR --no-print-directory
16 # Do not use built-in rules
17 .SUFFIXES:
19 # =============================================================================
20 # Config
21 CC      := winegcc
22 CXX     := wineg++
23 RC      := wrc
25 RM      := rm -f
26 LN_S    := ln -sf
28 DEPDIR  := .deps
30 ifeq ($(MAKELEVEL),0)
31 export TOP := $(CURDIR)
33 # hook winemake into make's path, so Makefiles in subdirectories can just do
34 # 'include Winemake.include'
35 winemake_root:= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
36 MAKEFLAGS += -I $(winemake_root)
37 endif
39 # load build configuration
40 -include $(TOP)/.config
43 # =============================================================================
44 # Build internals
46 # quiet/verbose
47 V       ?= 0
48 ifneq ($(V),0)
49   quiet :=
50   Q     :=
51 else
52   quiet := quiet_
53   Q     := @
54 endif
57 # Main goal
58 .PHONY  : all $(SUBDIRS)
59 all     : $(SUBDIRS) $(MODULES)
61 $(SUBDIRS):
62         $(Q)$(MAKE) -C $@
64 # Rules for cleaning
65 CLEAN_FILES     = y.tab.c y.tab.h lex.yy.c core *.orig *.rej \
66                   \\\#*\\\# *~ *% .\\\#*
68 clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
69         $(call qpretty,CLEAN   $(if $(curdir),$(curdir),.))
70         $(Q)$(RM) $(CLEAN_FILES)
71         $(Q)$(RM) -R $(DEPDIR)
73 $(SUBDIRS:%=%/__clean__): FORCE
74         $(Q)$(MAKE) -C $(dir $@) clean
77 .PHONY  : FORCE
79 help    : FORCE
80         @echo  '*****************************************'
81         @echo  '* Winelib/GNU Make build system -- help *'
82         @echo  '*****************************************'
83         @echo  ''
84         @echo  'Build setup'
85         @echo  '-----------'
86         @echo  ''
87         @echo  'Build setup should be done in `.config` file.'
88         @echo  ''
89         @echo  ''
90         @echo  'Targets'
91         @echo  '-------'
92         @echo  ''
93         @echo  '  clean           - Clean source tree'
94         @echo  '  all             - Build software'
95         @echo  ''
96         @echo  '  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
98 # =============================================================================
100 # canonicalize a name
101 # UC: $(call canonicalize, foo-xxx.exe)  ->  foo_xxx_exe
102 canonicalize = $(subst -,_,$(subst .,_,$1))
104 # handy canonical arguments
105 1C      = $(call canonicalize,$1)
106 *C      = $(call canonicalize,$*)
107 @C      = $(call canonicalize,$@)
109 # handy variables
110 1C_SRC  = $($(1C)_SRC)
111 @C_LINK = $($(@C)_LINK)
113 # $! == eye-candy $@ , $(1!) == eye-candy $1
114 curdir  := $(patsubst $(TOP)%,%,$(CURDIR))
115 curdir  := $(patsubst /%,%,$(curdir))
116 curdir  := $(curdir)$(if $(curdir),/)
117 !       = $(curdir)$@
118 1!      = $(curdir)$1
121 # Utils
123 # filter list items by extension
124 # UC: $(call __filter-ext,.cxx,hello.c abc.C arm.cxx)  ->  arm.cxx
125 __filter-ext= $(filter %$1,$2)
127 # filter list items by extension, then substitute extension for filtered items
128 # UC: $(call __subst-ext,.c,.o,hello.c abc.cpp)  ->  hello.o
129 __subst-ext= $(patsubst %$1,%$2,$(call __filter-ext,$1,$3))
131 # C++ has so many extensions ...
132 c++-ext   := cpp cxx cc C c++
134 # extract X-sources from sources list
135 # UC: $(call __src-c, hello.c hi.cpp ...)  ->  hello.c
136 __src-c   = $(filter %.c,$1)
137 __src-cxx = $(strip $(foreach ext,$(c++-ext),$(filter %.$(ext),$1)))
138 __src-rc  = $(filter %.rc,$1)
139 __src-spec= $(filter %.spec,$1)
141 # extract X-sources from a module
142 # UC: $(call src-c,foo.exe)
143 src-c   = $(call __src-c,$(1C_SRC))
144 src-cxx = $(call __src-cxx,$(1C_SRC))
145 src-rc  = $(call __src-rc,$(1C_SRC))
146 src-spec= $(call __src-spec,$(1C_SRC))
148 # list of unknown sources for a module
149 # it is an error when this list is not empty
150 src-unknown = $(filter-out $(foreach srctype,c cxx rc spec,$(call src-$(srctype),$1)), $(1C_SRC))
153 # extract X-objects from source list
154 # UC: $(call objs-c, hello.c hi.cpp ...)  ->  hello.o
155 __objs-c  = $(call __subst-ext,.c,.o,$1)
156 __objs-cxx= $(foreach ext,$(c++-ext),$(call __subst-ext,.$(ext),.o,$1))
157 __objs-rc = $(call __subst-ext,.rc,.res,$1)
159 # extract X-objects from a module
160 # UC: objs = $(call objs-c, foo)
161 objs-c  = $(call __objs-c,$(1C_SRC))
162 objs-cxx= $(call __objs-cxx,$(1C_SRC))
163 objs-rc = $(call __objs-rc,$(1C_SRC))
166 # Autogen modules templates
167 __SRC_UNKNOWN   :=
169 define MODULE_template
170 $(1C)_SRC_C     := $$(call src-c,$1)
171 $(1C)_SRC_CXX   := $$(call src-cxx,$1)
172 $(1C)_SRC_RC    := $$(call src-rc,$1)
173 $(1C)_SRC_SPEC  := $$(call src-spec,$1)
175 $(1C)_OBJS      := $(foreach lang,c cxx rc,$$(call objs-$(lang),$1))
177 # link command (C++ programs have to be linked by C++ compiler)
178 $(1C)_LINK      := $$(if $$($(1C)_SRC_CXX),$(CXX),$(CC))
180 # explicit dependencies (to keep objects precious)
181 $1      : $$($(1C)_OBJS)
183 # objects want $(DEPDIR)
184 $$($(1C)_OBJS)  : | $(DEPDIR)
186 # include auto-generated dependencies
187 -include $$(foreach obj,$$(basename $$($(1C)_OBJS)),$(DEPDIR)/$$(obj).d)
189 $(1C)_SRC_UNKNOWN:=$$(call src-unknown,$1)
190 __SRC_UNKNOWN   += $$($(1C)_SRC_UNKNOWN)
191 clean::
192         $$(call qpretty,CLEAN   $(1!))
193         $(Q)$(RM) $$($(1C)_OBJS) $1.so $1
194 endef
196 $(foreach module,$(MODULES),$(eval $(call MODULE_template,$(module))))
198 # Verify whether all sources provided are of known type
199 __SRC_UNKNOWN   := $(strip $(__SRC_UNKNOWN))
200 ifneq "$(__SRC_UNKNOWN)" ""
201 $(error E: Source(s) of unknown type: [ $(__SRC_UNKNOWN) ] )
202 endif
205 # =============================================================================
206 # Common
208 # Convenient variables
209 comma   := ,
210 squote  := '
211 empty   :=
212 space   := $(empty) $(empty)
215 # Escape single quote for use in echo statements
216 escsq = $(subst $(squote),'\$(squote)',$1)
218 # echo command.
219 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
220 echo-cmd = $(if $($(quiet)cmd_$(1)),\
221         echo '  $(call escsq,$($(quiet)cmd_$(1)))';)
223 # echo pretty string [only in quiet mode]
224 qpretty = $(if $(Q),@echo '  $1')
226 # printing commands
227 cmd     = @$(echo-cmd) $(cmd_$(1))
229 # =============================================================================
230 # Rules
232 quiet_cmd_mkdir = MKDIR   $!
233       cmd_mkdir = mkdir -p $@
235 # XXX do we need '-MT $@ -MP' here?
236 cc_dep_opts     = -MD -MF $(@:%.o=$(DEPDIR)/%.d)
238 quiet_cmd_c_c   = CC      $!
239       cmd_c_c   = $(CC) -c $(CFLAGS) $(CEXTRA) $(CPPFLAGS) $(INCLUDES:%=-I%) -o $@ $<  $(cc_dep_opts)
241 quiet_cmd_cxx_c = C++     $!
242       cmd_cxx_c = $(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(CPPFLAGS) $(INCLUDES:%=-I%) -o $@ $<  $(cc_dep_opts)
244 # TODO add dependency generation for RC command
245 quiet_cmd_rc_x  = RC      $!
246       cmd_rc_x  = $(RC) $(RCFLAGS) $(RCEXTRA) $(INCLUDES:%=-I%) -fo$@ $<
249 $(DEPDIR):
250         $(call cmd,mkdir)
252 %.o     : %.c
253         $(call cmd,c_c)
255 define rule_cxx_ext
256 %.o     : %.$1
257         $$(call cmd,cxx_c)
258 endef
259 $(foreach ext,$(c++-ext),$(eval $(call rule_cxx_ext,$(ext))))
261 %.res   : %.rc
262         $(call cmd,rc_x)
265 DEFLIB  := $(LIBRARY_PATH) $(LIBRARIES) $(DLL_PATH)
267 quiet_cmd_link_exe = EXE     $!
268       cmd_link_exe = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -o $@.so $+       \
269                      $(DEFLIB) $(DLLS:%=-l%) $(DLLS_DELAY:%=-l%) $(DLLS_DELAY:%=-Wb,-d%) $(LIBS:%=-l%)
270       cmd_exe_fixup= echo -e '\#!/bin/sh\n\nexec wine $$0.so\n' > $@    && chmod a+x $@
272 quiet_cmd_link_dll = DLL     $!
273       cmd_link_dll = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -shared -o $@.so $+       \
274                      $(DEFLIB) $(DLLS:%=-l%) $(DLLS_DELAY:%=-l%) $(DLLS_DELAY:%=-Wb,-d%) $(LIBS:%=-l%)
275       cmd_dll_fixup= $(LN_S) $(@F).so $(@D)/$(@F:.so=)
277 .SECONDEXPANSION:
278 %.exe   :
279         $(call cmd,link_exe)
280         $(call cmd,exe_fixup)
282 %.dll   : $$($$(@C)_SRC_SPEC)
283         $(call cmd,link_dll)
284         $(call cmd,dll_fixup)
287 # vim: filetype=make