我正在为x86 ubuntu机器上的raspberry pi ARM目标编写一些代码。我正在使用gcc-linaro-armhf工具链。我能够在pi上交叉编译并运行一些独立的程序。现在,我想将我的代码链接到外部库,如ncurses。我怎样才能做到这一点。
我应该将我的程序与主机上现有的ncurses lib链接,然后在ARM上运行吗? (我认为这不会起作用) 我需要获取arm的源代码或预构建版本的lib,将它放在我的lib路径中然后编译吗?
在这种情况下,最佳做法是什么?
我也想知道它对c stdlib的作用。在我的程序中,我使用了stdio函数,它在交叉编译后工作,没有做任何特殊的事情。我刚刚在makefile中为我的arm gcc提供了路径。所以,我想知道它是如何得到正确的标题和库?
答案 0 :(得分:22)
关于您的一般问题:
为什么C库有效:
C库是交叉工具链的一部分。这就是找到标题并且程序正确链接和运行的原因。对于其他一些非常基本的系统库(如libm和libstdc ++)也是如此(并非在所有情况下都依赖于工具链配置)。
通常,在处理交叉开发时,您需要一些方法来交叉编译所需的库。在这种情况下使用二进制文件是非常罕见的。也就是说,特别是对于ARM硬件,因为有许多不同的配置,并且通常所有内容都以不同的方式被剥离。这就是为什么二进制文件在不同设备和Linux配置之间不是非常二进制兼容的原因。
如果您在Raspberry Pi上运行Ubuntu,那么您可能会在互联网或甚至某些Ubuntu apt存储库中找到合适的ncurses库。然而,典型的方法是使用您拥有的特定工具链交叉编译库。
在需要交叉编译大量复杂库的情况下,有一些解决方案可以让生活变得像buildroot或ptxdist一样简单。这些程序为嵌入式设备构建了完整的Linux内核和根文件系统。
但是,在您的情况下,只要您只想要ncurses,您就可以自己编译源代码。您只需下载源代码,在使用configure
选项指定工具链的同时运行--host
。 --prefix
选项将选择安装目录。运行make
和make install
后,考虑到一切正常,您将获得一组标头和ARM编译库供您的应用程序链接。
关于交叉编译,您肯定会在互联网上找到大量信息,也许ncurses也在其发布的文档中有一些指示。
答案 1 :(得分: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 :(得分:2)
显然,你需要为你所针对的ARM编译ncurses
- 主机上的那个将完全没有任何好处[除非你的主机有一个ARM处理器 - 但是你说x86,显然不是这样的]。
可能有一些预建的库可用,但我怀疑找到一个(工作和匹配你的特定条件)比从源自己构建库更多的工作 - 它应该不那么难,我希望{ {1}}不需要花费很多分钟来构建。
答案 3 :(得分: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工具链可能是一样的。你可以尝试一下。
答案 4 :(得分: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.