1# Disable built-in makefile rules for all apps to avoid pointless file-system
2# scanning and general weirdness resulting from implicit rules.
3MAKEFLAGS += --no-builtin-rules
4.SUFFIXES:
5
6HALIDE_DISTRIB_PATH ?= $(realpath ../../distrib)
7ifeq (,$(HALIDE_DISTRIB_PATH))
8$(error Could not find a Halide distribution. Before building an app, run "make distrib" at the root level, or set HALIDE_DISTRIB_PATH to the root of an existing Halide distribution)
9endif
10
11LDFLAGS ?=
12IMAGES ?= ../images
13UNAME ?= $(shell uname)
14SHELL = bash
15PYTHON ?= python3
16
17# TODO(srj): the python bindings need to be put into the distrib folders;
18# this is a hopefully-temporary workaround (https://github.com/halide/Halide/issues/4368)
19HALIDE_PYTHON_BINDINGS_PATH ?= $(realpath ../../bin/python3_bindings)
20
21BIN_DIR ?= bin
22
23# Most build outputs go into $(BIN)/$(HL_TARGET)/$(HL_TARGET)/, so that you can vary the test
24# and/or benchmark output easily by changing HL_TARGET and not have to worry
25# about cleaning the output (e.g. to add different GPU or SIMD features).
26BIN ?= $(BIN_DIR)
27HL_TARGET ?= host
28
29
30# GENERATOR_BIN is used mainly for Generators, which are always built
31# (and executed) on the host, regardless of the final target; this saves a bit
32# of recompile time (and disk space). (It would still provide correct results
33# if we output them to $(BIN), it would just be inefficient.)
34GENERATOR_BIN ?= $(BIN)/host
35
36SANITIZER_FLAGS ?=
37
38# The outputs to produce when running a Generator (ie the args to the -e flag).
39# If -e is unspecified, Halide normally defaults to the equivalent of
40# `-e static_library,h,registration`; we add assembly and stmt to the 'default'
41# outputs for the apps, since it makes casual inspection of the Generator output
42# easier to inspect and experiment with. (Production build systems wouldn't
43# normally do this, as it would just waste cycles and storage.)
44GENERATOR_OUTPUTS ?= static_library,h,registration,stmt,assembly
45
46# This pulls in the definition of HALIDE_SYSTEM_LIBS and HALIDE_RTTI
47include $(HALIDE_DISTRIB_PATH)/halide_config.make
48
49LDFLAGS += -ldl -lpthread -lz
50
51CXX ?= g++
52GXX ?= g++
53
54OPTIMIZE ?= -O3
55
56CFLAGS += $(OPTIMIZE) -I $(HALIDE_DISTRIB_PATH)/include/ -I $(HALIDE_DISTRIB_PATH)/tools/ -I $(HALIDE_DISTRIB_PATH)/apps/support/
57CXXFLAGS += $(OPTIMIZE) -std=c++11 -I $(HALIDE_DISTRIB_PATH)/include/ -I $(HALIDE_DISTRIB_PATH)/tools/ $(SANITIZER_FLAGS) -Wall -Werror -Wno-unused-function -Wcast-qual -Wignored-qualifiers -Wno-comment -Wsign-compare -Wno-unknown-warning-option -Wno-psabi
58
59CXX_VERSION = $(shell $(CXX) --version | head -n1)
60ifneq (,$(findstring clang,$(CXX_VERSION)))
61CXXFLAGS += $(findstring -stdlib=libc++, $(HALIDE_LLVM_CXX_FLAGS))
62endif
63
64ifeq (0, $(HALIDE_RTTI))
65CXXFLAGS += -fno-rtti
66endif
67
68ifeq ($(UNAME), Darwin)
69CXXFLAGS += -fvisibility=hidden
70endif
71
72ifeq ($(UNAME), Linux)
73USE_EXPORT_DYNAMIC=-rdynamic
74else
75ifeq ($(UNAME), Darwin)
76USE_EXPORT_DYNAMIC=-undefined dynamic_lookup
77else
78USE_EXPORT_DYNAMIC=
79endif
80endif
81
82ifeq ($(UNAME), Darwin)
83SHARED_EXT=dylib
84else
85SHARED_EXT=so
86endif
87
88# To run apps on android that support this, build a separate toolchain from the Android NDK
89# using the make-standalone-toolchain.sh script:
90#$ build/tools/make-standalone-toolchain.sh --arch=arm64 --platform=android-21 --install-dir=$ANDROID_ARM64_TOOLCHAIN
91#$ build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --install-dir=$ANDROID_ARM_TOOLCHAIN
92CXX-host ?= $(CXX)
93CXX-host-opencl ?= $(CXX)
94CXX-host-opengl ?= $(CXX)
95CXX-host-cuda ?= $(CXX)
96CXX-host-metal ?= $(CXX)
97CXX-host-hvx_128 ?= $(CXX)
98CXX-host-hvx_64 ?= $(CXX)
99CXX-$(HL_TARGET) ?= $(CXX)
100CXX-arm-64-android ?= $(ANDROID_ARM64_TOOLCHAIN)/bin/aarch64-linux-android-c++
101CXX-arm-32-android ?= $(ANDROID_ARM_TOOLCHAIN)/bin/arm-linux-androideabi-c++
102
103CXXFLAGS-host ?= $(CXXFLAGS)
104CXXFLAGS-host-opencl ?= $(CXXFLAGS)
105CXXFLAGS-host-opengl ?= $(CXXFLAGS)
106CXXFLAGS-host-cuda ?= $(CXXFLAGS)
107CXXFLAGS-host-metal ?= $(CXXFLAGS)
108CXXFLAGS-host-hvx_128 ?= $(CXXFLAGS)
109CXXFLAGS-host-hvx_64 ?= $(CXXFLAGS)
110CXXFLAGS-$(HL_TARGET) ?= $(CXXFLAGS)
111CXXFLAGS-arm-64-android ?= $(CXXFLAGS)
112CXXFLAGS-arm-32-android ?= $(CXXFLAGS)
113
114LDFLAGS-host ?= $(LDFLAGS)
115LDFLAGS-host-opencl ?= $(LDFLAGS)
116LDFLAGS-host-opengl ?= $(LDFLAGS)
117LDFLAGS-host-cuda ?= $(LDFLAGS)
118LDFLAGS-host-metal ?= $(LDFLAGS)
119LDFLAGS-host-hvx_128 ?= $(LDFLAGS)
120LDFLAGS-host-hvx_64 ?= $(LDFLAGS)
121LDFLAGS-$(HL_TARGET) ?= $(LDFLAGS)
122LDFLAGS-arm-64-android ?= -llog -fPIE -pie
123LDFLAGS-arm-32-android ?= -llog -fPIE -pie
124
125LIB_HALIDE_STATIC = $(HALIDE_DISTRIB_PATH)/lib/libHalide.a
126
127LIB_HALIDE = $(HALIDE_DISTRIB_PATH)/bin/libHalide.$(SHARED_EXT)
128
129GENERATOR_DEPS ?= $(LIB_HALIDE) $(HALIDE_DISTRIB_PATH)/include/Halide.h $(HALIDE_DISTRIB_PATH)/tools/GenGen.cpp
130GENERATOR_DEPS_STATIC ?= $(LIB_HALIDE_STATIC) $(HALIDE_DISTRIB_PATH)/include/Halide.h $(HALIDE_DISTRIB_PATH)/tools/GenGen.cpp
131
132# Generators which use autoscheduler plugin need to specify the linker where to find libHalide.so required by the plugin.
133LIBHALIDE_LDFLAGS ?= -Wl,-rpath,$(dir $(LIB_HALIDE)) -L $(dir $(LIB_HALIDE)) -lHalide $(LDFLAGS)
134LIBHALIDE_LDFLAGS_STATIC ?=  -L $(dir $(LIB_HALIDE_STATIC)) -lHalide $(LDFLAGS)
135
136LIBPNG_LIBS_DEFAULT = $(shell libpng-config --ldflags)
137LIBPNG_CXX_FLAGS ?= $(shell libpng-config --cflags)
138# Workaround for libpng-config pointing to 64-bit versions on linux even when we're building for 32-bit
139ifneq (,$(findstring -m32,$(CXX)))
140ifneq (,$(findstring x86_64,$(LIBPNG_LIBS_DEFAULT)))
141LIBPNG_LIBS ?= -lpng
142endif
143endif
144LIBPNG_LIBS ?= $(LIBPNG_LIBS_DEFAULT)
145
146# Workaround brew Cellar path for libpng-config output.
147LIBJPEG_LINKER_PATH ?= $(shell echo $(LIBPNG_LIBS_DEFAULT) | sed -e'/-L.*[/][Cc]ellar[/]libpng/!d;s=\(.*\)/[Cc]ellar/libpng/.*=\1/lib=')
148LIBJPEG_LIBS ?= $(LIBJPEG_LINKER_PATH) -ljpeg
149
150# There's no libjpeg-config, unfortunately. We should look for
151# jpeglib.h one directory level up from png.h . Also handle
152# Mac OS brew installs where libpng-config returns paths
153# into the PNG cellar.
154LIBPNG_INCLUDE_DIRS = $(filter -I%,$(LIBPNG_CXX_FLAGS))
155LIBJPEG_CXX_FLAGS ?= $(shell echo $(LIBPNG_INCLUDE_DIRS) | sed -e'/[Cc]ellar[/]libpng/!s=\(.*\)=\1/..=;s=\(.*\)/[Cc]ellar/libpng/.*=\1/include=')
156
157IMAGE_IO_LIBS = $(LIBPNG_LIBS) $(LIBJPEG_LIBS)
158IMAGE_IO_CXX_FLAGS = $(LIBPNG_CXX_FLAGS) $(LIBJPEG_CXX_FLAGS)
159
160IMAGE_IO_FLAGS = $(IMAGE_IO_LIBS) $(IMAGE_IO_CXX_FLAGS)
161
162PLATFORM_OPENGL_LDFLAGS=-lGL -lX11
163ifeq ($(UNAME), Darwin)
164PLATFORM_OPENGL_LDFLAGS=-framework OpenGL
165endif
166
167ifneq (, $(findstring opengl,$(HL_TARGET)))
168  OPENGL_LDFLAGS=$(PLATFORM_OPENGL_LDFLAGS)
169endif
170
171ifneq (, $(findstring metal,$(HL_TARGET)))
172  LDFLAGS += -framework Metal -framework Foundation
173endif
174
175# Utility to convert raw video -> h264. HL_AVCONV=ffmpeg will work too.
176HL_AVCONV ?= avconv
177
178# Utility to show h264 video
179HL_VIDEOPLAYER ?= mplayer
180
181# ------- RunGen/Benchmark support
182
183# Really, .SECONDARY is what we want instead of .PRECIOUS (here and elsewhere),
184# but .SECONDARY doesn't accept wildcards
185.PRECIOUS: $(BIN)/%.registration.cpp
186$(BIN)/%.registration.cpp: $(BIN)/%.a
187	@echo $@ produced implicitly by $^
188
189.PRECIOUS: $(BIN)/%/RunGenMain.o
190$(BIN)/%/RunGenMain.o: $(HALIDE_DISTRIB_PATH)/tools/RunGenMain.cpp $(HALIDE_DISTRIB_PATH)/tools/RunGen.h
191	@mkdir -p $(@D)
192	$(CXX) -c $< $(CXXFLAGS) -fno-exceptions $(IMAGE_IO_CXX_FLAGS) -I$(BIN)/$* -o $@
193
194.PRECIOUS: $(BIN)/%.rungen
195$(BIN)/%.rungen: $(BIN)/%/RunGenMain.o $(BIN)/%.a $(BIN)/%.registration.cpp
196	$(CXX) $(CXXFLAGS) $^ -o $@ $(IMAGE_IO_FLAGS) $(LDFLAGS)
197
198RUNARGS ?=
199
200# Pseudo target that allows us to build-and-run in one step, e.g.
201#
202#     make bin/host/foo.run RUNARGS='input=a output=baz'
203#
204.PHONY: $(BIN)/%.run
205$(BIN)/%.run: $(BIN)/%.rungen
206	@$(CURDIR)/$< $(RUNARGS)
207
208# Also allow 'foo.run' as a shortcut to mean host
209.PHONY: %.run
210%.run: $(BIN)/host/%.rungen
211	@$(CURDIR)/$< $(RUNARGS)
212
213.PHONY: %.benchmark
214%.benchmark: $(BIN)/$(HL_TARGET)/%.rungen
215	@$^ --benchmarks=all --estimate_all --parsable_output
216
217