1################################################################################ 2# 3# This file contains various utility functions used by the package 4# infrastructure, or by the packages themselves. 5# 6################################################################################ 7 8# 9# Manipulation of .config files based on the Kconfig 10# infrastructure. Used by the BusyBox package, the Linux kernel 11# package, and more. 12# 13 14# KCONFIG_DOT_CONFIG ([file]) 15# Returns the path to the .config file that should be used, which will 16# be $(1) if provided, or the current package .config file otherwise. 17KCONFIG_DOT_CONFIG = $(strip \ 18 $(if $(strip $(1)), $(1), \ 19 $($(PKG)_BUILDDIR)/$($(PKG)_KCONFIG_DOTCONFIG) \ 20 ) \ 21) 22 23# KCONFIG_MUNGE_DOT_CONFIG (option, newline [, file]) 24define KCONFIG_MUNGE_DOT_CONFIG 25 $(SED) '/^\(# \)\?$(strip $(1))\>/d' $(call KCONFIG_DOT_CONFIG,$(3)) && \ 26 echo '$(strip $(2))' >> $(call KCONFIG_DOT_CONFIG,$(3)) 27endef 28 29# KCONFIG_ENABLE_OPT (option [, file]) 30# If the option is already set to =m or =y, ignore. 31define KCONFIG_ENABLE_OPT 32 $(Q)if ! grep -q '^$(strip $(1))=[my]' $(call KCONFIG_DOT_CONFIG,$(2)); then \ 33 $(call KCONFIG_MUNGE_DOT_CONFIG, $(1), $(1)=y, $(2)); \ 34 fi 35endef 36# KCONFIG_SET_OPT (option, value [, file]) 37KCONFIG_SET_OPT = $(Q)$(call KCONFIG_MUNGE_DOT_CONFIG, $(1), $(1)=$(2), $(3)) 38# KCONFIG_DISABLE_OPT (option [, file]) 39KCONFIG_DISABLE_OPT = $(Q)$(call KCONFIG_MUNGE_DOT_CONFIG, $(1), $(SHARP_SIGN) $(1) is not set, $(2)) 40 41# Helper functions to determine the name of a package and its 42# directory from its makefile directory, using the $(MAKEFILE_LIST) 43# variable provided by make. This is used by the *-package macros to 44# automagically find where the package is located. 45pkgdir = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) 46pkgname = $(lastword $(subst /, ,$(pkgdir))) 47 48# Helper to build the extension for a package archive, based on various 49# conditions. 50# $(1): upper-case package name 51pkg_source_ext = $(BR_FMT_VERSION_$($(1)_SITE_METHOD))$(BR_FMT_VERSION_$($(1)_DOWNLOAD_POST_PROCESS)).tar.gz 52 53# Define extractors for different archive suffixes 54INFLATE.bz2 = $(BZCAT) 55INFLATE.gz = $(ZCAT) 56INFLATE.lz = $(LZCAT) 57INFLATE.lzma = $(XZCAT) 58INFLATE.tbz = $(BZCAT) 59INFLATE.tbz2 = $(BZCAT) 60INFLATE.tgz = $(ZCAT) 61INFLATE.xz = $(XZCAT) 62INFLATE.tar = cat 63# suitable-extractor(filename): returns extractor based on suffix 64suitable-extractor = $(INFLATE$(suffix $(1))) 65 66EXTRACTOR_PKG_DEPENDENCY.lzma = $(BR2_XZCAT_HOST_DEPENDENCY) 67EXTRACTOR_PKG_DEPENDENCY.xz = $(BR2_XZCAT_HOST_DEPENDENCY) 68EXTRACTOR_PKG_DEPENDENCY.lz = $(BR2_LZIP_HOST_DEPENDENCY) 69 70# extractor-pkg-dependency(filename): returns a Buildroot package 71# dependency needed to extract file based on suffix 72extractor-pkg-dependency = $(EXTRACTOR_PKG_DEPENDENCY$(suffix $(1))) 73 74# extractor-system-dependency(filename): returns the name of the tool 75# needed to extract 'filename', and is meant to be used with 76# DL_TOOLS_DEPENDENCIES, in order to check that the necesary tool is 77# provided by the system Buildroot runs on. 78# 79# $(firstword) is used here because the extractor can have arguments, 80# like ZCAT="gzip -d -c", and to check for the dependency we only want 81# 'gzip'. 82extractor-system-dependency = $(if $(EXTRACTOR_PKG_DEPENDENCY$(suffix $(1))),,\ 83 $(firstword $(INFLATE$(suffix $(1))))) 84 85# check-deprecated-variable -- throw an error on deprecated variables 86# example: 87# $(eval $(call check-deprecated-variable,FOO_MAKE_OPT,FOO_MAKE_OPTS)) 88define check-deprecated-variable # (deprecated var, new var) 89ifneq ($$(origin $(1)),undefined) 90$$(error Package error: use $(2) instead of $(1). Please fix your .mk file) 91endif 92endef 93 94# $(1): YES or NO 95define yesno-to-bool 96 $(subst NO,false,$(subst YES,true,$(1))) 97endef 98 99# json-info -- return package or filesystem metadata formatted as an entry 100# of a JSON dictionnary 101# $(1): upper-case package or filesystem name 102define json-info 103 "$($(1)_NAME)": { 104 "type": $(call mk-json-str,$($(1)_TYPE)), 105 $(if $(filter rootfs,$($(1)_TYPE)), \ 106 $(call _json-info-fs,$(1)), \ 107 $(call _json-info-pkg,$(1)), \ 108 ) 109 } 110endef 111 112# _json-info-pkg, _json-info-pkg-details, _json-info-fs: private helpers 113# for json-info, above 114define _json-info-pkg 115 "name": $(call mk-json-str,$($(1)_RAWNAME)), 116 $(if $($(1)_IS_VIRTUAL), \ 117 "virtual": true$(comma), 118 "virtual": false$(comma) 119 $(call _json-info-pkg-details,$(1)) \ 120 ) 121 "stamp_dir": $(call mk-json-str,$(patsubst $(CONFIG_DIR)/%,%,$($(1)_DIR))), 122 "source_dir": $(call mk-json-str,$(patsubst $(CONFIG_DIR)/%,%,$($(1)_DIR))), 123 "build_dir": $(call mk-json-str,$(patsubst $(CONFIG_DIR)/%,%,$($(1)_BUILDDIR))), 124 $(if $(filter target,$($(1)_TYPE)), \ 125 "install_target": $(call yesno-to-bool,$($(1)_INSTALL_TARGET))$(comma) \ 126 "install_staging": $(call yesno-to-bool,$($(1)_INSTALL_STAGING))$(comma) \ 127 "install_images": $(call yesno-to-bool,$($(1)_INSTALL_IMAGES))$(comma) \ 128 ) 129 "dependencies": [ 130 $(call make-comma-list, \ 131 $(foreach dep,$(sort $($(1)_FINAL_ALL_DEPENDENCIES)), \ 132 $(call mk-json-str,$(dep)) \ 133 ) \ 134 ) 135 ], 136 "reverse_dependencies": [ 137 $(call make-comma-list, \ 138 $(foreach dep,$(sort $($(1)_RDEPENDENCIES)), \ 139 $(call mk-json-str,$(dep)) \ 140 ) \ 141 ) 142 ] 143 $(if $($(1)_CPE_ID_VALID), \ 144 $(comma) "cpe-id": $(call mk-json-str,$($(1)_CPE_ID)) \ 145 ) 146 $(if $($(1)_IGNORE_CVES), 147 $(comma) "ignore_cves": [ 148 $(call make-comma-list, \ 149 $(foreach cve,$(sort $($(1)_IGNORE_CVES)), \ 150 $(call mk-json-str,$(cve)) \ 151 ) \ 152 ) 153 ] 154 ) 155endef 156 157define _json-info-pkg-details 158 "version": $(call mk-json-str,$($(1)_DL_VERSION)), 159 "licenses": $(call mk-json-str,$($(1)_LICENSE)), 160 "license_files": [ 161 $(foreach f, $($(1)_LICENSE_FILES),$(call mk-json-str,$(f))$(comma)) 162 ], 163 "redistributable": $(if $(filter NO,$($(1)_REDISTRIBUTE)),false,true), 164 "dl_dir": $(call mk-json-str,$($(1)_DL_SUBDIR)), 165 "downloads": [ 166 $(foreach dl,$(sort $($(1)_ALL_DOWNLOADS)), 167 { 168 "source": $(call mk-json-str,$(notdir $(dl))), 169 "uris": [ 170 $(call make-comma-list, \ 171 $(foreach uri,$(call DOWNLOAD_URIS,$(dl),$(1)), \ 172 $(call mk-json-str,$(subst \|,|,$(uri))) \ 173 ) \ 174 ) 175 ] 176 }, 177 ) 178 ], 179endef 180 181define _json-info-fs 182 "image_name": $(if $($(1)_FINAL_IMAGE_NAME), \ 183 $(call mk-json-str,$($(1)_FINAL_IMAGE_NAME)), \ 184 null \ 185 ), 186 "dependencies": [ 187 $(call make-comma-list, \ 188 $(foreach dep,$(sort $($(1)_DEPENDENCIES)), \ 189 $(call mk-json-str,$(dep)) \ 190 ) \ 191 ) 192 ] 193endef 194 195# clean-json -- cleanup pseudo-json into clean json: 196# - remove commas before closing ] and } 197# - minify with $(strip) 198clean-json = $(strip \ 199 $(subst $(comma)},}, $(subst $(comma)$(space)},$(space)}, \ 200 $(subst $(comma)],], $(subst $(comma)$(space)],$(space)], \ 201 $(strip $(1)) \ 202 )))) \ 203) 204 205# mk-json-str -- escape and double-quote a string to make it a valid json string 206# - escape \ 207# - escape " 208# - escape \n 209# - escape \t 210# - escape ESC 211# - escape SPACE (so that we can $(strip) a JSON blurb without squashing multiple spaces) 212# This unfortunately has to be on a single line... 213mk-json-str = "$(subst $(space),\u0020,$(subst $(escape),\u001b,$(subst $(tab),\t,$(subst $(sep),\n,$(subst ",\",$(subst \,\\,$(1)))))))" 214# )))))" # Syntax colouring 215 216ifeq ($(BR2_PER_PACKAGE_DIRECTORIES),y) 217# rsync the contents of per-package directories 218# $1: space-separated list of packages to rsync from 219# $2: 'host' or 'target' 220# $3: destination directory 221# $4: literal "copy" or "hardlink" to copy or hardlink files from src to dest 222define per-package-rsync 223 mkdir -p $(3) 224 $(foreach pkg,$(1),\ 225 rsync -a \ 226 --hard-links \ 227 $(if $(filter hardlink,$(4)), \ 228 --link-dest=$(PER_PACKAGE_DIR)/$(pkg)/$(2)/, \ 229 $(if $(filter copy,$(4)), \ 230 $(empty), \ 231 $(error per-package-rsync can only "copy" or "hardlink", not "$(4)") \ 232 ) \ 233 ) \ 234 $(PER_PACKAGE_DIR)/$(pkg)/$(2)/ \ 235 $(3)$(sep)) 236endef 237 238# prepares the per-package HOST_DIR and TARGET_DIR of the current 239# package, by rsync the host and target directories of the 240# dependencies of this package. The list of dependencies is passed as 241# argument, so that this function can be used to prepare with 242# different set of dependencies (download, extract, configure, etc.) 243# 244# $1: space-separated list of packages to rsync from 245define prepare-per-package-directory 246 $(call per-package-rsync,$(1),host,$(HOST_DIR),hardlink) 247 $(call per-package-rsync,$(1),target,$(TARGET_DIR),hardlink) 248endef 249 250# Ensure files like .la, .pc, .pri, .cmake, and so on, point to the 251# proper staging and host directories for the current package: find 252# all text files that contain the PPD root, and replace it with the 253# current package's PPD. 254# $1: destination root directory containing host and staging 255define ppd-fixup-paths 256 $(Q)grep --binary-files=without-match -lrZ '$(PER_PACKAGE_DIR)/[^/]\+/' $(HOST_DIR) \ 257 |while read -d '' f; do \ 258 file -b --mime-type "$${f}" | grep -q '^text/' || continue; \ 259 printf '%s\0' "$${f}"; \ 260 done \ 261 |xargs -0 --no-run-if-empty \ 262 $(SED) 's:$(PER_PACKAGE_DIR)/[^/]\+/:$(1)/:g' 263endef 264endif 265 266# 267# legal-info helper functions 268# 269LEGAL_INFO_SEPARATOR = "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" 270 271define legal-warning # text 272 echo "WARNING: $(1)" >>$(LEGAL_WARNINGS) 273endef 274 275define legal-warning-pkg # pkg, text 276 echo "WARNING: $(1): $(2)" >>$(LEGAL_WARNINGS) 277endef 278 279define legal-warning-nosource # pkg, {local|override} 280 $(call legal-warning-pkg,$(1),sources not saved ($(2) packages not handled)) 281endef 282 283define legal-manifest # {HOST|TARGET}, pkg, version, license, license-files, source, url, dependencies 284 echo '"$(2)","$(3)","$(4)","$(5)","$(6)","$(7)","$(8)"' >>$(LEGAL_MANIFEST_CSV_$(1)) 285endef 286 287define legal-license-file # {HOST|TARGET}, pkgname, pkgname-pkgver, filename, file-fullpath, pkg-hashfiles 288 mkdir -p $(LICENSE_FILES_DIR_$(1))/$(3)/$(dir $(4)) && \ 289 { \ 290 support/download/check-hash $(5) $(4) $(6); \ 291 case $${?} in (0|3) ;; (*) exit 1;; esac; \ 292 } && \ 293 cp $(5) $(LICENSE_FILES_DIR_$(1))/$(3)/$(4) 294endef 295 296non-virtual-deps = $(foreach p,$(1),$(if $($(call UPPERCASE,$(p))_IS_VIRTUAL),,$(p))) 297 298# Returns the list of recursive dependencies and their licensing terms 299# for the package specified in parameter (in lowercase). If that 300# package is a target package, remove host packages from the list. 301legal-deps = \ 302 $(foreach p,\ 303 $(filter-out $(if $(1:host-%=),host-%),\ 304 $(call non-virtual-deps,\ 305 $($(call UPPERCASE,$(1))_FINAL_RECURSIVE_DEPENDENCIES))),$(p) [$($(call UPPERCASE,$(p))_LICENSE)]) 306 307# Helper for self-extracting binaries distributed by NXP, and 308# formerlly Freescale. 309# 310# The --force option makes sure it doesn't fail if the source 311# directory already exists. The --auto-accept skips the license check, 312# as it is not needed in Buildroot because we have legal-info. Since 313# there's a EULA in the binary file, we extract it in this macro, and 314# it should therefore be added to the LICENSE_FILES variable of 315# packages using this macro. Also, remember to set REDISTRIBUTE to 316# "NO". Indeed, this is a legal minefield: the EULA specifies that the 317# Board Support Package includes software and hardware (sic!) for 318# which a separate license is needed... 319# 320# $(1): full path to the archive file 321# 322define NXP_EXTRACT_HELPER 323 awk 'BEGIN { start = 0; } \ 324 /^EOEULA/ { start = 0; } \ 325 { if (start) print; } \ 326 /<<EOEULA/ { start = 1; }' \ 327 $(1) > $(@D)/EULA 328 cd $(@D) && sh $(1) --force --auto-accept 329 find $(@D)/$(basename $(notdir $(1))) -mindepth 1 -maxdepth 1 -exec mv {} $(@D) \; 330 rmdir $(@D)/$(basename $(notdir $(1))) 331endef 332