funcs.mk
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))))