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>
9 # o use make's built-in rules and variables
10 # (this increases performance and avoid hard-to-debug behavour);
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
19 # =============================================================================
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)
39 # load build configuration
40 -include $(TOP)/.config
43 # =============================================================================
58 .PHONY : all $(SUBDIRS)
59 all : $(SUBDIRS) $(MODULES)
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
79 # =============================================================================
82 # UC: $(call canonicalize, foo-xxx.exe) -> foo_xxx_exe
83 canonicalize = $(subst -,_,$(subst .,_,$1))
85 # handy canonical arguments
86 1C = $(call canonicalize,$1)
87 *C = $(call canonicalize,$*)
88 @C = $(call canonicalize,$@)
92 @C_LINK = $($(@C)_LINK)
94 # $! == eye-candy $@ , $(1!) == eye-candy $1
95 curdir := $(patsubst $(TOP)%,%,$(CURDIR))
96 curdir := $(patsubst /%,%,$(curdir))
97 curdir := $(curdir)$(if $(curdir),/)
104 # filter list items by extension
105 # UC: $(call __filter-ext,.cxx,hello.c abc.C arm.cxx) -> arm.cxx
106 __filter-ext= $(filter %$1,$2)
108 # filter list items by extension, then substiture extension for filtered items
109 # UC: $(call __subst-ext,.c,.o,hello.c abc.cpp) -> hello.o
110 __subst-ext= $(patsubst %$1,%$2,$(call __filter-ext,$1,$3))
112 # C++ has so many extensions ...
113 c++-ext := cpp cxx cc C c++
115 # extract X-sources from sources list
116 # UC: $(call __src-c, hello.c hi.cpp ...) -> hello.c
117 __src-c = $(filter %.c,$1)
118 __src-cxx = $(strip $(foreach ext,$(c++-ext),$(filter %.$(ext),$1)))
119 __src-rc = $(filter %.rc,$1)
120 __src-spec= $(filter %.spec,$1)
122 # extract X-sources from a module
123 # UC: $(call src-c,foo.exe)
124 src-c = $(call __src-c,$(1C_SRC))
125 src-cxx = $(call __src-cxx,$(1C_SRC))
126 src-rc = $(call __src-rc,$(1C_SRC))
127 src-spec= $(call __src-spec,$(1C_SRC))
129 # list of unknown sources for a module
130 # it is an error when this list is not empty
131 src-unknown = $(filter-out $(foreach srctype,c cxx rc spec,$(call src-$(srctype),$1)), $(1C_SRC))
134 # extract X-objects from source list
135 # UC: $(call objs-c, hello.c hi.cpp ...) -> hello.o
136 __objs-c = $(call __subst-ext,.c,.o,$1)
137 __objs-cxx= $(foreach ext,$(c++-ext),$(call __subst-ext,.$(ext),.o,$1))
138 __objs-rc = $(call __subst-ext,.rc,.res,$1)
140 # extract X-objects from a module
141 # UC: objs = $(call objs-c, foo)
142 objs-c = $(call __objs-c,$(1C_SRC))
143 objs-cxx= $(call __objs-cxx,$(1C_SRC))
144 objs-rc = $(call __objs-rc,$(1C_SRC))
147 # Autogen modules templates
150 define MODULE_template
151 $(1C)_SRC_C := $$(call src-c,$1)
152 $(1C)_SRC_CXX := $$(call src-cxx,$1)
153 $(1C)_SRC_RC := $$(call src-rc,$1)
154 $(1C)_SRC_SPEC := $$(call src-spec,$1)
156 $(1C)_OBJS := $(foreach lang,c cxx rc,$$(call objs-$(lang),$1))
158 # link command (C++ programs have to be linked by C++ compiler)
159 $(1C)_LINK := $$(if $$($(1C)_SRC_CXX),$(CXX),$(CC))
161 # explicit dependencies (to keep objects precious)
164 # objects want $(DEPDIR)
165 $$($(1C)_OBJS) : | $(DEPDIR)
167 # include auto-generated dependencies
168 -include $$(foreach obj,$$(basename $$($(1C)_OBJS)),$(DEPDIR)/$$(obj).d)
170 $(1C)_SRC_UNKNOWN:=$$(call src-unknown,$1)
171 __SRC_UNKNOWN += $$($(1C)_SRC_UNKNOWN)
173 $$(call qpretty,CLEAN $(1!))
174 $(Q)$(RM) $$($(1C)_OBJS) $1.so $1
177 $(foreach module,$(MODULES),$(eval $(call MODULE_template,$(module))))
179 # Verify whether all sources provided are of known type
180 __SRC_UNKNOWN := $(strip $(__SRC_UNKNOWN))
181 ifneq "$(__SRC_UNKNOWN)" ""
182 $(error E: Source(s) of unknown type: [ $(__SRC_UNKNOWN) ] )
186 # =============================================================================
189 # Convenient variables
193 space := $(empty) $(empty)
196 # Escape single quote for use in echo statements
197 escsq = $(subst $(squote),'\$(squote)',$1)
200 # Short version is used, if $(quiet) equals `quiet_', otherwise full one.
201 echo-cmd = $(if $($(quiet)cmd_$(1)),\
202 echo ' $(call escsq,$($(quiet)cmd_$(1)))';)
204 # echo pretty string [only in quiet mode]
205 qpretty = $(if $(Q),@echo ' $1')
208 cmd = @$(echo-cmd) $(cmd_$(1))
210 # =============================================================================
213 quiet_cmd_mkdir = MKDIR $!
214 cmd_mkdir = mkdir -p $@
216 # XXX do we need '-MT $@ -MP' here?
217 cc_dep_opts = -MD -MF $(@:%.o=$(DEPDIR)/%.d)
219 quiet_cmd_c_c = CC $!
220 cmd_c_c = $(CC) -c $(CFLAGS) $(CEXTRA) $(DEFINCL) -o $@ $< $(cc_dep_opts)
222 quiet_cmd_cxx_c = C++ $!
223 cmd_cxx_c = $(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $< $(cc_dep_opts)
225 # TODO add dependency generation for RC command
226 quiet_cmd_rc_x = RC $!
227 cmd_rc_x = $(RC) $(RCFLAGS) $(RCEXTRA) $(DEFINCL) -fo$@ $<
240 $(foreach ext,$(c++-ext),$(eval $(call rule_cxx_ext,$(ext))))
246 DEFLIB := $(LIBRARY_PATH) $(LIBRARIES) $(DLL_PATH)
248 quiet_cmd_link_exe = EXE $!
249 cmd_link_exe = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -o $@.so $+ $(DEFLIB) $(DLLS:%=-l%) $(LIBS:%=-l%)
250 cmd_exe_fixup= echo -e '\#!/bin/sh\n\nexec wine $$0.so\n' > $@ && chmod a+x $@
252 quiet_cmd_link_dll = DLL $!
253 cmd_link_dll = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -shared -o $@.so $+ $(DEFLIB) $(DLLS:%=-l%) $(LIBS:%=-l%)
254 cmd_dll_fixup= $(LN_S) $(@F).so $(@D)/$(@F:.so=)
259 $(call cmd,exe_fixup)
261 %.dll : $$($$(@C)_SRC_SPEC)
263 $(call cmd,dll_fixup)