问题描述
我的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 脚本
由于没有其他人会对您的本地克隆进行操作,因此其状态将在整个构建过程中保持一致。