2025年4月28日星期一

openwrt中golang的编译原理,解决版本不兼容问题

 在openwrt中经常出现golang的版本不兼容问题。如何修改,我们需要先搞清楚其原理:

下openwrt的目录下(git clone https://github.com/openwrt/openwrt.git 获得):

下面这个文件是编译golang的配置文件:

feeds/packages/lang/golang/golang/Makefile

在openwrt的编译需要的go是自满足的。就是通过自己编译出go,然后用这个go再编译其他app。无需使用系统(如ubuntu)的go。所以设置系统的go,解决不了openwrt的编译中出现go版本不兼容的问题。

那么openwrt的自编译go的过程是怎么样的呢。

在Makefile中下面这段:
```

GO_VERSION_MAJOR_MINOR:=1.24

GO_VERSION_PATCH:=2


PKG_NAME:=golang

PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH))

PKG_RELEASE:=1


GO_SOURCE_URLS:=https://dl.google.com/go/ \

                https://mirrors.ustc.edu.cn/golang/ \

                https://mirrors.nju.edu.cn/golang/


PKG_SOURCE:=go$(PKG_VERSION).src.tar.gz

PKG_SOURCE_URL:=$(GO_SOURCE_URLS)

PKG_HASH:=9dc77ffadc16d837a1bf32d99c624cb4df0647cee7b119edd9e7b1bcc05f2e00

```

上面这段是指定最后编译的go的版本,PKG_HASH需要和 https://go.dev/dl/ 中的对应。

那么如何编译最后go的版本(该版本用于其他app的编译)。

它是先下载go1.14的基础版本,通过该基础版本编译go.17的版本。然后通过go.17版本再编译go1.20版本。然后通过go1.20版本,再编译go1.23版本。每个版本不能跳跃,因为每个版本的编译都定义了其最低编译其的版本要求。比如上面编译的最终版本go1.24,编译其版本最低是go1.22。

每一个版本,都需要定义其文件的源,如下:
```

BOOTSTRAP_1_17_SOURCE:=go1.17.13.src.tar.gz

BOOTSTRAP_1_17_SOURCE_URL:=$(GO_SOURCE_URLS)

BOOTSTRAP_1_17_HASH:=a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd

BOOTSTRAP_1_17_BUILD_DIR:=$(HOST_BUILD_DIR)/.go_bootstrap_1.17

BOOTSTRAP_1_20_SOURCE:=go1.20.14.src.tar.gz

BOOTSTRAP_1_20_SOURCE_URL:=$(GO_SOURCE_URLS)

BOOTSTRAP_1_20_HASH:=1aef321a0e3e38b7e91d2d7eb64040666cabdcc77d383de3c9522d0d69b67f4e

BOOTSTRAP_1_20_BUILD_DIR:=$(HOST_BUILD_DIR)/.go_bootstrap_1.20

BOOTSTRAP_1_23_SOURCE:=go1.23.8.src.tar.gz

BOOTSTRAP_1_23_SOURCE_URL:=$(GO_SOURCE_URLS)

BOOTSTRAP_1_23_HASH:=0ca1f1e37ea255e3ce283af3f4e628502fb444587da987a5bb96d6c6f15930d4

BOOTSTRAP_1_23_BUILD_DIR:=$(HOST_BUILD_DIR)/.go_bootstrap_1.23

```

当然HASH需要和 https://go.dev/dl/ 中的对应。

这段代码是下载每个源,然后解压:
```

PKG_UNPACK:=$(HOST_TAR) -C "$(PKG_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(PKG_SOURCE)"

HOST_UNPACK:=$(HOST_TAR) -C "$(HOST_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(PKG_SOURCE)"

BOOTSTRAP_UNPACK:=$(HOST_TAR) -C "$(BOOTSTRAP_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(BOOTSTRAP_SOURCE)"

BOOTSTRAP_1_17_UNPACK:=$(HOST_TAR) -C "$(BOOTSTRAP_1_17_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(BOOTSTRAP_1_17_SOURCE)"

BOOTSTRAP_1_20_UNPACK:=$(HOST_TAR) -C "$(BOOTSTRAP_1_20_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(BOOTSTRAP_1_20_SOURCE)"

BOOTSTRAP_1_23_UNPACK:=$(HOST_TAR) -C "$(BOOTSTRAP_1_23_BUILD_DIR)" --strip-components=1 -xzf "$(DL_DIR)/$(BOOTSTRAP_1_23_SOURCE)"

```

定义每一个源的下载:

```

# Bootstrap

BOOTSTRAP_ROOT_DIR:=$(call qstrip,$(CONFIG_GOLANG_EXTERNAL_BOOTSTRAP_ROOT))

ifeq ($(BOOTSTRAP_ROOT_DIR),)

  BOOTSTRAP_ROOT_DIR:=$(BOOTSTRAP_BUILD_DIR)


  define Download/golang-bootstrap

    FILE:=$(BOOTSTRAP_SOURCE)

    URL:=$(BOOTSTRAP_SOURCE_URL)

    HASH:=$(BOOTSTRAP_HASH)

  endef

  $(eval $(call Download,golang-bootstrap))

  define Bootstrap/Prepare

mkdir -p "$(BOOTSTRAP_BUILD_DIR)" && $(BOOTSTRAP_UNPACK) ;

  endef

  Hooks/HostPrepare/Post+=Bootstrap/Prepare

  $(eval $(call GoCompiler/AddProfile,Bootstrap,$(BOOTSTRAP_BUILD_DIR),,bootstrap,$(GO_HOST_OS_ARCH)))

endif

# Bootstrap 1.17

define Download/golang-bootstrap-1.17

  FILE:=$(BOOTSTRAP_1_17_SOURCE)

  URL:=$(BOOTSTRAP_1_17_SOURCE_URL)

  HASH:=$(BOOTSTRAP_1_17_HASH)

endef

$(eval $(call Download,golang-bootstrap-1.17))

define Bootstrap-1.17/Prepare

mkdir -p "$(BOOTSTRAP_1_17_BUILD_DIR)" && $(BOOTSTRAP_1_17_UNPACK) ;

endef

Hooks/HostPrepare/Post+=Bootstrap-1.17/Prepare

$(eval $(call GoCompiler/AddProfile,Bootstrap-1.17,$(BOOTSTRAP_1_17_BUILD_DIR),,bootstrap-1.17,$(GO_HOST_OS_ARCH)))

# Bootstrap 1.20

define Download/golang-bootstrap-1.20

  FILE:=$(BOOTSTRAP_1_20_SOURCE)

  URL:=$(BOOTSTRAP_1_20_SOURCE_URL)

  HASH:=$(BOOTSTRAP_1_20_HASH)

endef

$(eval $(call Download,golang-bootstrap-1.20))

define Bootstrap-1.20/Prepare

mkdir -p "$(BOOTSTRAP_1_20_BUILD_DIR)" && $(BOOTSTRAP_1_20_UNPACK) ;

endef

Hooks/HostPrepare/Post+=Bootstrap-1.20/Prepare

$(eval $(call GoCompiler/AddProfile,Bootstrap-1.20,$(BOOTSTRAP_1_20_BUILD_DIR),,bootstrap-1.20,$(GO_HOST_OS_ARCH)))

# Bootstrap 1.23

define Download/golang-bootstrap-1.23

  FILE:=$(BOOTSTRAP_1_23_SOURCE)

  URL:=$(BOOTSTRAP_1_23_SOURCE_URL)

  HASH:=$(BOOTSTRAP_1_23_HASH)

endef

$(eval $(call Download,golang-bootstrap-1.23))

define Bootstrap-1.23/Prepare

mkdir -p "$(BOOTSTRAP_1_23_BUILD_DIR)" && $(BOOTSTRAP_1_23_UNPACK) ;

endef

Hooks/HostPrepare/Post+=Bootstrap-1.23/Prepare

$(eval $(call GoCompiler/AddProfile,Bootstrap-1.23,$(BOOTSTRAP_1_23_BUILD_DIR),,bootstrap-1.23,$(GO_HOST_OS_ARCH)))

```

下面就是每个go的编译顺序:
```

define Host/Compile

$(call GoCompiler/Bootstrap/Make, \

$(HOST_GO_VARS) \

)

$(call GoCompiler/Bootstrap-1.17/Make, \

GOROOT_BOOTSTRAP="$(BOOTSTRAP_ROOT_DIR)" \

$(HOST_GO_VARS) \

)


$(call GoCompiler/Bootstrap-1.20/Make, \

GOROOT_BOOTSTRAP="$(BOOTSTRAP_1_17_BUILD_DIR)" \

$(HOST_GO_VARS) \

)

$(call GoCompiler/Bootstrap-1.23/Make, \

GOROOT_BOOTSTRAP="$(BOOTSTRAP_1_20_BUILD_DIR)" \

$(HOST_GO_VARS) \

)

$(call GoCompiler/Host/Make, \

GOROOT_BOOTSTRAP="$(BOOTSTRAP_1_23_BUILD_DIR)" \

$(if $(HOST_GO_ENABLE_PIE),GO_LDFLAGS="-buildmode pie") \

$(HOST_GO_VARS) \

)

endef

```

上面就是从go1.14开始编译、go1.17、go1.20、go1.23、go1.24。

最后使用go1.24编译其他app。

没有评论:

发表评论

安装 PaddleOCR的方法

  安装飞桨版本:https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/develop/install/pip/windows-pip.html 命令:  python -m pip...