【问题标题】:How to work with external libraries when cross compiling?交叉编译时如何使用外部库?
【发布时间】:2013-09-24 21:39:28
【问题描述】:

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

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

在这种情况下最好的做法是什么?

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

【问题讨论】:

    标签: c linux gcc arm cross-compiling


    【解决方案1】:

    关于您的一般问题:

    C 库为何有效:

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

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

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

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

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

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

    【讨论】:

    • 谢谢,这很有帮助。一个更普遍的问题。关于 C 库,我没有在 makefile 中指定任何路径。我只是提供了 arm-gcc 的路径,那么它怎么知道在哪里可以找到 stdlib。我知道对于外部库,我可以使用 -L 指定路径。
    • @PunitSoni arm-gcc 会根据相对路径自动计算,所以你不能改变你的交叉编译器的目录结构
    • 可能有助于举例说明这些选项(--host--prefix)如何工作。
    【解决方案2】:

    查询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) 和(包含文件)

    你可以通过

    arm-linux-gnueabihf-gcc -print-sysroot

    这显示了在哪里寻找 libc。

    还有

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

    给你清晰的画面

    【讨论】:

    • 谢谢,有道理。
    • 所以,如果我的嵌入式系统有 ISO,我可以挂载那个 ISO(只读)并使用 --with-sysroot 让交叉编译器在构建时使用所有这些系统库新包?
    【解决方案3】:

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

    可能有一些预构建的库可用,但我怀疑找到一个(可以工作并符合您的特定条件)比从源代码自己构建库要多 - 它不应该那么难,我希望@ 987654322@ 不需要那么多分钟来构建。

    【讨论】:

    • 谢谢,我只是想确认一下,这是最好的方法。那么,stdlib 在这种情况下是如何工作的。我没有在这里编译或链接 ARM 的标准库。
    【解决方案4】:

    关于您的第一个问题,如果您打算将 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 工具链可能是相同的。你可以试试这个。

    【讨论】:

      【解决方案5】:

      Vinay 的回答非常中肯。只是在为 raspberry pi 编译 ncurses 库时进行更正,设置 rootfs 的选项是 --sysroot=<dir> 而不是 --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. 这是免费软件;查看复制条件的来源。没有 保修单;甚至不是为了适销性或特定用途的适用性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多