kumquat-buildroot/package/pkg-download.mk
Yann E. MORIN 29df0eb414 package/pkg-download: use _DL_SUBDIR as root dir of generated archives
Currently, when we generate archives, e.g.  for git, svn, cargo or go, we
use the package _BASENAME_RAW as the root directory of the generated
archive.  For example, for package foo at version 1.2.3, that would generate
an archive rooted at foo-1.2.3/.

This is usually what we want, except in one specific condition: when the
package shares its download with another package *and* it is a generated
archive. In that case, the root directory will be different for each of
the two packages, which is incorrect, but was so far benign: we never
had any hash for such generated archives, and they were only generated
in two cases:
  - linux and linux-headers
  - barebox and barebox-aux

As we skip one directory depth when extracting the archives, we did not
care what the root directory was; whether it was that of one package or
the other was of no consequence.

But now that we can have hashes for archives generated from custom
versions, this breaks the usual case where the headers used for the
toolchains are those of the kernel to build for the target. In this
case, we may end up downloading the linux-headers package before we
download the linux package, so we'd get the hash for an archive rooted
at linux-headers-XXX/, but the one for the linux package the archive
would be rooted at linux-XXX/, or we may end up (e.g. with parallel
builds) downloading the linux package first and linux-headers next.

That would cause conflicts in hashes, as demonstrated by the only defconfig
we have in that situation, olimex_stmp157_olinuxino_lime_defconfig.

_BASENAME_RAW is a construct that is expanded to include the RAWNAME
followed by a dash and the version, if there is a version, or with just
the RAWNAME when there is no version.

We tweak the download macro to use _DL_SUBDIR followed by the version.

This is only used by VCS backends (cvs, git, svn...) and so there will
always be a version string, so no need to duplicate the case without a
version like is done for _BASENAME_RAW

_DL_SUBDIR defaults to _RAWNAME, so this is a noop by default, unless
the package declares it shares its download with another one, in which
case the generated archive will now be rooted as for the shared package.

This was triggered by:
    https://patchwork.ozlabs.org/project/buildroot/patch/20240602070634.597337-1-francois.perrad@gadz.org/

Reported-by: Peter Korsgaard <peter@korsgaard.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Francois Perrad <francois.perrad@gadz.org>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
(cherry picked from commit ebe238f2b5)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2024-06-08 19:56:23 +02:00

130 lines
4.6 KiB
Makefile

################################################################################
#
# This file contains the download helpers for the various package
# infrastructures. It is used to handle downloads from HTTP servers,
# FTP servers, Git repositories, Subversion repositories, Mercurial
# repositories, Bazaar repositories, and SCP servers.
#
################################################################################
# Download method commands
export WGET := $(call qstrip,$(BR2_WGET))
export SVN := $(call qstrip,$(BR2_SVN))
export CVS := $(call qstrip,$(BR2_CVS))
export BZR := $(call qstrip,$(BR2_BZR))
export GIT := $(call qstrip,$(BR2_GIT))
export HG := $(call qstrip,$(BR2_HG))
export SCP := $(call qstrip,$(BR2_SCP))
export SFTP := $(call qstrip,$(BR2_SFTP))
export LOCALFILES := $(call qstrip,$(BR2_LOCALFILES))
# Version of the format of the archives we generate in the corresponding
# download backend:
BR_FMT_VERSION_git = -br1
BR_FMT_VERSION_svn = -br3
DL_WRAPPER = support/download/dl-wrapper
# DL_DIR may have been set already from the environment
ifeq ($(origin DL_DIR),undefined)
DL_DIR ?= $(call qstrip,$(BR2_DL_DIR))
ifeq ($(DL_DIR),)
DL_DIR := $(TOPDIR)/dl
endif
else
# Restore the BR2_DL_DIR that was overridden by the .config file
BR2_DL_DIR = $(DL_DIR)
endif
# ensure it exists and a absolute path, derefrecing symlinks
DL_DIR := $(shell mkdir -p $(DL_DIR) && cd $(DL_DIR) >/dev/null && pwd -P)
#
# URI scheme helper functions
# Example URIs:
# * http://www.example.com/dir/file
# * scp://www.example.com:dir/file (with domainseparator :)
#
# geturischeme: http
geturischeme = $(firstword $(subst ://, ,$(call qstrip,$(1))))
# getschemeplusuri: git|parameter+http://example.com
getschemeplusuri = $(call geturischeme,$(1))$(if $(2),\|$(2))+$(1)
# stripurischeme: www.example.com/dir/file
stripurischeme = $(lastword $(subst ://, ,$(call qstrip,$(1))))
# domain: www.example.com
domain = $(firstword $(subst $(call domainseparator,$(2)), ,$(call stripurischeme,$(1))))
# notdomain: dir/file
notdomain = $(patsubst $(call domain,$(1),$(2))$(call domainseparator,$(2))%,%,$(call stripurischeme,$(1)))
#
# default domainseparator is /, specify alternative value as first argument
domainseparator = $(if $(1),$(1),/)
# github(user,package,version): returns site of GitHub repository
github = https://github.com/$(1)/$(2)/archive/$(3)
# gitlab(user,package,version): returns site of Gitlab-generated tarball
gitlab = https://gitlab.com/$(1)/$(2)/-/archive/$(3)
# Expressly do not check hashes for those files
BR_NO_CHECK_HASH_FOR =
################################################################################
# DOWNLOAD_URIS - List the candidates URIs where to get the package from:
# 1) BR2_PRIMARY_SITE if enabled
# 2) Download site, unless BR2_PRIMARY_SITE_ONLY is set
# 3) BR2_BACKUP_SITE if enabled, unless BR2_PRIMARY_SITE_ONLY is set
#
# Argument 1 is the source location
# Argument 2 is the upper-case package name
#
################################################################################
ifneq ($(call qstrip,$(BR2_PRIMARY_SITE)),)
DOWNLOAD_URIS += \
$(call getschemeplusuri,$(call qstrip,$(BR2_PRIMARY_SITE)/$($(2)_DL_SUBDIR)),urlencode) \
$(call getschemeplusuri,$(call qstrip,$(BR2_PRIMARY_SITE)),urlencode)
endif
ifeq ($(BR2_PRIMARY_SITE_ONLY),)
DOWNLOAD_URIS += \
$(patsubst %/,%,$(dir $(call qstrip,$(1))))
ifneq ($(call qstrip,$(BR2_BACKUP_SITE)),)
DOWNLOAD_URIS += \
$(call getschemeplusuri,$(call qstrip,$(BR2_BACKUP_SITE)/$($(2)_DL_SUBDIR)),urlencode) \
$(call getschemeplusuri,$(call qstrip,$(BR2_BACKUP_SITE)),urlencode)
endif
endif
################################################################################
# DOWNLOAD -- Download helper. Will call DL_WRAPPER which will try to download
# source from the list returned by DOWNLOAD_URIS.
#
# Argument 1 is the source location
# Argument 2 is the upper-case package name
# Argument 3 is a space-separated list of optional arguments
#
################################################################################
define DOWNLOAD
$(Q)mkdir -p $($(2)_DL_DIR)
$(Q)$(EXTRA_ENV) $($(2)_DL_ENV) \
BR_NO_CHECK_HASH_FOR="$(if $(BR2_DOWNLOAD_FORCE_CHECK_HASHES),,$(BR_NO_CHECK_HASH_FOR))" \
flock $($(2)_DL_DIR)/.lock $(DL_WRAPPER) \
-c '$($(2)_DL_VERSION)' \
-d '$($(2)_DL_DIR)' \
-D '$(DL_DIR)' \
-f '$(notdir $(1))' \
$(foreach f,$($(2)_HASH_FILES),-H '$(f)') \
-n '$($(2)_DL_SUBDIR)-$($(2)_VERSION)' \
-N '$($(2)_RAWNAME)' \
-o '$($(2)_DL_DIR)/$(notdir $(1))' \
$(if $(filter YES,$($(2)_SVN_EXTERNALS)),-r) \
$(if $($(2)_GIT_SUBMODULES),-r) \
$(if $($(2)_GIT_LFS),-l) \
$(foreach uri,$(call DOWNLOAD_URIS,$(1),$(2)),-u $(uri)) \
$(3) \
$(QUIET) \
-- \
$($(2)_DL_OPTS)
endef