- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
从 amd64 到 arm7l 的交叉编译让我头疼
我终于可以用 Gitlab CI 做到这一点,所以现在,我在 docker 镜像中编译我的二进制文件,这是 dockerfile:
FROM golang
WORKDIR /go/src/gitlab.com/company/edge_to_bc
COPY . .
RUN dpkg --add-architecture armhf && apt update && apt-get install -y gcc-arm-linux-gnueabihf libltdl-dev:armhf
我将其构建为然后我将使用名称 ubuntu:cross-compil
现在,我可以编译我的二进制文件:
docker run -it -v ${EDGE_TO_BC_PATH}/release:/go/src/gitlab.com/company/edge_to_bc/release ubuntu:cross-compil bash -c 'CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 go build -v -o ./release/edge_to_bc '
我可以在 ./release/edge_to_bc
中看到我的可执行文件生成
然后我构建我的 docker 镜像:
docker build -t registry.gitlab.com/company/edge_to_bc:armhf .
然后我插入它。
在 Dockerfile 中,我只是从主机复制可执行文件:
FROM alpine:3.7
RUN apk --no-cache add ca-certificates libtool
WORKDIR /sunclient/
COPY ./release/edge_to_bc ./
EXPOSE 5555
CMD [ "./edge_to_bc" ]
但是当我在我的 ARM 板上运行它时:
docker run --rm registry.gitlab.com/company/edge_to_bc:armhf
我得到:
standard_init_linux.go:207: exec user process caused "no such file or directory"
调试时,如果我想获取文件列表
docker run --rm registry.gitlab.com/company/edge_to_bc:armhf
我得到:
standard_init_linux.go:207: exec user process caused "exec format error"
这表明二进制仍然没有正确的格式...
我错过了什么?我在这个主题上花了很多时间,没有更多的想法。
当我检查二进制的架构时,这是我得到的:
edge_to_bc git:(master) ✗ readelf -h ./release/edge_to_bc
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x19209
Start of program headers: 52 (bytes into file)
Start of section headers: 23993360 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 10
Size of section headers: 40 (bytes)
Number of section headers: 49
Section header string table index: 48
在目标操作系统上,这是我得到的:
[root@gw-sol1 ~]# uname -a
Linux gw-sol-1 4.4.113-UNRELEASED #1 SMP PREEMPT Thu Mar 7 16:46:40 CET 2019 armv7l armv7l armv7l GNU/Linux
编辑:
当我直接在 ARM 设备上构建应用程序时,它将运行:
go build -o ./release/edge_to_bc -v -ldflags '-w -s -extldflags "-static"' ./...
小 Sprite :
ELF Header:
Magic: 7f 45 4c 46 01 01 01 03 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - GNU
ABI Version: 0
Type: EXEC (Executable file)
Machine: ARM
Version: 0x1
Entry point address: 0x125f1
Start of program headers: 52 (bytes into file)
Start of section headers: 16594072 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 38
Section header string table index: 37
它看起来与另一个非常相似,至少在架构上是这样。
然后构建docker镜像:
docker build . -t image/peer-test:armhf
最佳答案
当您使用以下命令在 arm7 镜像的 amd64 系统上运行构建时:
docker build -t registry.gitlab.com/company/edge_to_bc:armhf .
它将使用基本镜像并在该镜像中为 amd64 运行命令。因此,即使您的单个 edge_to_bc
二进制文件可能会被交叉编译,图像的其余部分却不会。接下来,二进制编译命令本身看起来像是在链接到库,而这些库很可能不在您的最终镜像中。您可以运行 ldd edge_to_bc
来查看这些链接,如果它们丢失,您将收到找不到文件的错误消息。
在我自己的交叉编译测试中,我在 19.03.0-rc2 上使用 BuildKit、Buildx 和一些实验性功能,因此其中有些部分不向后兼容,但希望对您有所帮助。我正在使用多阶段构建来避免在 docker 外部进行编译然后进行第二次构建。我还指定了构建主机的平台,并使用目标架构和操作系统变量来配置 go 以进行交叉编译。在这种情况下,我使用了一个完全静态链接的二进制文件,因此没有要包含的库,并且在我的最终发布镜像中只有复制命令,我避免了在不同平台上运行构建的问题。
# syntax=docker/dockerfile:experimental
# ^ above line must be at the beginning of the Dockerfile for BuildKit
# --platform pulls an image for the build host rather than target OS/Arch
FROM --platform=$BUILDPLATFORM golang:1.12-alpine as dev
RUN apk add --no-cache git ca-certificates
RUN adduser -D appuser
WORKDIR /src
COPY . /src/
CMD CGO_ENABLED=0 go build -o app . && ./app
# my dev stage is separate from build to allow mounting source and rebuilding
# on developer machines
FROM --platform=$BUILDPLATFORM dev as build
ARG TARGETPLATFORM
ARG TARGETOS
ARG TARGETARCH
# --mount is an experimental BuildKit feature
RUN --mount=type=cache,id=gomod,target=/go/pkg/mod/cache \
--mount=type=cache,id=goroot,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -ldflags '-w -extldflags -static' -o app .
USER appuser
CMD [ "./app" ]
# this stage will have the target OS/Arch and cannot have any RUN commands
FROM scratch as release
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /etc/passwd /etc/group /etc/
COPY --from=build /src/app /app
USER appuser
CMD [ "/app" ]
FROM scratch as artifact
COPY --from=build /src/app /app
FROM release
要构建它,我可以使用 BuildKit 运行一次性构建命令:
DOCKER_BUILDKIT=1 docker build --platform=linux/amd64 -f Dockerfile -t golang-app:amd64 .
DOCKER_BUILDKIT=1 docker build --platform=linux/arm64 -f Dockerfile -t golang-app:arm64 .
但更好的是 Buildx 版本,它创建了一个可以在多个平台上运行的多架构镜像。这确实需要您推送到注册表服务器:
docker buildx build -f Dockerfile --platform linux/amd64,linux/arm64 \
-t ${docker_hub_id}/golang-app:multi-arch --output type=registry .
对于您的场景,您可以将 arm64 中的引用换成您自己的架构。 --platform
选项在我运行的许多命令中被列为实验性选项,因此您可能需要在/etc/docker/daemon.json 文件中配置以下内容以启用:
{ "experimental": true }
我相信这需要完全重启 docker 守护进程 (systemctl restart docker
),而不仅仅是重新加载,才能生效。
为了从构建中提取工件(特定架构的编译二进制文件),我使用:
docker build -f Dockerfile --target artifact -o type=local,dest=. .
这会将工件阶段的内容(单个二进制文件)输出到本地目录。
以上是 Docker 构建多架构镜像的方法列表中的选项 3。
选项 1 是使用 binfmt_misc 配置 qemu 来为不同平台构建和运行图像。我还没有能够使用 Buildx 在 Linux 上使用它,但是 Docker 已经为 Mac 做到了这一点,您可以找到更多关于他们在 LinuxKit 项目中所做的事情的详细信息。如果您需要运行命令并在构建过程中安装其他工具,而不仅仅是交叉编译单个静态链接的二进制文件,那么根据您的情况使用 qemu 可能是理想的选择。
选项 2 是在目标平台上运行构建,如您所见,效果很好。用Buildx ,您可以添加多个构建节点,每个平台最多一个,从而允许您从一个位置(CI 服务器)运行构建。
关于docker - 从 Ubuntu amd64 到 arm7l : exec user process caused "exec format error" 进行交叉编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56634558/
AMD 似乎是按需加载 javascript 模块的最佳实践。 这应该适用于用户仅使用一部分可用功能的大型网络应用程序。 我读过有关优化器的信息,它将所有必需的模块连接到一个文件中,并且我读过有关无优
我在一个项目中使用 requirejs,并且有 2 个模块: a.js:是一个非 AMD 模块,我无法触及其代码 b.js:是我用 define() 函数编写的 AMD 模块。它需要 a.js 才能工
有没有办法导入或注释 Typescript 模块,以便在生成 AMD 兼容模块时自动将外部 AMD 模块作为依赖项包括在内?: tsc --module AMD example.ts 我尝试同时包含一
在我的项目中,有一个自定义第三方库(单个构建文件),他们使用几个非 AMD 和 AMD 文件创建了该库。并且大多数属性直接暴露给窗口对象。在我们的项目中,根据新的要求,我们必须使用 requireJS
我正在尝试创建一个由许多小文件(编译为 JavaScript-AMD 模块的 TypeScript 文件)构建的单个 AMD 库(模块)文件。 问题是: 我在类之间有循环依赖。 ( parent 需要
我有一个库 - 称之为 SomeLib - 它被定义为支持各种模块加载器: (function(global, factory) { if (typeof define === 'functi
一个星期以来,我开始学习如何将 require.js 与 Backbone.js 和 Underscore.js 一起使用。 这是一个非常困难的东西,但 3 天前我读到 Underscore 将不再支
main-bower-files无法抓取backbone-amd和underscore-amd ,有什么想法为什么以及如何解决它吗? gulpfile.js var mainBowerFiles =
我正在尝试使用 perf在我的带有 AMD cpu 的设备上,但我真的找不到任何关于如何获取的信息,比如说,cache-misses来自 AMD。我读到你需要写 -e rNNN ,其中 NNN是事件的
我对 AMD 波前和 OpenCL 的工作组大小的术语有些困惑。 我发现不同的来源做了不同的陈述。 我的问题是:AMDs GCN 技术的波前大小是多少,根据这个:opencl 上的工作组至少应该有多大
我正在尝试使用 Intern 测试 Require.js 项目。我在测试中遇到错误,其中在加载 jQuery 插件时未定义 jQuery。我的加载器配置如下所示: loader: { // A
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想要改善这个问题吗?更新问题,以便将其作为on-topi
Modernizr 是使用 AMD 定义编写的,这很好,因为这就是我当前项目所使用的,并且可以在需要时引入 Modernizr 依赖项。问题是,Modernizr 模块都需要一个平面文件夹层次结构,但
AMD 不久前宣布推出 Fusion 平台。读了一些相关内容后,我既兴奋又怀疑。例如,它应该使 GPU 和 CPU 共享相同的内存成为可能。 (GPU 和 CPU 都在同一个封装中)现在,由于 GPU
当我从 Android Studio 启动 AVD 时,它长时间显示黑色空白屏幕并且我看不到主屏幕。我查看了 2013 年之前的几个 Stack Overflow 帖子(Virtual Machine
AMD 是否允许您定义一个模块,其导出是动态的,具体取决于其他模块? 我遇到的问题是,即使正文中有 require 调用,define 也会立即返回。这意味着,如果模块的定义依赖于其他模块,则任何依赖
假设我有一个加载模块myModule的应用程序。所述模块需要一些其他资源才能工作(例如模板),因此 myModule 关心加载它所需的资源,这很巧妙。实际上,这很简单: // main.js requ
AMD 规范中是否有任何内容规定必需的模块必须提供相同的对象?假设所需的模块是提供给所有需要的模块的单个实例,这似乎是相当常见的做法,但是有什么可以防止模块加载器将加载的模块仅视为缓存(可能在某个时候
所以我现在一直在使用 require.js,但我意识到我实际上并不知道它在幕后是如何工作的。它说它是一个 AMD 加载器。 我知道 CommonJS 是同步的,这意味着它会在加载时阻止其他代码的执行。
有没有办法从*.ts 中设置编译模块的名称?一些 tsconfig、json 设置或一些可以执行此操作的 Gulp 插件。 目前我得到 define([], function(){ .. }) 但我不
我是一名优秀的程序员,十分优秀!