国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

這篇具有很好參考價(jià)值的文章主要介紹了【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

在現(xiàn)代計(jì)算機(jī)系統(tǒng)中,X86和ARM64是兩種常見的處理器架構(gòu)。為了滿足不同架構(gòu)的需求,Docker鏡像也需要支持雙架構(gòu)編包形式。本文將介紹Docker鏡像雙架構(gòu)編包統(tǒng)一的實(shí)踐

? ? 一、Docker鏡像編包

? ??在Docker鏡像中,通常使用多階段構(gòu)建來實(shí)現(xiàn)。在第一階段,構(gòu)建出對(duì)應(yīng)架構(gòu)服務(wù)的二進(jìn)制文件;在第二階段,運(yùn)行對(duì)應(yīng)架構(gòu)的二進(jìn)制文件,下面是兩個(gè)基于Debian的Dockerfile文件示例,分別用于構(gòu)建X86架構(gòu)和ARM64架構(gòu)的Docker鏡像:

1.X86架構(gòu)的Dockerfile文件示例:

FROM debian:latest AS builder

RUN apt-get update && apt-get install -y build-essential

WORKDIR /app

COPY . .

RUN make

FROM debian:latest

WORKDIR /app

COPY --from=builder /app/app /app

CMD ["/app/app/install.sh"]

CMD ["/app/app/build.sh"]

復(fù)制

?2.ARM64架構(gòu)的Dockerfile文件示例:

FROM arm64v8/debian:latest AS builder

RUN apt-get update && apt-get install -y build-essential

WORKDIR /app

COPY . .

RUN make

FROM arm64v8/debian:latest

WORKDIR /app

COPY --from=builder /app/app /app

CMD ["/app/app/install_arm.sh"]

CMD ["/app/app/build_arm.sh"]

復(fù)制

? ? ? 這兩個(gè)Dockerfile文件的主要區(qū)別在于基礎(chǔ)鏡像的選擇和FROM語句中的架構(gòu)標(biāo)識(shí)符。X86架構(gòu)的Dockerfile文件使用了debian:latest作為基礎(chǔ)鏡像,而ARM64架構(gòu)的Dockerfile文件使用了arm64v8/debian:latest作為基礎(chǔ)鏡像。此外,ARM64架構(gòu)的Dockerfile文件在FROM語句中使用了arm64v8標(biāo)識(shí)符,以指定ARM64架構(gòu)。最后,CMD執(zhí)行的安裝腳本也不一樣,應(yīng)該是不同的環(huán)境需要不同的安裝腳本。

? ? 為了方便在雙架構(gòu)環(huán)境下部署Docker服務(wù),可以編寫一個(gè)bash腳本,以執(zhí)行docker build命令的形式來調(diào)用上面兩種Dockerfile文件的運(yùn)行。下面是兩個(gè)示例bash腳本:

1.X86的bash腳本

#!/bin/bash

docker build -t myapp:x86 -f Dockerfile.x86 .

docker manifest create myapp:latest myapp:x86

docker manifest push myapp:latest

復(fù)制

2.Arm64的bash腳本

#!/bin/bash

docker build -t myapp:arm64 -f Dockerfile.arm64 .

docker manifest create myapp:latest myapp:arm64

docker manifest push myapp:latest

復(fù)制

? ? ? 這個(gè)bash腳本中,首先使用docker build命令分別構(gòu)建X86架構(gòu)和ARM64架構(gòu)的Docker鏡像,并分別打上myapp:x86和myapp:arm64的標(biāo)簽。然后,使用docker manifest create命令創(chuàng)建一個(gè)名為myapp:latest的manifest文件,并將myapp:x86和myapp:arm64的標(biāo)簽添加到manifest文件中。最后,使用docker manifest push命令將manifest文件推送到Docker Hub上,以便在不同架構(gòu)的計(jì)算機(jī)系統(tǒng)上使用myapp:latest標(biāo)簽來獲取Docker鏡像。

具體流程大概是這樣:

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

? ? 二、Docker鏡像多架構(gòu)編包統(tǒng)一

從上面的流程圖中,可以看到,編譯雙架構(gòu)的鏡像基本上需要兩套完全獨(dú)立的腳本,這顯然會(huì)增加代碼量和維護(hù)成本,那么有沒有可以統(tǒng)一多架構(gòu)編包的腳本和流程內(nèi)?答案是顯然的,下面就以上面的流程為例,生成一套多架構(gòu)統(tǒng)一的編譯腳本集。

1.合并build_docker.sh腳本

首先是編鏡像的啟動(dòng)腳本build_docker.sh,這里之所以有兩個(gè)腳本,是因?yàn)橐獔?zhí)行不同的dockerfile,事實(shí)上,可以通過傳入?yún)?shù)的形式,來動(dòng)態(tài)決定執(zhí)行不同的dockersfile,比如下面這個(gè)示例:

#!/bin/bash

# 獲取傳入的架構(gòu)參數(shù)
ARCH=$1

# 根據(jù)不同的架構(gòu)參數(shù),構(gòu)建不同的Dockerfile文件
case $ARCH in
  "x86_64")
    DOCKERFILE="Dockerfile.x86_64"
    ;;
  "armv7l")
    DOCKERFILE="Dockerfile.armv7l"
    ;;
  "aarch64")
    DOCKERFILE="Dockerfile.aarch64"
    ;;
  *)
    echo "Unsupported architecture: $ARCH"
    exit 1
    ;;
esac

# 構(gòu)建Docker鏡像
docker build -t myimage:$ARCH -f $DOCKERFILE .

復(fù)制

?當(dāng)然,如果業(yè)務(wù)本身已經(jīng)有很多參數(shù)了,問了避免混淆和命令層級(jí)的一致性,也可以使用opt的別名進(jìn)行,比如:

#!/bin/bash

# 默認(rèn)架構(gòu)為x86_64
ARCH="x86_64"

# 處理命令行參數(shù)
while getopts "a:" opt; do
  case $opt in
    a)
      ARCH=$OPTARG
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

# 根據(jù)不同的架構(gòu)參數(shù),構(gòu)建不同的Dockerfile文件
case $ARCH in
  "x86_64")
    DOCKERFILE="Dockerfile.x86_64"
    ;;
  "armv7l")
    DOCKERFILE="Dockerfile.armv7l"
    ;;
  "aarch64")
    DOCKERFILE="Dockerfile.aarch64"
    ;;
  *)
    echo "Unsupported architecture: $ARCH"
    exit 1
    ;;
esac

# 構(gòu)建Docker鏡像
docker build -t myimage:$ARCH -f $DOCKERFILE .

復(fù)制

?這里有個(gè)優(yōu)雅的點(diǎn):如果沒有指定-a選項(xiàng),則默認(rèn)使用x86_64架構(gòu),方便與已有編譯腳本的融合和兼容。如果傳入的架構(gòu)參數(shù)不支持,腳本會(huì)輸出錯(cuò)誤信息并退出。

當(dāng)然,業(yè)務(wù)需要可能是一次編譯多個(gè)架構(gòu),那還需要對(duì)這個(gè)腳本再更新一下:

#!/bin/bash

# 默認(rèn)架構(gòu)為x86_64
ARCHS=("x86_64")

# 處理命令行參數(shù)
while getopts "a:" opt; do
  case $opt in
    a)
      ARCHS+=("$OPTARG")
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

# 如果有兩個(gè)以上的架構(gòu)參數(shù),則同時(shí)構(gòu)建多個(gè)Docker鏡像
if [ ${#ARCHS[@]} -ge 2 ]; then
  # 構(gòu)建Docker鏡像
  docker buildx build --platform "${ARCHS[@]/#/--platform }" -t myimage .
else
  # 只有一個(gè)架構(gòu)參數(shù),則按照之前的方式構(gòu)建Docker鏡像
  ARCH=${ARCHS[0]}
  # 根據(jù)不同的架構(gòu)參數(shù),構(gòu)建不同的Dockerfile文件
  case $ARCH in
    "x86_64")
      DOCKERFILE="Dockerfile.x86_64"
      ;;
    "armv7l")
      DOCKERFILE="Dockerfile.armv7l"
      ;;
    "aarch64")
      DOCKERFILE="Dockerfile.aarch64"
      ;;
    *)
      echo "Unsupported architecture: $ARCH"
      exit 1
      ;;
  esac

  # 構(gòu)建Docker鏡像
  docker build -t myimage:$ARCH -f $DOCKERFILE .
fi

復(fù)制

這里涉及到--platform的使用,對(duì)應(yīng)的dockerfile為:

FROM --platform=$BUILDPLATFORM golang:1.14 as builder

復(fù)制

事實(shí)上,還有其他的dockerfile命令可以用

架構(gòu)相關(guān)變量

Dockerfile 支持如下架構(gòu)相關(guān)的變量

TARGETPLATFORM

構(gòu)建鏡像的目標(biāo)平臺(tái),例如 linux/amd64, linux/arm/v7, windows/amd64。

TARGETOS

TARGETPLATFORM 的 OS 類型,例如 linux, windows

TARGETARCH

TARGETPLATFORM 的架構(gòu)類型,例如 amd64, arm

TARGETVARIANT

TARGETPLATFORM 的變種,該變量可能為空,例如 v7

BUILDPLATFORM

構(gòu)建鏡像主機(jī)平臺(tái),例如 linux/amd64

BUILDOS

BUILDPLATFORM 的 OS 類型,例如 linux

BUILDARCH

BUILDPLATFORM 的架構(gòu)類型,例如 amd64

BUILDVARIANT

BUILDPLATFORM 的變種,該變量可能為空,例如 v7

那么通過這三種方式,做到了build_docker.sh腳本的統(tǒng)一

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

2.合并dockerfile文件

剛才,主要解決了build_docker.sh的合并統(tǒng)一,現(xiàn)在還要解決dockfile文件的一致的問題

在剛才的build_docker腳本中使用

docker build或者

docker buildx build --platform的命令運(yùn)行dockerfile文件

這里由于dockerfile文件需要根據(jù)不同的架構(gòu)進(jìn)行編包,內(nèi)容不同,所以寫了兩個(gè)文件dockerfile.x86和dockerfile.arm

如果可以將架構(gòu)信息傳遞到dockerfile中,則可以將這兩個(gè)文件合二為一

這里主要的執(zhí)行命令為:

docker build --build-arg ARCH=x86_64 -t myimage:x86_64 .

復(fù)制

對(duì)應(yīng)的dockerfile文件為:

# 構(gòu)建參數(shù)
ARG ARCH

# 根據(jù)不同的架構(gòu),選擇不同的基礎(chǔ)鏡像
FROM ${ARCH}/debian:latest

# 安裝必要的軟件包
RUN apt-get update && apt-get install -y gcc g++ make && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY . .

RUN make

FROM ${ARCH}/debian:latest

WORKDIR /app 

COPY --from=builder /app/app /app 

CMD ["/app/app/install.sh"]

CMD ["/app/app/build.sh"]

復(fù)制

當(dāng)然這里只是做了個(gè)樣例,實(shí)際上除了FROM里面還有一些安裝腳本需要選擇,這里就需要用到了IF ELSE命令

?修改上面的腳本如下:

# 構(gòu)建參數(shù)
ARG ARCH

# 根據(jù)不同的架構(gòu),選擇不同的基礎(chǔ)鏡像
FROM ${ARCH}/debian:latest

# 安裝必要的軟件包
RUN apt-get update && apt-get install -y gcc g++ make && rm -rf /var/lib/apt/lists/*

# 復(fù)制應(yīng)用程序源代碼
COPY app /app

# 根據(jù)不同的架構(gòu),選擇不同的應(yīng)用程序目錄
RUN if [ "$ARCH" = "x86_64" ]; then \
        cp -r /app/install_x86.sh /app/install.sh; \
    elif [ "$ARCH" = "arm64v8" ]; then \
        cp -r /app/install_arm.sh /app/install.sh; \
    else \
        echo "Unsupported architecture: $ARCH"; \
        exit 1; \
    fi

# 運(yùn)行安裝程序
CMD ["/app/install.sh"]

復(fù)制

?通過上面的方法,基本上實(shí)現(xiàn)了一個(gè)dockerfile文件的多架構(gòu)鏡像編譯

那么情況變成了這個(gè)樣子:

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

離成功又進(jìn)了一步

3.合并安裝依賴腳本(install.sh)

和上面類似,通過變量傳入進(jìn)行修改

#!/bin/bash

# 構(gòu)建參數(shù)
ARCH=$1

# 安裝不同的環(huán)境依賴
if [ "$ARCH" = "x86_64" ]; then
    apt-get update && apt-get install -y gcc g++ make
elif [ "$ARCH" = "arm64v8" ]; then
    apt-get update && apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu make
else
    echo "Unsupported architecture: $ARCH"
    exit 1
fi

# 下載并編譯golang程序
wget https://example.com/myapp.tar.gz
tar -xzf myapp.tar.gz
cd myapp
GOOS=linux GOARCH=$ARCH go build -o myapp

# 運(yùn)行g(shù)olang程序
./myapp

復(fù)制

當(dāng)然,一般來說依賴安裝會(huì)稍微復(fù)雜一些,有些涉及的是ARm和非ARM的版本問題,有的是版本號(hào)的升級(jí)和降級(jí),除了上文額if和else之外,還可以使用sed –i命令進(jìn)行個(gè)性化修改,比如安裝腳本是這樣的:

#!/bin/bash

# 安裝x86架構(gòu)的環(huán)境依賴
apt-get update && apt-get install -y gcc g++ make libssl-dev

# 下載并編譯golang程序
wget https://example.com/myapp.tar.gz
tar -xzf myapp.tar.gz
cd myapp
GOOS=linux GOARCH=amd64 go build -o myapp

# 運(yùn)行g(shù)olang程序
./myapp

復(fù)制

那外部調(diào)用腳本可以用下面的方式進(jìn)行調(diào)整

#!/bin/bash

# 修改install.sh中的環(huán)境依賴
sed -i 's/apt-get install -y gcc g++ make libssl-dev/apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu make libssl-dev/g' install.sh

# 調(diào)用安裝腳本
./install.sh

復(fù)制

當(dāng)然sed -i是比較靈活的修改方式,需要注意可維護(hù)性,不然,可能出現(xiàn)改一個(gè)腳本,導(dǎo)致一堆腳本不可用

當(dāng)然,看到這里,可能有個(gè)疑問,dockerfile的多架構(gòu)適配是不是也可以用sed -i的方法,而不用ARG的傳參?

這里筆者也比較了下兩者的不同

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

最后,這里的建議是把基本的安裝依賴作為基礎(chǔ)鏡像單獨(dú)存儲(chǔ),這樣可以避免在多個(gè)業(yè)務(wù)鏡像中重復(fù)編譯

大概是這樣:

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

? 三、golang多架構(gòu)編譯

1.Golang多系統(tǒng)多架構(gòu)編譯

在Golang中,我們可以通過不同的文件后綴來實(shí)現(xiàn)多架構(gòu)編譯。這是因?yàn)镚olang的編譯器可以根據(jù)文件后綴來判斷需要編譯的架構(gòu)類型。首先,讓我們來了解一下不同的文件后綴代表的含義。在Golang中,文件后綴通常由兩部分組成,分別是操作系統(tǒng)(GOOS)和架構(gòu)(GOARCH)。例如,文件名為“hello_windows_amd64.exe”,其中“windows”代表操作系統(tǒng)為Windows,“amd64”代表架構(gòu)為64位的x86架構(gòu)。

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

下面是一個(gè)基本的Golang多系統(tǒng)多架構(gòu)編譯示例:

package main

import "fmt"

func main() {
    fmt.Println("Hello, world!")
}

復(fù)制

?在Linux操作系統(tǒng)下,可以使用以下命令編譯該程序:

$ go build -o hello_windows_amd64.exe

復(fù)制

?在ARM處理器架構(gòu)下,可以使用以下命令編譯該程序:

go build -o hello_linux_amd64

復(fù)制

這個(gè)方法在很多的ARM的信創(chuàng)適配上比較常用

以github上比較常見的日志庫為例:

適配時(shí)報(bào)了這個(gè)錯(cuò)誤

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

因?yàn)槭褂昧薉up2這個(gè)方法報(bào)錯(cuò),dup2是dup命令的一種,還有dup和dup3命令,三者的區(qū)別如下

dup(int filedes)函數(shù)返回一個(gè)可用的與filedes共享文件表項(xiàng)的最小描述符

dup2(int filedes,int filedes2)是使用一個(gè)描述符filedes2去指向filedes文件表項(xiàng)(也是共享)

dup3(int oldfd, int newfd, int flags)和dup2相似,不同在于,可以通過指定flags為O_CLOEXEC強(qiáng)制置位新文件描述符的 close-on-exec 標(biāo)志

事實(shí)上,三個(gè)方法除了功能上的差異外,在平臺(tái)適配上也有些不同:

Darwin(MacOS)的X86架構(gòu)支持: Dup2

Linux的X86架構(gòu)支持: ? ?Dup2、Dup3

Linux的arm架構(gòu)支持: Dup3

所以進(jìn)行適配時(shí),可以根據(jù)不同的平臺(tái)編譯不同的文件分別定義對(duì)應(yīng)的方法實(shí)現(xiàn),比如:

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

2.CGo多系統(tǒng)多架構(gòu)編譯

CGO是Go語言中用于與C語言進(jìn)行交互的工具,它可以讓我們?cè)贕o語言中調(diào)用C語言的函數(shù)和使用C語言的庫。在進(jìn)行CGO編譯時(shí),我們需要考慮多系統(tǒng)多架構(gòu)的問題,以確保我們的程序可以在不同的操作系統(tǒng)和架構(gòu)中正常運(yùn)行。

下面是一些CGO多系統(tǒng)多架構(gòu)編譯的方法:

2.1?使用CGO_ENABLED環(huán)境變量

使用CGO_ENABLED環(huán)境變量。CGO_ENABLED環(huán)境變量可以用來控制CGO是否啟用。在進(jìn)行多系統(tǒng)多架構(gòu)編譯時(shí),我們可以設(shè)置CGO_ENABLED環(huán)境變量為0,這樣就可以禁用CGO,從而避免在不同的操作系統(tǒng)和架構(gòu)中出現(xiàn)問題。

下面是一個(gè)具體的例子,假設(shè)我們需要編譯一個(gè)使用了libcurl庫的Go程序,并且需要在Linux和Windows操作系統(tǒng)中分別編譯出x86和x64架構(gòu)的程序。我們可以使用以下命令來進(jìn)行編譯:

CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o myprogram-linux-amd64 main.go 
CGO_ENABLED=1 GOOS=linux GOARCH=386 go build -o myprogram-linux-386 main.go 
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 go build -o myprogram-windows-amd64.exe main.go 
CGO_ENABLED=1 GOOS=windows GOARCH=386 go build -o myprogram-windows-386.exe main.go

復(fù)制

這個(gè)命令會(huì)分別編譯出Linux和Windows操作系統(tǒng)中的x86和x64架構(gòu)的程序

2.2 使用交叉編譯工具

使用交叉編譯工具。交叉編譯工具可以讓我們?cè)谝慌_(tái)機(jī)器上編譯出多個(gè)不同操作系統(tǒng)和架構(gòu)的程序。在進(jìn)行CGO編譯時(shí),我們可以使用交叉編譯工具來編譯出多個(gè)不同操作系統(tǒng)和架構(gòu)的程序,從而確保我們的程序可以在不同的操作系統(tǒng)和架構(gòu)中正常運(yùn)行。

下面是一個(gè)詳細(xì)的cgo交叉編譯的例子,假設(shè)我們需要編譯一個(gè)使用了libcurl庫的Go程序,并且需要在Linux和Windows操作系統(tǒng)中分別編譯出x86和x64架構(gòu)的程序。

安裝交叉編譯工具 首先,我們需要安裝交叉編譯工具。在Ubuntu系統(tǒng)中,我們可以使用以下命令來安裝交叉編譯工具:

sudo apt-get install gcc-arm-linux-gnueabihf
sudo apt-get install gcc-mingw-w64-x86-64

復(fù)制

?這個(gè)命令會(huì)安裝arm-linux-gnueabihf和mingw-w64-x86-64交叉編譯工具,分別用于編譯ARM和Windows x64架構(gòu)的程序。

編寫Go程序 接下來,我們需要編寫一個(gè)使用了libcurl庫的Go程序。假設(shè)我們的程序代碼如下:

package main

// #cgo LDFLAGS: -lcurl
// #include <curl/curl.h>
import "C"

import (
    "fmt"
    "unsafe"
)

func main() {
    curl := C.curl_easy_init()
    if curl == nil {
        fmt.Println("Failed to initialize curl")
        return
    }
    defer C.curl_easy_cleanup(curl)

    url := C.CString("https://www.example.com")
    defer C.free(unsafe.Pointer(url))

    C.curl_easy_setopt(curl, C.CURLOPT_URL, url)

    res := C.curl_easy_perform(curl)
    if res != C.CURLE_OK {
        fmt.Println("Failed to perform curl request")
        return
    }

    fmt.Println("Curl request succeeded")
}

復(fù)制

?這個(gè)程序使用了libcurl庫來發(fā)送HTTP請(qǐng)求。在程序中,我們使用了CGO LDFLAGS關(guān)鍵字來鏈接libcurl庫,并使用了C語言的頭文件來調(diào)用libcurl庫的函數(shù)。

編譯ARM架構(gòu)的程序 接下來,我們需要編譯ARM架構(gòu)的程序。我們可以使用以下命令來編譯ARM架構(gòu)的程序:

CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 CC=arm-linux-gnueabihf-gcc go build -o myprogram-arm main.go

復(fù)制

這個(gè)命令會(huì)使用arm-linux-gnueabihf-gcc交叉編譯工具來編譯ARM架構(gòu)的程序,并使用CGO LDFLAGS關(guān)鍵字來鏈接libcurl庫。其中,GOOS=linux表示編譯Linux操作系統(tǒng)的程序,GOARCH=arm表示編譯ARM架構(gòu)的程序,GOARM=7表示編譯ARMv7架構(gòu)的程序。

編譯Windows x64架構(gòu)的程序 最后,我們需要編譯Windows x64架構(gòu)的程序。我們可以使用以下命令來編譯Windows x64架構(gòu)的程序:

CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o myprogram-windows.exe main.go

復(fù)制

?這個(gè)命令會(huì)使用x86_64-w64-mingw32-gcc交叉編譯工具來編譯Windows x64架構(gòu)的程序,并使用CGO LDFLAGS關(guān)鍵字來鏈接libcurl庫。其中,GOOS=windows表示編譯Windows操作系統(tǒng)的程序,GOARCH=amd64表示編譯x64架構(gòu)的程序。

這里還有一個(gè)比較好的例子:

如何使用 docker buildx 構(gòu)建跨平臺(tái) Go 鏡像

2.3 使用CGO LDFLAGS等關(guān)鍵字

使用CGO LDFLAGS等關(guān)鍵字。在進(jìn)行CGO編譯時(shí),我們可以使用CGO LDFLAGS等關(guān)鍵字來指定需要鏈接的庫和編譯選項(xiàng)。這些關(guān)鍵字可以讓我們?cè)诓煌牟僮飨到y(tǒng)和架構(gòu)中使用不同的鏈接庫和編譯選項(xiàng),從而確保我們的程序可以在不同的操作系統(tǒng)和架構(gòu)中正常運(yùn)行。

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

#cgo指令符是用于在Go語言中調(diào)用C語言函數(shù)和庫的關(guān)鍵字。它可以讓我們?cè)贕o語言中使用C語言的函數(shù)和庫,從而擴(kuò)展Go語言的功能。在進(jìn)行cgo多架構(gòu)編譯時(shí),我們可以使用#cgo指令符來指定不同操作系統(tǒng)和架構(gòu)下的編譯選項(xiàng)。

下面是一些#cgo指令符在cgo多架構(gòu)編譯中的使用方法:

#cgo CFLAGS #cgo CFLAGS指令符可以用來指定C語言編譯器的編譯選項(xiàng)。在進(jìn)行多架構(gòu)編譯時(shí),我們可以使用#cgo CFLAGS指令符來指定不同操作系統(tǒng)和架構(gòu)下的編譯選項(xiàng)。例如,我們可以使用以下指令符來指定ARM架構(gòu)下的編譯選項(xiàng):

#cgo CFLAGS: -march=armv7-a -mfpu=neon

復(fù)制

這個(gè)指令符會(huì)在ARM架構(gòu)下使用-march=armv7-a和-mfpu=neon編譯選項(xiàng)來編譯C語言代碼。

#cgo LDFLAGS #cgo LDFLAGS指令符可以用來指定鏈接器的選項(xiàng)。在進(jìn)行多架構(gòu)編譯時(shí),我們可以使用#cgo LDFLAGS指令符來指定不同操作系統(tǒng)和架構(gòu)下的鏈接選項(xiàng)。例如,我們可以使用以下指令符來指定Windows x64架構(gòu)下的鏈接選項(xiàng):

#cgo LDFLAGS: -L/usr/local/lib -lcurl

復(fù)制

?這個(gè)指令符會(huì)在Windows x64架構(gòu)下使用-L/usr/local/lib和-lcurl鏈接選項(xiàng)來鏈接libcurl庫。

#cgo windows #cgo windows指令符可以用來指定Windows操作系統(tǒng)下的編譯選項(xiàng)。在進(jìn)行多架構(gòu)編譯時(shí),我們可以使用#cgo windows指令符來指定不同操作系統(tǒng)下的編譯選項(xiàng)。例如,我們可以使用以下指令符來指定Windows操作系統(tǒng)下的編譯選項(xiàng):

#cgo windows CFLAGS: -D_WIN32_WINNT=0x0601

復(fù)制

?這個(gè)指令符會(huì)在Windows操作系統(tǒng)下使用-D_WIN32_WINNT=0x0601編譯選項(xiàng)來編譯C語言代碼

#cgo linux

#cgo windows指令符可以用來指定Linux操作系統(tǒng)下的編譯選項(xiàng)。在進(jìn)行多架構(gòu)編譯時(shí),我們可以使用#cgo linux指令符來指定不同操作系統(tǒng)下的編譯選項(xiàng)。例如,我們可以使用以下指令符來指定Linux操作系統(tǒng)下的編譯選項(xiàng):

#cgo linux CFLAGS: -D_GNU_SOURCE

復(fù)制

?這個(gè)指令符會(huì)在Linux操作系統(tǒng)下使用-D_GNU_SOURCE編譯選項(xiàng)來編譯C語言代碼。

#cgo darwin #cgo darwin指令符可以用來指定macOS操作系統(tǒng)下的編譯選項(xiàng)。在進(jìn)行多架構(gòu)編譯時(shí),我們可以使用#cgo darwin指令符來指定不同操作系統(tǒng)下的編譯選項(xiàng)。例如,我們可以使用以下指令符來指定macOS操作系統(tǒng)下的編譯選項(xiàng):

#cgo darwin CFLAGS: -mmacosx-version-min=10.10

復(fù)制

?這個(gè)指令符會(huì)在macOS操作系統(tǒng)下使用-mmacosx-version-min=10.10編譯選項(xiàng)來編譯C語言代碼。

#cgo linux,arm64 和 #cgo linux,amd64

#cgo linux,amd64 LDFLAGS: /lib/linux/liba.a
#cgo linux,arm64 LDFLAGS: /lib/linux/liba_arm.a

復(fù)制

?等價(jià)于

#cgo linux,!arm64 LDFLAGS: /lib/linux/liba.a
#cgo linux,!amd64 LDFLAGS: /lib/linux/liba_arm.a

復(fù)制

通過上面兩個(gè)代碼層級(jí)的編譯一致性,可以得到在編譯階段也可以做到合并統(tǒng)一

這時(shí)流程圖變成了這樣的

【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐

完美!文章來源地址http://www.zghlxwxcb.cn/news/detail-464882.html

到了這里,關(guān)于【保姆級(jí)教程】Docker服務(wù)在雙架構(gòu)(X86和ARM)編譯統(tǒng)一實(shí)踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • openEuler 22.03 x86架構(gòu)下docker運(yùn)行arm等架構(gòu)的容器——筑夢(mèng)之路

    openEuler 22.03 x86架構(gòu)下docker運(yùn)行arm等架構(gòu)的容器——筑夢(mèng)之路

    隨著國產(chǎn)化的普及,國家政策對(duì)信創(chuàng)產(chǎn)業(yè)的支持,尤其一些金融證券行業(yè)、政府單位等,逐漸開始走國產(chǎn)化信創(chuàng)的路線,越來越多接觸到國產(chǎn) CPU ( arm ?平臺(tái),比如華為的鯤鵬處理器) 自己買? arm ?平臺(tái)的? CPU ,這個(gè)成本著實(shí)吃不消,于是嘗試? x86 ?平臺(tái)運(yùn)行? arm ?平臺(tái)的

    2024年02月04日
    瀏覽(25)
  • CPU 架構(gòu):ARM 和 x86 架構(gòu)區(qū)別

    計(jì)算機(jī)有兩種主要的 CPU 架構(gòu)可供選擇。Windows PC 通常建立在 Intel 和 AMD 使用的 x86 平臺(tái)上,而 Apple 的計(jì)算機(jī)則使用該公司自己的基于 ARM 架構(gòu)的?M1 和 M2 處理器。 這些方法之間存在差異,并且對(duì)性能的意義具有重大影響。 x86 和 ARM 處理器平臺(tái)做相同的事情,但它們以完全不

    2024年04月27日
    瀏覽(23)
  • ros2交叉編譯 x86到arm

    ros2交叉編譯 x86到arm

    內(nèi)容概括: 本篇文章記錄了ros2 交叉編譯(從x86_ubuntu到arm_ubuntu)過程,以及問題解決。 ros2官方文檔 中給出了 三種交叉編譯 編譯的實(shí)現(xiàn)方法: ①提前在本地下載ros2源碼然后創(chuàng)建docker ②直接自動(dòng)下載ros2源碼然后創(chuàng)建docker③不用ros2源碼,在docker中安裝預(yù)編譯ros 因?yàn)榻徊婢幾g

    2024年04月17日
    瀏覽(26)
  • 【交叉編譯】編譯生成 x86、arm 環(huán)境下的FFTW庫

    【交叉編譯】編譯生成 x86、arm 環(huán)境下的FFTW庫

    FFTW是一個(gè)快速計(jì)算離散傅里葉變換的標(biāo)準(zhǔn)C語言程序集,可計(jì)算一維或多維實(shí)和復(fù)數(shù)據(jù)以及任意規(guī)模的DFT。下面主要介紹的是 x86 環(huán)境下?FFTW庫的編譯過程,arm環(huán)境下的編譯過程和FFTW類似,不同之處在于需要手動(dòng)指定 編譯環(huán)境 和 編譯器 。 FFTW有三個(gè)版本的數(shù)據(jù)類型:double、

    2024年02月06日
    瀏覽(78)
  • gcc編譯 與交叉編譯(x86 to arm) (一)單個(gè)文件編譯

    gcc編譯 與交叉編譯(x86 to arm) (一)單個(gè)文件編譯

    源平臺(tái): UOS_X86_64 目標(biāo)平臺(tái):UOS_arm 方法:使用現(xiàn)成的交叉編譯工具鏈 參考資料:交叉編譯概念 ; 安裝交叉編譯器 ; 交叉編譯入門 ( 步驟1 )去平臺(tái)下載對(duì)應(yīng)的工具鏈 https://www.linaro.org/downloads/ https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads 以上兩個(gè)均可以下載,我下載

    2024年02月06日
    瀏覽(34)
  • 『ARM』和『x86』處理器架構(gòu)解析指南

    『ARM』和『x86』處理器架構(gòu)解析指南

    如果問大家是否知道 CPU,我相信不會(huì)得到否定的答案,但是如果繼續(xù)問大家是否了解 ARM 和 X86 架構(gòu) ,他們的區(qū)別又是什么,相信 可能部分人就會(huì)啞口無言 了 目前隨著深度學(xué)習(xí)、高性能計(jì)算、NLP、AIGC、GLM、AGI 的技術(shù)迭代,助力大模型快速發(fā)展,對(duì)于 多元算力結(jié)合(CPU+GP

    2024年02月08日
    瀏覽(122)
  • ARM和X86架構(gòu)對(duì)比分析-2023-4-27

    架構(gòu) 項(xiàng)目 ARM X86 性能 CPU:幾百兆,最近才出現(xiàn)1G左右。制程使用不到65nm制程的工藝。 CPU: 1G以上;雙核、四核。常用45nm(甚至更高級(jí))制程工藝生產(chǎn)。 擴(kuò)展能力 ARM結(jié)構(gòu)的電腦是通過專用的數(shù)據(jù)接口使CPU與數(shù)據(jù)存儲(chǔ)設(shè)備進(jìn)行連接,所以ARM的存儲(chǔ)、內(nèi)存等性能擴(kuò)展難以進(jìn)行

    2024年02月01日
    瀏覽(54)
  • Linux操作系統(tǒng)下Docker和Docker Compose的安裝教程(包含x86和arm64平臺(tái)離線一鍵安裝資源包)

    本文章將詳細(xì)介紹Linux下Docker和Docker Compose的安裝教程。 目錄3為x86和arm64平臺(tái)Docker離線安裝資源包,包含Docker Compose、一鍵安裝腳本使用教程。 相關(guān)文章參考: Docker常用基礎(chǔ)命令 Docker批量清理刪除鏡像和容器常用命令 版本如下 名稱 版本 CentOS 7.6+ openEuler等其他操作系統(tǒng)可以使

    2024年02月06日
    瀏覽(26)
  • ARM與X86架構(gòu)的簡(jiǎn)單剖析與未來展望

    ????????在計(jì)算機(jī)硬件領(lǐng)域,ARM和X86架構(gòu)無疑是兩種最具影響力的處理器架構(gòu)。它們各自在全球范圍內(nèi)應(yīng)用于廣泛的設(shè)備中,從嵌入式系統(tǒng)到服務(wù)器,再到個(gè)人電腦和移動(dòng)設(shè)備,塑造了現(xiàn)代計(jì)算技術(shù)的面貌。本文將深入解析ARM與X86架構(gòu)的異同,并對(duì)未來市場(chǎng)發(fā)展趨勢(shì)進(jìn)行前

    2024年04月09日
    瀏覽(20)
  • ubuntu x86搭建 麒麟arm QT6交叉編譯

    近期項(xiàng)目需求開發(fā)平臺(tái)是unbuntu x86,目標(biāo)機(jī)器是UOS arm架構(gòu),由于需要在不同平臺(tái)上使用程序,需要建立基于QT6.32的交叉編譯平臺(tái) 交叉編譯器 https://blog.csdn.net/zhang421412170/article/details/110952705 下載 gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz(因?yàn)槲疫@里用的是linux平臺(tái)進(jìn)行編譯,需要

    2024年02月13日
    瀏覽(26)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包