交叉编译时如何使用外部库?

问题描述 投票:27回答:5

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

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

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

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

c linux gcc arm cross-compiling
5个回答
22
投票

关于你的一般问题:

为什么C库有效:

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

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

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

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

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

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


14
投票

查询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

给你清晰的图片


2
投票

显然,你需要为你所针对的ARM编译一个ncurses - 主机上的那个将完全没有任何好处[除非你的主机有一个ARM处理器 - 但你说的是x86,所以显然不是这样)。

可能有一些预构建的库可用,但我怀疑找到一个(工作和匹配你的特定条件)比从源自己构建库更多的工作 - 它应该不那么难,我希望ncurses不需要花费很多分钟才能建成。


1
投票

至于你的第一个问题,如果你打算在你的交叉编译工具链中使用ncurses库,那么你将准备好它的arm-built二进制文件。

你的第二个问题是它如何与std lib一起使用,它真的不是工具链用于编译/链接你的程序的系统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工具链可能是一样的。你可以尝试一下。


1
投票

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 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
© www.soinside.com 2019 - 2024. All rights reserved.