funcs.mk raw
1 define int_vars
2 #Set defaults for vars which may be overridden per-package
3 $(1)_cc=$$($$($(1)_type)_CC)
4 $(1)_cxx=$$($$($(1)_type)_CXX)
5 $(1)_objc=$$($$($(1)_type)_OBJC)
6 $(1)_objcxx=$$($$($(1)_type)_OBJCXX)
7 $(1)_ar=$$($$($(1)_type)_AR)
8 $(1)_ranlib=$$($$($(1)_type)_RANLIB)
9 $(1)_nm=$$($$($(1)_type)_NM)
10 $(1)_cflags=$$($$($(1)_type)_CFLAGS) \
11 $$($$($(1)_type)_$$(release_type)_CFLAGS) \
12 -pipe -std=$(C_STANDARD)
13 $(1)_cxxflags=$$($$($(1)_type)_CXXFLAGS) \
14 $$($$($(1)_type)_$$(release_type)_CXXFLAGS) \
15 -pipe -std=$(CXX_STANDARD)
16 $(1)_ldflags=$$($$($(1)_type)_LDFLAGS) \
17 $$($$($(1)_type)_$$(release_type)_LDFLAGS) \
18 -L$$($($(1)_type)_prefix)/lib
19 $(1)_cppflags=$$($$($(1)_type)_CPPFLAGS) \
20 $$($$($(1)_type)_$$(release_type)_CPPFLAGS) \
21 -I$$($$($(1)_type)_prefix)/include
22 $(1)_recipe_hash:=
23 endef
24
25 define int_get_all_dependencies
26 $(sort $(foreach dep,$(2),$(2) $(call int_get_all_dependencies,$(1),$($(dep)_dependencies))))
27 endef
28
29 define fetch_file_inner
30 ( mkdir -p $$($(1)_download_dir) && echo Fetching $(3) from $(2) && \
31 $(build_DOWNLOAD) "$$($(1)_download_dir)/$(4).temp" "$(2)/$(3)" && \
32 echo "$(5) $$($(1)_download_dir)/$(4).temp" > $$($(1)_download_dir)/.$(4).hash && \
33 $(build_SHA256SUM) -c $$($(1)_download_dir)/.$(4).hash && \
34 mv $$($(1)_download_dir)/$(4).temp $$($(1)_source_dir)/$(4) && \
35 rm -rf $$($(1)_download_dir) )
36 endef
37
38 define fetch_file
39 ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \
40 $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5)))
41 endef
42
43 # Shell script to create a source tarball in $(1)_source from local directory
44 # $(1)_local_dir instead of downloading remote sources. Tarball is recreated if
45 # any paths in the local directory have a newer mtime, and checksum of the
46 # tarball is saved to $(1)_fetched and returned as output.
47 define fetch_local_dir_sha256
48 if ! [ -f $($(1)_source) ] || [ -n "$$(find $($(1)_local_dir) -newer $($(1)_source) | head -n1)" ]; then \
49 mkdir -p $(dir $($(1)_source)) && \
50 $(build_TAR) -c -f $($(1)_source) -C $($(1)_local_dir) . && \
51 rm -f $($(1)_fetched); \
52 fi && \
53 if ! [ -f $($(1)_fetched) ] || [ -n "$$(find $($(1)_source) -newer $($(1)_fetched))" ]; then \
54 mkdir -p $(dir $($(1)_fetched)) && \
55 cd $($(1)_source_dir) && \
56 $(build_SHA256SUM) $($(1)_all_sources) > $($(1)_fetched); \
57 fi && \
58 cut -d" " -f1 $($(1)_fetched)
59 endef
60
61 define int_get_build_recipe_hash
62 $(eval $(1)_patches_path?=$(PATCHES_PATH)/$(1))
63 $(eval $(1)_all_file_checksums:=$(shell $(build_SHA256SUM) $(meta_depends) packages/$(1).mk $(addprefix $($(1)_patches_path)/,$($(1)_patches)) | cut -d" " -f1))
64 # If $(1)_local_dir is set, create a tarball of the local directory contents to
65 # use as the source of the package, and include a hash of the tarball in the
66 # package id, so if directory contents change, the package and packages
67 # depending on it will be rebuilt.
68 $(if $($(1)_local_dir),$(eval $(1)_sha256_hash:=$(shell $(call fetch_local_dir_sha256,$(1)))))
69 $(if $($(1)_local_dir),$(eval $(1)_all_file_checksums+=$($(1)_sha256_hash)))
70 $(eval $(1)_recipe_hash:=$(shell echo -n "$($(1)_all_file_checksums)" | $(build_SHA256SUM) | cut -d" " -f1))
71 endef
72
73 define int_get_build_id
74 $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies))
75 $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($(1)_dependencies)))
76 $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash)))
77 $(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id))
78 $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)))
79 final_build_id_long+=$($(package)_build_id_long)
80
81 #compute package-specific paths
82 $(1)_staging_dir=$(base_staging_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
83 $(1)_staging_prefix_dir:=$$($(1)_staging_dir)$($($(1)_type)_prefix)
84 $(1)_extract_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)
85 $(1)_build_dir:=$$($(1)_extract_dir)/$$($(1)_build_subdir)
86 $(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz.hash
87 $(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id)
88 $(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz
89 $(1)_build_log:=$(BASEDIR)/$(1)-$($(1)_version)-$($(1)_build_id).log
90 endef
91
92 # Convert a string to a human-readable filename, replacing dot, slash, and space
93 # characters that could cause problems with dashes and collapsing them.
94 define int_friendly_file_name
95 $(subst $(null) $(null),-,$(strip $(subst ., ,$(subst /, ,$(1)))))
96 endef
97
98 define int_get_build_properties
99 $(1)_build_subdir?=.
100 $(1)_download_file?=$($(1)_file_name)
101 $(1)_source_dir:=$(SOURCES_PATH)
102 # If $(1)_file_name is empty and $(1)_local_dir is nonempty, set file name to a
103 # .tar file with a friendly filename named after the directory path.
104 $(if $($(1)_file_name),,$(if $($(1)_local_dir),$(eval $(1)_file_name:=$(call int_friendly_file_name,$($(1)_local_dir)).tar)))
105 $(1)_source:=$$($(1)_source_dir)/$($(1)_file_name)
106 $(1)_download_dir:=$(base_download_dir)/$(1)-$($(1)_version)
107 $(1)_prefixbin:=$($($(1)_type)_prefix)/bin/
108 $(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources)
109
110 #stamps
111 $(1)_fetched=$(SOURCES_PATH)/download-stamps/.stamp_fetched-$(1)-$($(1)_file_name).hash
112 $(1)_extracted=$$($(1)_extract_dir)/.stamp_extracted
113 $(1)_preprocessed=$$($(1)_extract_dir)/.stamp_preprocessed
114 $(1)_cleaned=$$($(1)_extract_dir)/.stamp_cleaned
115 $(1)_built=$$($(1)_build_dir)/.stamp_built
116 $(1)_configured=$(host_prefix)/.$(1)_stamp_configured
117 $(1)_staged=$$($(1)_staging_dir)/.stamp_staged
118 $(1)_postprocessed=$$($(1)_staging_prefix_dir)/.stamp_postprocessed
119 $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path))
120
121
122 #default commands
123 # The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior
124 $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash))
125 $(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source)
126 $(1)_preprocess_cmds ?= true
127 $(1)_build_cmds ?= true
128 $(1)_config_cmds ?= true
129 $(1)_stage_cmds ?= true
130 $(1)_set_vars ?=
131
132
133 all_sources+=$$($(1)_fetched)
134 endef
135 #$(foreach dep_target,$($(1)_all_dependencies),$(eval $(1)_dependency_targets=$($(dep_target)_cached)))
136
137
138 define int_config_attach_build_config
139 $(eval $(call $(1)_set_vars,$(1)))
140 $(1)_cflags+=$($(1)_cflags_$(release_type))
141 $(1)_cflags+=$($(1)_cflags_$(host_arch)) $($(1)_cflags_$(host_arch)_$(release_type))
142 $(1)_cflags+=$($(1)_cflags_$(host_os)) $($(1)_cflags_$(host_os)_$(release_type))
143 $(1)_cflags+=$($(1)_cflags_$(host_arch)_$(host_os)) $($(1)_cflags_$(host_arch)_$(host_os)_$(release_type))
144
145 $(1)_cxxflags+=$($(1)_cxxflags_$(release_type))
146 $(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)) $($(1)_cxxflags_$(host_arch)_$(release_type))
147 $(1)_cxxflags+=$($(1)_cxxflags_$(host_os)) $($(1)_cxxflags_$(host_os)_$(release_type))
148 $(1)_cxxflags+=$($(1)_cxxflags_$(host_arch)_$(host_os)) $($(1)_cxxflags_$(host_arch)_$(host_os)_$(release_type))
149
150 $(1)_cppflags+=$($(1)_cppflags_$(release_type))
151 $(1)_cppflags+=$($(1)_cppflags_$(host_arch)) $($(1)_cppflags_$(host_arch)_$(release_type))
152 $(1)_cppflags+=$($(1)_cppflags_$(host_os)) $($(1)_cppflags_$(host_os)_$(release_type))
153 $(1)_cppflags+=$($(1)_cppflags_$(host_arch)_$(host_os)) $($(1)_cppflags_$(host_arch)_$(host_os)_$(release_type))
154
155 $(1)_ldflags+=$($(1)_ldflags_$(release_type))
156 $(1)_ldflags+=$($(1)_ldflags_$(host_arch)) $($(1)_ldflags_$(host_arch)_$(release_type))
157 $(1)_ldflags+=$($(1)_ldflags_$(host_os)) $($(1)_ldflags_$(host_os)_$(release_type))
158 $(1)_ldflags+=$($(1)_ldflags_$(host_arch)_$(host_os)) $($(1)_ldflags_$(host_arch)_$(host_os)_$(release_type))
159
160 $(1)_build_opts+=$$($(1)_build_opts_$(release_type))
161 $(1)_build_opts+=$$($(1)_build_opts_$(host_arch)) $$($(1)_build_opts_$(host_arch)_$(release_type))
162 $(1)_build_opts+=$$($(1)_build_opts_$(host_os)) $$($(1)_build_opts_$(host_os)_$(release_type))
163 $(1)_build_opts+=$$($(1)_build_opts_$(host_arch)_$(host_os)) $$($(1)_build_opts_$(host_arch)_$(host_os)_$(release_type))
164
165 $(1)_config_opts+=$$($(1)_config_opts_$(release_type))
166 $(1)_config_opts+=$$($(1)_config_opts_$(host_arch)) $$($(1)_config_opts_$(host_arch)_$(release_type))
167 $(1)_config_opts+=$$($(1)_config_opts_$(host_os)) $$($(1)_config_opts_$(host_os)_$(release_type))
168 $(1)_config_opts+=$$($(1)_config_opts_$(host_arch)_$(host_os)) $$($(1)_config_opts_$(host_arch)_$(host_os)_$(release_type))
169
170 $(1)_config_env+=$$($(1)_config_env_$(release_type))
171 $(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_$(release_type))
172 $(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type))
173 $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type))
174
175 $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
176 $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
177 $(1)_config_env+=PKG_CONFIG_SYSROOT_DIR=/
178 $(1)_config_env+=CMAKE_MODULE_PATH=$($($(1)_type)_prefix)/lib/cmake
179 $(1)_config_env+=PATH="$(build_prefix)/bin:$(PATH)"
180 $(1)_build_env+=PATH="$(build_prefix)/bin:$(PATH)"
181 $(1)_stage_env+=PATH="$(build_prefix)/bin:$(PATH)"
182
183 # Setting a --build type that differs from --host will explicitly enable
184 # cross-compilation mode. Note that --build defaults to the output of
185 # config.guess, which is what we set it too here. This also quells autoconf
186 # warnings, "If you wanted to set the --build type, don't use --host.",
187 # when using versions older than 2.70.
188 $(1)_autoconf=./configure --build=$(BUILD) --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) --with-pic $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)"
189 ifneq ($($(1)_nm),)
190 $(1)_autoconf += NM="$$($(1)_nm)"
191 endif
192 ifneq ($($(1)_ranlib),)
193 $(1)_autoconf += RANLIB="$$($(1)_ranlib)"
194 endif
195 ifneq ($($(1)_ar),)
196 $(1)_autoconf += AR="$$($(1)_ar)"
197 endif
198 ifneq ($($(1)_cflags),)
199 $(1)_autoconf += CFLAGS="$$($(1)_cflags)"
200 endif
201 ifneq ($($(1)_cxxflags),)
202 $(1)_autoconf += CXXFLAGS="$$($(1)_cxxflags)"
203 endif
204 ifneq ($($(1)_cppflags),)
205 $(1)_autoconf += CPPFLAGS="$$($(1)_cppflags)"
206 endif
207 ifneq ($($(1)_ldflags),)
208 $(1)_autoconf += LDFLAGS="$$($(1)_ldflags)"
209 endif
210
211 # We hardcode the library install path to "lib" to match the PKG_CONFIG_PATH
212 # setting in depends/toolchain.cmake.in, which also hardcodes "lib".
213 # Without this setting, CMake by default would use the OS library
214 # directory, which might be "lib64" or something else, not "lib", on multiarch systems.
215 $(1)_cmake=env CC="$$($(1)_cc)" \
216 CFLAGS="$$($(1)_cppflags) $$($(1)_cflags)" \
217 CXX="$$($(1)_cxx)" \
218 CXXFLAGS="$$($(1)_cppflags) $$($(1)_cxxflags)" \
219 LDFLAGS="$$($(1)_ldflags)" \
220 cmake -G "Unix Makefiles" \
221 -DCMAKE_INSTALL_PREFIX:PATH="$$($($(1)_type)_prefix)" \
222 -DCMAKE_AR=`which $$($(1)_ar)` \
223 -DCMAKE_NM=`which $$($(1)_nm)` \
224 -DCMAKE_RANLIB=`which $$($(1)_ranlib)` \
225 -DCMAKE_INSTALL_LIBDIR=lib \
226 -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
227 -DCMAKE_VERBOSE_MAKEFILE:BOOL=$(V) \
228 -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY:BOOL=TRUE \
229 $$($(1)_config_opts)
230 ifeq ($($(1)_type),build)
231 $(1)_cmake += -DCMAKE_INSTALL_RPATH:PATH="$$($($(1)_type)_prefix)/lib"
232 else
233 ifneq ($(host),$(build))
234 $(1)_cmake += -DCMAKE_SYSTEM_NAME=$($(host_os)_cmake_system_name)
235 $(1)_cmake += -DCMAKE_C_COMPILER_TARGET=$(host)
236 $(1)_cmake += -DCMAKE_CXX_COMPILER_TARGET=$(host)
237 endif
238 endif
239 endef
240
241 define int_add_cmds
242 ifneq ($(LOG),)
243 $(1)_logging = >>$$($(1)_build_log) 2>&1 || { if test -f $$($(1)_build_log); then cat $$($(1)_build_log); fi; exit 1; }
244 endif
245
246 $($(1)_fetched):
247 mkdir -p $$(@D) $(SOURCES_PATH)
248 rm -f $$@
249 cd $$(@D); $($(1)_fetch_cmds)
250 cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);)
251 touch $$@
252 $($(1)_extracted): | $($(1)_fetched)
253 echo Extracting $(1)...
254 mkdir -p $$(@D)
255 cd $$(@D); $($(1)_extract_cmds)
256 touch $$@
257 $($(1)_preprocessed): | $($(1)_extracted)
258 echo Preprocessing $(1)...
259 mkdir -p $$(@D) $($(1)_patch_dir)
260 $(foreach patch,$($(1)_patches),cd $($(1)_patches_path); cp $(patch) $($(1)_patch_dir) ;)
261 { cd $$(@D); $($(1)_preprocess_cmds); } $$($(1)_logging)
262 touch $$@
263 $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed)
264 echo Configuring $(1)...
265 rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); )
266 mkdir -p $$($(1)_build_dir)
267 +{ cd $$($(1)_build_dir); export $($(1)_config_env); $($(1)_config_cmds); } $$($(1)_logging)
268 touch $$@
269 $($(1)_built): | $($(1)_configured)
270 echo Building $(1)...
271 mkdir -p $$(@D)
272 +{ cd $$(@D); export $($(1)_build_env); $($(1)_build_cmds); } $$($(1)_logging)
273 touch $$@
274 $($(1)_staged): | $($(1)_built)
275 echo Staging $(1)...
276 mkdir -p $($(1)_staging_dir)/$(host_prefix)
277 +{ cd $($(1)_build_dir); export $($(1)_stage_env); $($(1)_stage_cmds); } $$($(1)_logging)
278 rm -rf $($(1)_extract_dir)
279 touch $$@
280 $($(1)_postprocessed): | $($(1)_staged)
281 echo Postprocessing $(1)...
282 cd $($(1)_staging_prefix_dir); $($(1)_postprocess_cmds)
283 touch $$@
284 $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed)
285 echo Caching $(1)...
286 cd $$($(1)_staging_dir)/$(host_prefix); \
287 find . ! -name '.stamp_postprocessed' -print0 | TZ=UTC xargs -0r $(build_TOUCH); \
288 find . ! -name '.stamp_postprocessed' | LC_ALL=C sort | $(build_TAR) --numeric-owner --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T -
289 mkdir -p $$(@D)
290 rm -rf $$(@D) && mkdir -p $$(@D)
291 mv $$($(1)_staging_dir)/$$(@F) $$(@)
292 rm -rf $($(1)_staging_dir)
293 if test -f $($(1)_build_log); then mv $($(1)_build_log) $$(@D); fi
294 $($(1)_cached_checksum): $($(1)_cached)
295 cd $$(@D); $(build_SHA256SUM) $$(<F) > $$(@)
296
297 .PHONY: $(1)
298 $(1): | $($(1)_cached_checksum)
299 .SECONDARY: $($(1)_cached) $($(1)_postprocessed) $($(1)_staged) $($(1)_built) $($(1)_configured) $($(1)_preprocessed) $($(1)_extracted) $($(1)_fetched)
300
301 endef
302
303 stages = fetched extracted preprocessed configured built staged postprocessed cached cached_checksum
304
305 define ext_add_stages
306 $(foreach stage,$(stages),
307 $(1)_$(stage): $($(1)_$(stage))
308 .PHONY: $(1)_$(stage))
309 endef
310
311 # These functions create the build targets for each package. They must be
312 # broken down into small steps so that each part is done for all packages
313 # before moving on to the next step. Otherwise, a package's info
314 # (build-id for example) would only be available to another package if it
315 # happened to be computed already.
316
317 #set the type for host/build packages.
318 $(foreach native_package,$(native_packages),$(eval $(native_package)_type=build))
319 $(foreach package,$(packages),$(eval $(package)_type=$(host_arch)_$(host_os)))
320
321 #set overridable defaults
322 $(foreach package,$(all_packages),$(eval $(call int_vars,$(package))))
323
324 #include package files
325 $(foreach native_package,$(native_packages),$(eval include packages/$(native_package).mk))
326 $(foreach package,$(packages),$(eval include packages/$(package).mk))
327
328 #set build properties for included package files
329 $(foreach package,$(all_packages),$(eval $(call int_get_build_properties,$(package))))
330
331 #compute a hash of all files that comprise this package's build recipe
332 $(foreach package,$(all_packages),$(eval $(call int_get_build_recipe_hash,$(package))))
333
334 #generate a unique id for this package, incorporating its dependencies as well
335 $(foreach package,$(all_packages),$(eval $(call int_get_build_id,$(package))))
336
337 #compute final vars after reading package vars
338 $(foreach package,$(all_packages),$(eval $(call int_config_attach_build_config,$(package))))
339
340 #create build targets
341 $(foreach package,$(all_packages),$(eval $(call int_add_cmds,$(package))))
342