C 交叉编译时如何使用外部库?
我正在为x86 ubuntu机器上的raspberry pi ARM目标编写一些代码。我正在使用gcc linaro armhf工具链。我能够在pi上交叉编译和运行一些独立的程序。现在,我想将我的代码链接到外部库,如ncurses。我怎样才能做到这一点 我是否应该将我的程序与主机上现有的ncurses库链接,然后在ARM上运行?(我认为这行不通) 我是否需要获取arm库的源代码或预构建版本,将其放在我的库路径中,然后进行编译 在这种情况下,最佳做法是什么C 交叉编译时如何使用外部库?,c,linux,gcc,arm,cross-compiling,C,Linux,Gcc,Arm,Cross Compiling,我正在为x86 ubuntu机器上的raspberry pi ARM目标编写一些代码。我正在使用gcc linaro armhf工具链。我能够在pi上交叉编译和运行一些独立的程序。现在,我想将我的代码链接到外部库,如ncurses。我怎样才能做到这一点 我是否应该将我的程序与主机上现有的ncurses库链接,然后在ARM上运行?(我认为这行不通) 我是否需要获取arm库的源代码或预构建版本,将其放在我的库路径中,然后进行编译 在这种情况下,最佳做法是什么 我还想知道它是如何为c stdlib工作
我还想知道它是如何为c stdlib工作的。在我的程序中,我使用了stdio函数,它在交叉编译后工作,没有做任何特殊的事情。我只是在makefile中为我的arm gcc提供了路径。所以,我想知道,它是如何得到正确的std头和LIB的?很明显,你需要为你的目标ARM编译一个
ncurses
——主机上的那一个对你绝对没有好处(除非你的主机有ARM处理器——但你说的是x86,显然不是这样)
可能有一些预构建的库可用,但我怀疑找到一个(能够工作并符合您的特定条件)比自己从源代码中构建库要困难得多——这应该没有那么难,而且我预计
ncurses
构建不需要那么多分钟 关于您的一般问题:
C库工作原理:
C库是交叉工具链的一部分。这就是为什么会找到标题,程序会正确链接并运行。对于其他一些非常基本的系统库,如libm和libstdc++,也是如此(并非在所有情况下,都取决于工具链配置)
通常,在处理交叉开发时,您需要某种方法来交叉编译所需的库。在这种情况下使用二进制文件是非常罕见的。也就是说,特别是在ARM硬件上,因为有太多不同的配置,而且通常所有的东西都以不同的方式剥离。这就是为什么二进制文件在不同的设备和Linux配置之间不太兼容的原因
如果你在Raspberry Pi上运行Ubuntu,那么你有可能在互联网上甚至在Ubuntu apt存储库中找到合适的ncurses库。然而,典型的方法是使用您拥有的特定工具链交叉编译库
在许多复杂的库需要交叉编译的情况下,有一些解决方案可以使编译变得更简单,比如buildroot或ptxdist。这些程序为嵌入式设备构建完整的Linux内核和根文件系统
然而,在您的情况下,只要您只需要ncurses,您就可以自己编译源代码。您只需下载源代码,运行configure
,同时使用--host
选项指定工具链。--prefix
选项将选择安装目录。在运行make
和makeinstall
之后,考虑到一切顺利,您将获得一组头文件和ARM编译库,供您的应用程序链接
关于交叉编译,您肯定会在internet上找到大量的信息,也许ncurses在其附带的文档中也有一些提示。关于您的第一个问题,如果您打算将ncurses库与交叉编译器工具链一起使用,您将准备好其arm构建的二进制文件 你的第二个问题是它如何与std-libs一起工作,它实际上不是工具链用来编译/链接程序的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
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.
我认为你的树莓工具链可能是一样的。您可以试一试。有关查询
C库如何在跨工具中工作的信息
在配置期间编译和构建跨工具链时,它们将提供sysroot
类似于——使用sysroot=${CLFS\u CROSS\u TOOLS}
——使用sysroot
--使用sysroot=dir
<代码>告诉GCC将DIR作为包含目标操作系统根文件系统的一棵树的根。将在其中搜索目标系统头、库和运行时对象文件。更具体地说,这就像--sysroot=dir被添加到构建编译器的默认选项中一样。指定的目录不会复制到安装树中,这与此选项废弃的选项(带头和带libs)不同。如果没有为--with sysroot提供参数,则默认值为${gcc_tooldir}/sysroot。如果指定的目录是${exec_prefix}的子目录,那么如果安装树被移动,它将相对于GCC二进制文件被找到。
因此,在编译时,它不会查看/lib/usr/include
,而是查看/Toolchain/(libc)和(include文件)
你可以顺便去看看
armlinux gnueabihf gcc-print sysroot
这显示了在哪里可以找到libc
也
arm linux gnueabihf gcc-打印搜索目录
给你一个清晰的画面维奈的答案非常可靠。在为raspberry pi编译ncurses库时,需要更正的是,设置rootfs的选项是
--sysroot=
,而不是--sysroot
。这就是我在使用以下编译器时发现的:
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
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.
arm linux gnueabihf gcc——版本
arm linux gnueabihf gcc(crosstool NG linaro-1.13.1+bzr2650-linaro gcc 2014.03)4.8.3 20140303(预发布)
版权所有(C)2013免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
谢谢,我只是想确认一下,这是最好的方法。那么,stdlib是如何工作的呢