36

我正在为 x86 ubuntu 机器上的树莓派 ARM 目标编写一些代码。我正在使用 gcc-linaro-armhf 工具链。我能够在 pi 上交叉编译和运行一些独立的程序。现在,我想将我的代码与 ncurses 等外部库链接。我怎样才能做到这一点。

我是否应该将我的程序与主机上现有的 ncurses 库链接,然后在 ARM 上运行?(我认为这行不通)我是否需要为 arm 获取 lib 的源代码或预构建版本,将其放入我的 lib 路径然后编译?

在这种情况下,最佳做法是什么?

我还想知道它对 c stdlib 的工作原理。在我的程序中,我使用了 stdio 函数,它在交叉编译后工作,没有做任何特别的事情。我刚刚在 makefile 中为我的 arm gcc 提供了路径。所以,我想知道,它是如何得到正确的标准头文件和库的?

4

5 回答 5

30

关于您的一般问题:

为什么 C 库有效:

C 库是您的交叉工具链的一部分。这就是找到标头并且程序正确链接和运行的原因。对于其他一些非常基本的系统库,如 libm 和 libstdc++ 也是如此(并非在每种情况下,都取决于工具链配置)。

一般来说,在处理交叉开发时,您需要某种方法来交叉编译所需的库。在这种情况下使用二进制文件是非常罕见的。也就是说,尤其是 ARM 硬件,因为有很多不同的配置,而且通常所有东西都以不同的方式被剥离。这就是为什么二进制文件在不同设备和 Linux 配置之间不太兼容的原因。

如果您在 Raspberry Pi 上运行 Ubuntu,那么您可能会在 Internet 甚至某些 Ubuntu apt 存储库中找到合适的 ncurses 库。然而,典型的方法是使用您拥有的特定工具链交叉编译库。

在需要交叉编译大量复杂库的情况下,有一些解决方案可以让生活变得更轻松一些,比如 buildroot 或 ptxdist。这些程序为嵌入式设备构建完整的 Linux 内核和根文件系统。

但是,在您的情况下,只要您只需要 ncurses,您就可以自己编译源代码。您只需要下载源代码,在使用该选项configure指定您的工具链时运行。--host--prefix选项将选择安装目录。运行makeand之后make install,考虑到一切正常,您将获得一组头文件和 ARM 编译的库,供您的应用程序链接。

关于交叉编译,您肯定会在互联网上找到大量信息,也许 ncurses 在其随附的文档中也有一些指示。

于 2013-09-19T19:01:51.917 回答
17

对于查询How the C library works in cross-tools

在配置期间编译和构建跨工具链时,它们将提供 sysroot。

喜欢--with-sysroot=${CLFS_CROSS_TOOLS}

--with-sysroot --with-sysroot=dir

Tells GCC to consider dir as the root of a tree that contains (a subset of) the root filesystem of the target operating system. Target system headers, libraries and run-time object files will be searched for in there. More specifically, this acts as if --sysroot=dir was added to the default options of the built compiler. The specified directory is not copied into the install tree, unlike the options --with-headers and --with-libs that this option obsoletes. The default value, in case --with-sysroot is not given an argument, is ${gcc_tooldir}/sys-root. If the specified directory is a subdirectory of ${exec_prefix}, then it will be found relative to the GCC binaries if the installation tree is moved.

因此,/lib /usr/include在编译时,它不会看起来像 /Toolchain/(libc) 和 (include files)

你可以检查

arm-linux-gnueabihf-gcc -print-sysroot

这显示了在哪里寻找 libc 。

arm-linux-gnueabihf-gcc -print-search-dirs

给你清晰的画面

于 2013-09-20T15:52:50.260 回答
2

显然,您将需要ncurses为您所针对的 ARM 编译 - 主机上的那个绝对不会对您有任何好处[除非您的主机有 ARM 处理器 - 但您说的是 x86,所以显然不是这种情况]。

可能有一些可用的预建库,但我怀疑找到一个(有效并符合您的特定条件)比从源头自己构建库更费力 - 它不应该那么难,而且我希望ncurses不需要建造这么多分钟。

于 2013-09-19T17:13:39.190 回答
1

至于您的第一个问题,如果您打算将 ncurses 库与您的交叉编译器工具链一起使用,您将准备好其 arm 构建的二进制文件。

你的第二个问题是它如何与标准库一起工作,它真的不是工具链用来编译/链接你的程序的系统 libc/libm。也许您会从编译器的--- print-file-name=选项中看到它:

arm-none-linux-gnuabi-gcc --print-file-name=libm.a

...(my working folder)/arm-2011.03(arm-toolchain folder)/bin/../arm-none-linux-gnuabi/libc/usr/lib/libm.a

arm-none-linux-gnuabi-gcc --print-file-name=libpthread.so

...(my working folder)/arm-2011.03(arm-toolchain folder)/bin/../arm-none-linux-gnuabi/libc/usr/lib/libpthread.so

我认为您的 Raspberry 工具链可能是相同的。你可以试试这个。

于 2013-09-20T03:07:25.363 回答
1

维奈的回答非常中肯。只是在为 raspberry pi 编译 ncurses 库时进行更正,设置 rootfs 的选项 is--sysroot=<dir>和 not --with-sysroot。这就是我在使用以下编译器时发现的:

arm-linux-gnueabihf-gcc --version
arm-linux-gnueabihf-gcc(crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03)4.8.3 20140303(预发布)
版权所有 (C) 2013 Free Software Foundation, Inc.
这是免费软件;查看复制条件的来源。没有
保修单; 甚至不考虑适销性或特定用途的适用性。
于 2015-01-24T17:31:28.917 回答