1##
2##  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3##
4##  Use of this source code is governed by a BSD-style license
5##  that can be found in the LICENSE file in the root of the source
6##  tree. An additional intellectual property rights grant can be found
7##  in the file PATENTS.  All contributing project authors may
8##  be found in the AUTHORS file in the root of the source tree.
9##
10
11
12include config.mk
13quiet?=true
14ifeq ($(target),)
15# If a target wasn't specified, invoke for all enabled targets.
16.DEFAULT:
17	@for t in $(ALL_TARGETS); do \
18	     $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\
19        done
20all: .DEFAULT
21clean:: .DEFAULT
22install:: .DEFAULT
23test:: .DEFAULT
24testdata:: .DEFAULT
25
26
27# Note: md5sum is not installed on OS X, but openssl is. Openssl may not be
28# installed on cygwin, so we need to autodetect here.
29md5sum := $(firstword $(wildcard \
30          $(foreach e,md5sum openssl,\
31          $(foreach p,$(subst :, ,$(PATH)),$(p)/$(e)*))\
32          ))
33md5sum := $(if $(filter %openssl,$(md5sum)),$(md5sum) dgst -md5,$(md5sum))
34
35TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN)))
36dist:
37	@for t in $(ALL_TARGETS); do \
38	     $(MAKE) --no-print-directory target=$$t $(MAKECMDGOALS) || exit $$?;\
39        done
40        # Run configure for the user with the current toolchain.
41	@if [ -d "$(DIST_DIR)/src" ]; then \
42            mkdir -p "$(DIST_DIR)/build"; \
43            cd "$(DIST_DIR)/build"; \
44            echo "Rerunning configure $(CONFIGURE_ARGS)"; \
45            ../src/configure $(CONFIGURE_ARGS); \
46            $(if $(filter vs%,$(TGT_CC)),make NO_LAUNCH_DEVENV=1;) \
47        fi
48	@if [ -d "$(DIST_DIR)" ]; then \
49            echo "    [MD5SUM] $(DIST_DIR)"; \
50	    cd $(DIST_DIR) && \
51	    $(md5sum) `find . -name md5sums.txt -prune -o -type f -print` \
52                | sed -e 's/MD5(\(.*\))= \([0-9a-f]\{32\}\)/\2  \1/' \
53                > md5sums.txt;\
54        fi
55
56
57endif
58
59ifneq ($(target),)
60# Normally, we want to build the filename from the target and the toolchain.
61# This disambiguates from the $(target).mk file that exists in the source tree.
62# However, the toolchain is part of the target in universal builds, so we
63# don't want to include TOOLCHAIN in that case. FAT_ARCHS is used to test
64# if we're in the universal case.
65include $(target)$(if $(FAT_ARCHS),,-$(TOOLCHAIN)).mk
66endif
67BUILD_ROOT?=.
68VPATH=$(SRC_PATH_BARE)
69CFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
70CXXFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT) -I$(SRC_PATH)
71ASFLAGS+=-I$(BUILD_PFX)$(BUILD_ROOT)/ -I$(SRC_PATH)/
72DIST_DIR?=dist
73HOSTCC?=gcc
74TGT_ISA:=$(word 1, $(subst -, ,$(TOOLCHAIN)))
75TGT_OS:=$(word 2, $(subst -, ,$(TOOLCHAIN)))
76TGT_CC:=$(word 3, $(subst -, ,$(TOOLCHAIN)))
77quiet:=$(if $(or $(verbose), $(V)),, yes)
78qexec=$(if $(quiet),@)
79
80# Cancel built-in implicit rules
81%: %.o
82%.asm:
83%.a:
84%: %.cc
85
86#
87# Common rules"
88#
89.PHONY: all
90all:
91
92.PHONY: clean
93clean::
94	rm -f $(OBJS-yes) $(OBJS-yes:.o=.d) $(OBJS-yes:.asm.s.o=.asm.s)
95	rm -f $(CLEAN-OBJS)
96
97.PHONY: clean
98distclean: clean
99	if [ -z "$(target)" ]; then \
100      rm -f Makefile; \
101      rm -f config.log config.mk; \
102      rm -f vpx_config.[hc] vpx_config.asm; \
103    else \
104      rm -f $(target)-$(TOOLCHAIN).mk; \
105    fi
106
107.PHONY: dist
108dist:
109.PHONY: install
110install::
111.PHONY: test
112test::
113.PHONY: testdata
114testdata::
115
116# Add compiler flags for intrinsic files
117$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
118$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
119$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
120$(BUILD_PFX)%_sse2.c.o: CFLAGS += -msse2
121$(BUILD_PFX)%_sse3.c.d: CFLAGS += -msse3
122$(BUILD_PFX)%_sse3.c.o: CFLAGS += -msse3
123$(BUILD_PFX)%_ssse3.c.d: CFLAGS += -mssse3
124$(BUILD_PFX)%_ssse3.c.o: CFLAGS += -mssse3
125$(BUILD_PFX)%_sse4.c.d: CFLAGS += -msse4.1
126$(BUILD_PFX)%_sse4.c.o: CFLAGS += -msse4.1
127$(BUILD_PFX)%_avx.c.d: CFLAGS += -mavx
128$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
129$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
130$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
131
132$(BUILD_PFX)%.c.d: %.c
133	$(if $(quiet),@echo "    [DEP] $@")
134	$(qexec)mkdir -p $(dir $@)
135	$(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -M $< | $(fmt_deps) > $@
136
137$(BUILD_PFX)%.c.o: %.c
138	$(if $(quiet),@echo "    [CC] $@")
139	$(qexec)$(CC) $(INTERNAL_CFLAGS) $(CFLAGS) -c -o $@ $<
140
141$(BUILD_PFX)%.cc.d: %.cc
142	$(if $(quiet),@echo "    [DEP] $@")
143	$(qexec)mkdir -p $(dir $@)
144	$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -M $< | $(fmt_deps) > $@
145
146$(BUILD_PFX)%.cc.o: %.cc
147	$(if $(quiet),@echo "    [CXX] $@")
148	$(qexec)$(CXX) $(INTERNAL_CFLAGS) $(CXXFLAGS) -c -o $@ $<
149
150$(BUILD_PFX)%.asm.d: %.asm
151	$(if $(quiet),@echo "    [DEP] $@")
152	$(qexec)mkdir -p $(dir $@)
153	$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
154            --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
155
156$(BUILD_PFX)%.asm.o: %.asm
157	$(if $(quiet),@echo "    [AS] $@")
158	$(qexec)$(AS) $(ASFLAGS) -o $@ $<
159
160$(BUILD_PFX)%.s.d: %.s
161	$(if $(quiet),@echo "    [DEP] $@")
162	$(qexec)mkdir -p $(dir $@)
163	$(qexec)$(SRC_PATH_BARE)/build/make/gen_asm_deps.sh \
164            --build-pfx=$(BUILD_PFX) --depfile=$@ $(ASFLAGS) $< > $@
165
166$(BUILD_PFX)%.s.o: %.s
167	$(if $(quiet),@echo "    [AS] $@")
168	$(qexec)$(AS) $(ASFLAGS) -o $@ $<
169
170.PRECIOUS: %.c.S
171%.c.S: CFLAGS += -DINLINE_ASM
172$(BUILD_PFX)%.c.S: %.c
173	$(if $(quiet),@echo "    [GEN] $@")
174	$(qexec)$(CC) -S $(CFLAGS) -o $@ $<
175
176.PRECIOUS: %.asm.s
177$(BUILD_PFX)%.asm.s: %.asm
178	$(if $(quiet),@echo "    [ASM CONVERSION] $@")
179	$(qexec)mkdir -p $(dir $@)
180	$(qexec)$(ASM_CONVERSION) <$< >$@
181
182# If we're in debug mode, pretend we don't have GNU strip, to fall back to
183# the copy implementation
184HAVE_GNU_STRIP := $(if $(CONFIG_DEBUG),,$(HAVE_GNU_STRIP))
185ifeq ($(HAVE_GNU_STRIP),yes)
186# Older binutils strip global sybols not needed for relocation processing
187# when given --strip-unneeded. Use nm and awk to identify globals and
188# keep them.
189%.a: %_g.a
190	$(if $(quiet),@echo "    [STRIP] $@ < $<")
191	$(qexec)$(STRIP) --strip-unneeded \
192         `$(NM) $< | grep ' [A-TV-Z] ' | awk '{print "-K"$$3'}`\
193          -o $@ $<
194else
195%.a: %_g.a
196	$(if $(quiet),@echo "    [CP] $@ < $<")
197	$(qexec)cp $< $@
198endif
199
200#
201# Rule to extract assembly constants from C sources
202#
203obj_int_extract: build/make/obj_int_extract.c
204	$(if $(quiet),@echo "    [HOSTCC] $@")
205	$(qexec)$(HOSTCC) -I. -I$(SRC_PATH_BARE) -o $@ $<
206CLEAN-OBJS += obj_int_extract
207
208#
209# Utility functions
210#
211pairmap=$(if $(strip $(2)),\
212    $(call $(1),$(word 1,$(2)),$(word 2,$(2)))\
213    $(call pairmap,$(1),$(wordlist 3,$(words $(2)),$(2)))\
214)
215
216enabled=$(filter-out $($(1)-no),$($(1)-yes))
217cond_enabled=$(if $(filter yes,$($(1))), $(call enabled,$(2)))
218
219find_file1=$(word 1,$(wildcard $(subst //,/,$(addsuffix /$(1),$(2)))))
220find_file=$(foreach f,$(1),$(call find_file1,$(strip $(f)),$(strip $(2))) )
221obj_pats=.c=.c.o $(AS_SFX)=$(AS_SFX).o .cc=.cc.o
222objs=$(addprefix $(BUILD_PFX),$(foreach p,$(obj_pats),$(filter %.o,$(1:$(p))) ))
223
224install_map_templates=$(eval $(call install_map_template,$(1),$(2)))
225
226not=$(subst yes,no,$(1))
227
228ifeq ($(CONFIG_MSVS),yes)
229lib_file_name=$(1).lib
230else
231lib_file_name=lib$(1).a
232endif
233#
234# Rule Templates
235#
236define linker_template
237$(1): $(filter-out -%,$(2))
238$(1):
239	$(if $(quiet),@echo    "    [LD] $$@")
240	$(qexec)$$(LD) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs))
241endef
242define linkerxx_template
243$(1): $(filter-out -%,$(2))
244$(1):
245	$(if $(quiet),@echo    "    [LD] $$@")
246	$(qexec)$$(CXX) $$(strip $$(INTERNAL_LDFLAGS) $$(LDFLAGS) -o $$@ $(2) $(3) $$(extralibs))
247endef
248# make-3.80 has a bug with expanding large input strings to the eval function,
249# which was triggered in some cases by the following component of
250# linker_template:
251#   $(1): $$(call find_file, $(patsubst -l%,lib%.a,$(filter -l%,$(2))),\
252#                           $$(patsubst -L%,%,$$(filter -L%,$$(LDFLAGS) $(2))))
253# This may be useful to revisit in the future (it tries to locate libraries
254# in a search path and add them as prerequisites
255
256define install_map_template
257$(DIST_DIR)/$(1): $(2)
258	$(if $(quiet),@echo "    [INSTALL] $$@")
259	$(qexec)mkdir -p $$(dir $$@)
260	$(qexec)cp -p $$< $$@
261endef
262
263define archive_template
264# Not using a pattern rule here because we don't want to generate empty
265# archives when they are listed as a dependency in files not responsible
266# for creating them.
267$(1):
268	$(if $(quiet),@echo "    [AR] $$@")
269	$(qexec)$$(AR) $$(ARFLAGS) $$@ $$?
270endef
271
272define so_template
273# Not using a pattern rule here because we don't want to generate empty
274# archives when they are listed as a dependency in files not responsible
275# for creating them.
276#
277# This needs further abstraction for dealing with non-GNU linkers.
278$(1):
279	$(if $(quiet),@echo "    [LD] $$@")
280	$(qexec)$$(LD) -shared $$(LDFLAGS) \
281            -Wl,--no-undefined -Wl,-soname,$$(SONAME) \
282            -Wl,--version-script,$$(EXPORTS_FILE) -o $$@ \
283            $$(filter %.o,$$^) $$(extralibs)
284endef
285
286define dl_template
287# Not using a pattern rule here because we don't want to generate empty
288# archives when they are listed as a dependency in files not responsible
289# for creating them.
290$(1):
291	$(if $(quiet),@echo "    [LD] $$@")
292	$(qexec)$$(LD) -dynamiclib $$(LDFLAGS) \
293	    -exported_symbols_list $$(EXPORTS_FILE) \
294        -Wl,-headerpad_max_install_names,-compatibility_version,1.0,-current_version,$$(VERSION_MAJOR) \
295        -o $$@ \
296        $$(filter %.o,$$^) $$(extralibs)
297endef
298
299
300
301define lipo_lib_template
302$(1): $(addsuffix /$(1),$(FAT_ARCHS))
303	$(if $(quiet),@echo "    [LIPO] $$@")
304	$(qexec)libtool -static -o $$@ $$?
305endef
306
307define lipo_bin_template
308$(1): $(addsuffix /$(1),$(FAT_ARCHS))
309	$(if $(quiet),@echo "    [LIPO] $$@")
310	$(qexec)lipo -output $$@ -create $$?
311endef
312
313
314#
315# Get current configuration
316#
317ifneq ($(target),)
318include $(SRC_PATH_BARE)/$(target:-$(TOOLCHAIN)=).mk
319endif
320ifeq ($(filter %clean,$(MAKECMDGOALS)),)
321  # Older versions of make don't like -include directives with no arguments
322  ifneq ($(filter %.d,$(OBJS-yes:.o=.d)),)
323    -include $(filter %.d,$(OBJS-yes:.o=.d))
324  endif
325endif
326
327#
328# Configuration dependent rules
329#
330$(call pairmap,install_map_templates,$(INSTALL_MAPS))
331
332DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,DOCS)
333.docs: $(DOCS)
334	@touch $@
335
336INSTALL-DOCS=$(call cond_enabled,CONFIG_INSTALL_DOCS,INSTALL-DOCS)
337ifeq ($(MAKECMDGOALS),dist)
338INSTALL-DOCS+=$(call cond_enabled,CONFIG_INSTALL_DOCS,DIST-DOCS)
339endif
340.install-docs: .docs $(addprefix $(DIST_DIR)/,$(INSTALL-DOCS))
341	@touch $@
342
343clean::
344	rm -f .docs .install-docs $(DOCS)
345
346BINS=$(call enabled,BINS)
347.bins: $(BINS)
348	@touch $@
349
350INSTALL-BINS=$(call cond_enabled,CONFIG_INSTALL_BINS,INSTALL-BINS)
351ifeq ($(MAKECMDGOALS),dist)
352INSTALL-BINS+=$(call cond_enabled,CONFIG_INSTALL_BINS,DIST-BINS)
353endif
354.install-bins: .bins $(addprefix $(DIST_DIR)/,$(INSTALL-BINS))
355	@touch $@
356
357clean::
358	rm -f .bins .install-bins $(BINS)
359
360LIBS=$(call enabled,LIBS)
361.libs: $(LIBS)
362	@touch $@
363$(foreach lib,$(filter %_g.a,$(LIBS)),$(eval $(call archive_template,$(lib))))
364$(foreach lib,$(filter %so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH),$(LIBS)),$(eval $(call so_template,$(lib))))
365$(foreach lib,$(filter %$(VERSION_MAJOR).dylib,$(LIBS)),$(eval $(call dl_template,$(lib))))
366
367INSTALL-LIBS=$(call cond_enabled,CONFIG_INSTALL_LIBS,INSTALL-LIBS)
368ifeq ($(MAKECMDGOALS),dist)
369INSTALL-LIBS+=$(call cond_enabled,CONFIG_INSTALL_LIBS,DIST-LIBS)
370endif
371.install-libs: .libs $(addprefix $(DIST_DIR)/,$(INSTALL-LIBS))
372	@touch $@
373
374clean::
375	rm -f .libs .install-libs $(LIBS)
376
377ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
378PROJECTS=$(call enabled,PROJECTS)
379.projects: $(PROJECTS)
380	@touch $@
381
382INSTALL-PROJECTS=$(call cond_enabled,CONFIG_INSTALL_PROJECTS,INSTALL-PROJECTS)
383ifeq ($(MAKECMDGOALS),dist)
384INSTALL-PROJECTS+=$(call cond_enabled,CONFIG_INSTALL_PROJECTS,DIST-PROJECTS)
385endif
386.install-projects: .projects $(addprefix $(DIST_DIR)/,$(INSTALL-PROJECTS))
387	@touch $@
388
389clean::
390	rm -f .projects .install-projects $(PROJECTS)
391endif
392
393# If there are any source files to be distributed, then include the build
394# system too.
395ifneq ($(call enabled,DIST-SRCS),)
396    DIST-SRCS-yes            += configure
397    DIST-SRCS-yes            += build/make/configure.sh
398    DIST-SRCS-yes            += build/make/gen_asm_deps.sh
399    DIST-SRCS-yes            += build/make/Makefile
400    DIST-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_def.sh
401    DIST-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_proj.sh
402    DIST-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_sln.sh
403    DIST-SRCS-$(CONFIG_MSVS)  += build/make/gen_msvs_vcxproj.sh
404    DIST-SRCS-$(CONFIG_MSVS)  += build/x86-msvs/obj_int_extract.bat
405    DIST-SRCS-$(CONFIG_MSVS)  += build/arm-msvs/obj_int_extract.bat
406    DIST-SRCS-$(CONFIG_RVCT) += build/make/armlink_adapter.sh
407    # Include obj_int_extract if we use offsets from *_asm_*_offsets
408    DIST-SRCS-$(ARCH_ARM)$(ARCH_X86)$(ARCH_X86_64)    += build/make/obj_int_extract.c
409    DIST-SRCS-$(ARCH_ARM)    += build/make/ads2gas.pl
410    DIST-SRCS-$(ARCH_ARM)    += build/make/ads2gas_apple.pl
411    DIST-SRCS-$(ARCH_ARM)    += build/make/ads2armasm_ms.pl
412    DIST-SRCS-$(ARCH_ARM)    += build/make/thumb.pm
413    DIST-SRCS-yes            += $(target:-$(TOOLCHAIN)=).mk
414endif
415INSTALL-SRCS := $(call cond_enabled,CONFIG_INSTALL_SRCS,INSTALL-SRCS)
416ifeq ($(MAKECMDGOALS),dist)
417INSTALL-SRCS += $(call cond_enabled,CONFIG_INSTALL_SRCS,DIST-SRCS)
418endif
419.install-srcs: $(addprefix $(DIST_DIR)/src/,$(INSTALL-SRCS))
420	@touch $@
421
422clean::
423	rm -f .install-srcs
424
425ifeq ($(CONFIG_EXTERNAL_BUILD),yes)
426    BUILD_TARGETS += .projects
427    INSTALL_TARGETS += .install-projects
428endif
429BUILD_TARGETS += .docs .libs .bins
430INSTALL_TARGETS += .install-docs .install-srcs .install-libs .install-bins
431all: $(BUILD_TARGETS)
432install:: $(INSTALL_TARGETS)
433dist: $(INSTALL_TARGETS)
434test::
435