简体   繁体   English

如何将更多 memory 分配给运行 gcc 命令的 docker 容器?

[英]How allocate more memory to my docker container running the gcc command?

I have to compile C code which contains python function.我必须编译包含 python function 的 C 代码。 I have a Ubuntu 19 64 bit machine and I need to compile the C code for my raspberry pi 3model b+ running raspbian stretch.我有一台 Ubuntu 19 64 位机器,我需要为运行 raspbian 拉伸的树莓派 3model b+ 编译 C 代码。 To do that, I followed https://raspberrypi.stackexchange.com/a/109524/116139 to create a docker container with the stretch version I need.为此,我按照https://raspberrypi.stackexchange.com/a/109524/116139创建了一个带有我需要的拉伸版本的 docker 容器。 My docker stats are:我的 docker stats是:


CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT     MEM %                 NET I/O             BLOCK I/O           PIDS
14b303f257da        DOCKER_CONTAINER   0.00%               13.68MiB / 7.776GiB   0.17%               6.51MB / 26.6kB     19.4MB / 41kB       2

Inside the container environment, running top :在容器环境中,运行top

    1 root      20   0 4241352  12308   4892 S  0.0  0.2   0:00.50 bash         
  133 root       0   0 4241096  12048   4972 R  0.0  0.1   0:00.00 top 

In addition, running df -h :此外,运行df -h

Filesystem      Size  Used Avail Use% Mounted on
overlay          30G   21G  7.6G  74% /
tmpfs            64M     0   64M   0% /dev
tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
shm              64M     0   64M   0% /dev/shm
/dev/sda1        30G   21G  7.6G  74% /etc/hosts
tmpfs           3.9G     0  3.9G   0% /proc/asound
tmpfs           3.9G     0  3.9G   0% /proc/acpi
tmpfs           3.9G     0  3.9G   0% /proc/scsi
tmpfs           3.9G     0  3.9G   0% /sys/firmware

So, I gave you all the memories information about my system.所以,我给了你关于我系统的所有记忆信息。 My gcc command runs out of memory in compiling my large C code:我的 gcc 命令在编译我的大型 C 代码时用完了 memory 代码:

gcc -Os $(python3-config --cflags --ldflags) CCODE.c -o EXECUTABLE_CODE 

cc1: out of memory allocating 66660800 bytes after a total of 290631680 bytes

Running just the gcc command (without docker) in the RPi4 (4GB RAM) it works (while on RPi3b+, 1GB RAM, it fails reporting cc1: out of memory ).在 RPi4(4GB RAM)中仅运行gcc命令(没有 docker)它可以工作(在 RPi3b+、1GB RAM 上,它无法报告cc1: out of memory )。 However, I need RPi3 which unfortunately has a different OS.但是,我需要 RPi3,不幸的是它有不同的操作系统。 I'm stuck in this problem for weeks.我被困在这个问题上好几个星期了。 Does someone have any tips or different solutions?有人有任何提示或不同的解决方案吗? Thanks in advice.谢谢指教。

You could try cross-compiling your code to get around this issue.你可以尝试交叉编译你的代码来解决这个问题。

For the toolchain, you can use Crosstool-NG .对于工具链,您可以使用Crosstool-NG Getting Python to cross-compile is a bit more work, and I won't go into detail about it here.让 Python 进行交叉编译需要更多的工作,我不会在这里详细介绍 go。 I'll refer you to the Dockerfile and shell scripts I used.我将向您推荐我使用的Dockerfileshell 脚本 You can find more information about them here .您可以在此处找到有关它们的更多信息。

For the purposes of this answer, I'm going to use the Docker images I built myself.出于此答案的目的,我将使用我自己构建的 Docker 图像。 They are available from Docker Hub.它们可从 Docker 集线器获得。 You could of course build them yourself if you wanted to, the source is available in the GitHub repo I linked to earlier.如果您愿意,您当然可以自己构建它们,源代码在我之前链接到的 GitHub 存储库中可用。 If you don't need NumPy and OpenCV, be sure to comment all of that out in the Dockerfile, because it takes a long time to cross-compile.如果您不需要 NumPy 和 OpenCV,请务必在 Dockerfile 中将所有这些注释掉,因为交叉编译需要很长时间。

The toolchain I used is for Linux 4.15 and later.我使用的工具链适用于 Linux 4.15 及更高版本。 If you use Raspbian Stretch, its kernel may be too old.如果你使用 Raspbian Stretch,它的 kernel 可能太旧了。 It should work on Raspbian Buster and Ubuntu 18.04 and later, though.不过,它应该适用于 Raspbian Buster 和 Ubuntu 18.04 及更高版本。 If you really want to use Stretch, you'll have to edit the toolchain config file as explained here and build the toolchain yourself.如果您真的想使用 Stretch,则必须按照此处的说明编辑工具链配置文件并自己构建工具链。 The same goes for the Python version. Python 版本也是如此。 By default, it uses Python 3.8.2.默认情况下,它使用 Python 3.8.2。


1. Prepare your working directory 1.准备你的工作目录

Prepare a folder that contains all of the code you want to cross-compile.准备一个文件夹,其中包含您要交叉编译的所有代码。 If you have external dependencies that you can easily move around, place them in the folder as well.如果您有可以轻松移动的外部依赖项,请将它们也放在文件夹中。 We'll later just mount this folder to the Docker container.稍后我们将把这个文件夹挂载到 Docker 容器中。

2. Write the build commands in a small shell script 2.在一个小的shell脚本中编写构建命令

Create a file build-docker.sh that contains whatever commands you want to execute in the Docker container to build your code.创建一个build-docker.sh文件,其中包含您要在 Docker 容器中执行的任何命令来构建您的代码。

set -ex
PY_CONFIG="${RPI_SYSROOT}/usr/local/bin/python3.8-config"
OPTS=$(${PY_CONFIG} --cflags --ldflags)
CC=${HOST_TRIPLE}-gcc
${CC} ${OPTS} CCODE.c -o EXECUTABLE_CODE

Notice how I used the python3.8-config script in the Raspberry Pi's sysroot folder.请注意我是如何在 Raspberry Pi 的 sysroot 文件夹中使用python3.8-config脚本的。 If you just use python3.8-config without specifying the full path, it'll use the configuration of the build machine's Python installation, which is not what you want.如果你只使用python3.8-config而不指定完整路径,它将使用构建机器的 Python 安装的配置,这不是你想要的。

You also need to specify the cross-compiler.您还需要指定交叉编译器。 Again, if you just write gcc , it uses the build system's native x86_64 compiler.同样,如果您只编写gcc ,它使用构建系统的本机 x86_64 编译器。 You need the ARM cross-compiler.您需要 ARM 交叉编译器。

3. Run the script in the Docker container 3.运行Docker容器中的脚本

Your working directory should now look like this:您的工作目录现在应该如下所示:

.
├── build-docker.sh
└── CCODE.c

Now we'll start a Docker container with the necessary cross-compilation tools, mount the working directory to it, so you can access your CCODE.c , and run the build commands in the script we just wrote.现在我们将使用必要的交叉编译工具启动一个 Docker 容器,将工作目录挂载到其中,这样您就可以访问您的CCODE.c ,并在我们刚刚编写的脚本中运行构建命令。

docker run \
    --rm \
    -it \
    -v "$PWD:/tmp/workdir" \
    -w "/tmp/workdir" \
    tttapa/rpi-cross:armv8-rpi3-linux-gnueabihf \
    "bash" "build-docker.sh"

The first time you run it, it'll pull the image from Docker Hub, so it'll take some time (it's over a GiB).第一次运行它时,它会从 Docker Hub 拉取图像,因此需要一些时间(超过 GiB)。

When the build is done, you should be left with a file EXECUTABLE_CODE in your working directory:构建完成后,您应该在工作目录中留下一个文件EXECUTABLE_CODE

$ file EXECUTABLE_CODE
EXECUTABLE_CODE: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux-armhf.so.3,
for GNU/Linux 4.15.18, with debug_info, not stripped

You can find a more detailed example here: https://github.com/tttapa/RPi-Cpp-Toolchain/tree/master/extra/python/cross-compile-module/spam您可以在此处找到更详细的示例: https://github.com/tttapa/RPi-Cpp-Toolchain/tree/master/extra/python/cross-compile-module/spam


A small recommendation: If you write a lot of code that needs interaction between C/C++ and Python, or code that embeds the Python interpreter, Pybind11 is a great tool.一个小建议:如果你写了很多需要C/C++和Python交互的代码,或者嵌入Python解释器的代码, Pybind11是一个很好的工具。 It has bindings for all standard C++ containers and Python/NumPy/Eigen types, it allows you to call Python code from C++ code, export C/C++ functions/structs/classes as Python modules, and it handles all compilation for you using CMake: https://github.com/pybind/cmake_example It has bindings for all standard C++ containers and Python/NumPy/Eigen types, it allows you to call Python code from C++ code, export C/C++ functions/structs/classes as Python modules, and it handles all compilation for you using CMake: https://github.com/pybind/cmake_example


Edit: If your secret CCODE needs to embed Python, you have to link to libpython:编辑:如果您的秘密 CCODE 需要嵌入 Python,您必须链接到 libpython:

https://docs.python.org/3.8/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build https://docs.python.org/3.8/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build

To embed Python into an application, a new --embed option must be passed to python3-config --libs --embed to get -lpython3.8 (link the application to libpython).要将 Python 嵌入到应用程序中,必须将新的--embed选项传递给python3-config --libs --embed以获取-lpython3.8 (将应用程序链接到 libpython)。

OPTS=$(${PY_CONFIG} --cflags --ldflags --embed)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM