远程存储库获取自定义 buildroot 包的问题

问题描述

我的buildroot环境是从一个名为gitserver1的git服务器下载的:

$ git remote -v
origin git@gitserver1:/platforms/buildroot.git (fetch)

这是包含在 package/company/mypackage/mypackage.mk 中的 buildroot 包的示例

GITHOST = git@gitserver2
GIT_PATH = /packages/mypackage.git
GIT_BRANCH = branch

MYPACKAGE_SITE = $(GITHOST):$(GIT_PATH)
MYPACKAGE_SITE_METHOD = git
MYPACKAGE_VERSION = $(GIT_BRANCH)

MYPACKAGE_PKG_NAME = mypackage
MYPACKAGE_PKG_DIR = $(TOPDIR)/package/company/$(MYPACKAGE_PKG_NAME)
MYPACKAGE_BUILD_DIR = $(BUILD_DIR)/$(MYPACKAGE_PKG_NAME)-$(GIT_BRANCH)

define MYPACKAGE_BUILD_Cmds
    $(MAKE) CC="$(TARGET_CC)" CFLAGS="$(TARGET_CFLAGS)" -C $(@D)
endef

define MYPACKAGE_INSTALL_TARGET_Cmds
    $(INSTALL) -D -m 755 $(@D)/binary $(TARGET_DIR)/usr/bin/
endef

$(MYPACKAGE_PKG_NAME)-clean:
    if test -d $(MYPACKAGE_BUILD_DIR); then make clean -C $(MYPACKAGE_BUILD_DIR); fi

$(MYPACKAGE_PKG_NAME)-dirclean: $(MYPACKAGE_PKG_NAME)-clean
    rm -Rf $(DL_DIR)/$(MYPACKAGE_PKG_NAME)-$(GIT_BRANCH).tar.gz

$(MYPACKAGE_PKG_NAME)-rebuild: $(MYPACKAGE_PKG_NAME)-clean

ifeq ($(BR2_PACKAGE_MYPACKAGE),y)
$(eval $(generic-package))
endif

这个 buildroot 包的源代码是从名为 gitserver2 的不同 git 服务器获取的。此遥控器将用于示例:

$ git remote -v
origin git@gitserver2:/packages/mypackage.git (fetch)

要构建这个 buildroot 包,我输入:

$ make mypackage

内部buildroot过程:

  • 在 BR2_DL_DIR 中下载 mypackage-branch.tar.gz tarball。
  • 创建一个本地目录 output/build/mypackage-branch,其中 tarball 未压缩。

我的目的是获取用于构建 mypackage(用于内部报告)的提交的校验和 ID。使用分支,获取校验和 ID 的唯一方法是让 .git 目录可用。

但是当我检查 output/build 目录中的远程存储库时,我得到远程指向 gitserver1(buildroot .git repo),而不是预期的(gitserver2):

$ git remote -v
origin  git@gitserver1:/platforms/buildroot.git (fetch)

在对这篇文章进行一些回复后,我了解到下载的 tarball 在 output/build/mypackage-branch 中未压缩,并且它不包含 .git 控制信息。因此,当我输入 git remote -v 时,我得到了主存储库 (gitserver1) 而不是用于获取代码的存储库 (gitserver2)。

作为一种解决方法,我在 mypackage.mk 中定义了这个:

define MYPACKAGE_EXTRACT_Cmds
        @$(call MESSAGE,"Extracting $(MYPACKAGE_PKG_NAME) branch $(GIT_BRANCH) from $(GITHOST)")
        rm -f $(MYPACKAGE_BUILD_DIR)/.stamp_downloaded
        git clone -b $(GIT_BRANCH) $(GITHOST):$(GIT_PATH) $(MYPACKAGE_BUILD_DIR)
        touch $(MYPACKAGE_BUILD_DIR)/.stamp_downloaded
endef

现在,一旦构建了包,我就可以在 output/build/mypackage-branch 目录中看到预期的远程服务器(gitserver2):

$ git remote -v
origin  git@gitserver2:/packages/mypackage.git (fetch)

在这里,所有 repo 历史都可用,甚至是用于获取代码的分支的最后一次提交 ID。我使用该信息获取已编译分支的 checksum_ID。

然而,这是一个糟糕的修复。该包被提取两次。我明白这不是正确的方法

你能提出一个更好的方法来获得预期的结果吗?谢谢!

解决方法

Buildroot 将源代码下载到 BR2_DL_DIR 目录。您可以通过在 buildroot BASE_DIR 中搜索来找到 BR2_DL_DIR 目录:

grep BR2_DL_DIR .config

Buildroot 会将一个 repo 克隆到下载目录 (BR2_DL_DIR)。 Buildroot 会将遥控器重置为 buildroot git url。这就是为什么你在你的源包中看到 origin 指向 gitserver1 的原因。

如果您想在开发时更新源代码,有两种方法可以做到。

  • 在您的本地文件系统上进行开发并将站点更改为本地 uri。
  • 在您的 git 存储库中进行开发并将更改推送到 gitserver2。

在任何一种方法中,您都需要删除输出/构建目录,然后重新制作包:

rm -rf output/build/mypackage-branch
make mypackage

在本地uri的情况下,在本地克隆mypackage并像这样设置:

MYPACKAGE_SITE = path/to/mypackage
MYPACKAGE_SITE_METHOD = local

一旦你调试了你的代码,你就可以 git add/commit 和 push。然后将 SITE 改回 git 服务器。所有人都应该按照团队其他成员的预期进行构建。

,

我不知道“buildroot”。

据我所知:您正在使用一个框架来构建您的包。

构建框架来自gitserver1,要构建的代码来自gitserver2,构建的结果放在output/build/mypackage-branch目录中。

如果是这种情况:没有理由将该构建目录放在从 gitserver2 克隆的 repo 下。


您从 git remote -v 运行 output/build/mypackage-branch/,但您没有检查根存储库的位置:

  • 您可以运行 ls .git/ 以确认 output/build/mypackage-branch/ 不是任何存储库的克隆,
  • 运行 git rev-parse --show-toplevel 以查看您正在查看的存储库(我的猜测是:您的根存储库)

如果我正确理解了您的脚本,那么 gitserevr2 中的存储库可能是在 package/company/$(MYPACKAGE_PKG_NAME) 中克隆的。


如果您需要以某种方式比较或将构建工件推回 gitserver2,请花时间更新您的问题并解释您的意图。


[更新,跟随您的编辑]

在不克隆完整存储库的情况下获取分支的 sha1 的一种方法是:

git ls-remote origin refs/heads/$GIT_BRANCH

您遇到的问题是:由于下载 tarball 和获取 sha1 将是不同的操作,因此您需要某种方法来确保 sha1 与 tarball 匹配——例如:如果有人,您就不会混淆else 恰好在构建运行时运行 git push 到远程。

@Matt 在他的回答中提供了一种方法:使用 gitserver2 的本地克隆作为 buildroot 脚本的“远程存储库”。

假设您将 gitserver2:/packages/mypackage.git 的镜像克隆到 path/to/mypackage

git clone --mirror gitserver2:/packages/mypackage.git path/to/mypackage

将您的构建步骤改为:

一个。更新本地镜像:git --git-dir=path/to/mypackage fetch
湾运行你的 buildroot 脚本

由于没有其他人会对您的本地克隆进行操作,因此其状态将在整个构建过程中保持一致。