Linux 交叉编译时如何使用外部库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18900855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to work with external libraries when cross compiling?
提问by Punit Soni
I am writing some code for raspberry pi ARM target on x86 ubuntu machine. I am using the gcc-linaro-armhf toolchain. I am able to cross compile and run some independent programs on pi. Now, I want to link my code with external library such as ncurses. How can I achieve this.
我正在为 x86 ubuntu 机器上的 raspberry pi ARM 目标编写一些代码。我正在使用 gcc-linaro-armhf 工具链。我能够在 pi 上交叉编译和运行一些独立的程序。现在,我想将我的代码与外部库(例如 ncurses)链接起来。我怎样才能做到这一点。
Should I just link my program with the existing ncurses lib on host machine and then run on ARM? (I don't think this will work) Do I need to get source or prebuilt version of lib for arm, put it in my lib path and then compile?
我应该将我的程序与主机上现有的 ncurses 库链接起来,然后在 ARM 上运行吗?(我认为这行不通)我是否需要为 arm 获取 lib 的源代码或预构建版本,将其放入我的 lib 路径中,然后进行编译?
What is the best practice in this kind of situation?
在这种情况下,最佳做法是什么?
I also want to know how it works for the c stdlib. In my program I used the stdio functions and it worked after cross compiling without doing anything special. I just provided path for my arm gcc in makefile. So, I want to know, how it got correct std headers and libs?
我也想知道它对 c stdlib 是如何工作的。在我的程序中,我使用了 stdio 函数,它在交叉编译后工作,没有做任何特殊的事情。我只是在 makefile 中为我的 arm gcc 提供了路径。所以,我想知道,它是如何获得正确的标准头文件和库的?
采纳答案by gerrit zijlstra
Regarding your general questions:
关于您的一般问题:
Why the C library works:
为什么 C 库有效:
The C library is part of your cross toolchain. That's why the headers are found and the program correctly links and runs. This is also true for some other very basic system libraries like libm and libstdc++ (not in every case, depends on the toolchain configuration).
C 库是您的交叉工具链的一部分。这就是为什么找到标题并且程序正确链接和运行的原因。对于其他一些非常基本的系统库,如 libm 和 libstdc++(并非在所有情况下,取决于工具链配置)也是如此。
In general when dealing with cross-development you need some way to get your desired libraries cross-compiled. Using binaries in this case is very rare. That is, especially with ARM hardware, because there are so many different configurations and often everything is stripped down much in different ways. That's why binaries are not very much binary compatible between different devices and Linux configurations.
通常,在处理交叉开发时,您需要某种方式来交叉编译所需的库。在这种情况下使用二进制文件是非常罕见的。也就是说,尤其是对于 ARM 硬件,因为有很多不同的配置,而且通常所有东西都以不同的方式进行了大量精简。这就是为什么二进制文件在不同设备和 Linux 配置之间不是非常兼容的原因。
If you're running Ubuntu on the Raspberry Pi then there is a chance that you may find a suitable ncurses library on the internet or even in some Ubuntu apt repository. The typical way, however, will be to cross compile the library with the specific toolchain you have got.
如果您在 Raspberry Pi 上运行 Ubuntu,那么您可能会在 Internet 上甚至某些 Ubuntu apt 存储库中找到合适的 ncurses 库。然而,典型的方法是使用您拥有的特定工具链交叉编译库。
In cases when a lot and complex libraries need to be cross-compiled there are solutions that make life a bit easier like buildroot or ptxdist. These programs build complete Linux kernels and root file systems for embedded devices.
在需要交叉编译大量复杂库的情况下,有一些解决方案可以使生活更轻松,例如 buildroot 或 ptxdist。这些程序为嵌入式设备构建完整的 Linux 内核和根文件系统。
In your case, however, as long as you only want ncurses you can compile the source code yourself. You just need to download the sources, run configure
while specifying your toolchain using the --host
option. The --prefix
option will choose the installation directory. After running make
and make install
, considering everything went fine, you will have got a set of headers and the ARM-compiled library for your application to link against.
但是,在您的情况下,只要您只需要 ncurses,您就可以自己编译源代码。您只需要下载源代码,configure
在使用--host
选项指定工具链的同时运行。该--prefix
选项将选择安装目录。运行make
and 后make install
,考虑到一切正常,您将获得一组头文件和 ARM 编译的库供您的应用程序链接。
Regarding cross compilation you will surely find loads of information on the internet and maybe ncurses has got some pointers in its shipped documentation, too.
关于交叉编译,您肯定会在互联网上找到大量信息,也许 ncurses 在其附带的文档中也有一些指示。
回答by Mats Petersson
Clearly, you will need an ncurses
compiled for the ARM that you are targeting - the one on the host will do you absolutely no good at all [unless your host has an ARM processor - but you said x86, so clearly not the case].
显然,您将需要ncurses
针对您所针对的 ARM进行编译 - 主机上的那个绝对不会对您有任何好处[除非您的主机具有 ARM 处理器 - 但您说的是 x86,显然不是这种情况]。
There MAY be some prebuilt libraries available, but I suspect it's more work to find one (that works and matches your specific conditions) than to build the library yourself from sources - it shouldn't be that hard, and I expect ncurses
doesn't take that many minutes to build.
可能有一些可用的预构建库,但我怀疑找到一个(可以工作并符合您的特定条件)比自己从源代码构建库需要更多的工作-它不应该那么难,我希望ncurses
不会花费需要几分钟的时间来构建。
回答by TwoCode
As to your first question, if you intend to use ncurses library with your cross-compiler toolchain, you'll have its arm-built binaries prepared.
关于您的第一个问题,如果您打算将 ncurses 库与您的交叉编译器工具链一起使用,您将准备好其 arm 构建的二进制文件。
Your second question is how it works with std libs, well it's really NOT the system libc/libm the toolchain is using to compile/link your program is. Maybe you'll see it from --print-file-name=option of your compiler:
你的第二个问题是它如何与标准库一起工作,它真的不是工具链用来编译/链接你的程序的系统 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
I think your Raspberry toolchain might be the same. You can try this out.
我认为您的 Raspberry 工具链可能是相同的。你可以试试这个。
回答by vinay hunachyal
For the query How the C library works in cross-tools
对于查询 How the C library works in cross-tools
When compiling and building cross-tool chain during configuration they will provide sysroot.
在配置期间编译和构建跨工具链时,它们将提供 sysroot。
like --with-sysroot=${CLFS_CROSS_TOOLS}
喜欢 --with-sysroot=${CLFS_CROSS_TOOLS}
--with-sysroot
--with-sysroot=dir
--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.
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.
So instead of looking /lib /usr/include
it will look /Toolchain/(libc) and (include files) when its compiling
因此,/lib /usr/include
它在编译时将看起来 /Toolchain/(libc) 和 (include files)而不是查看
you can check by
你可以通过
arm-linux-gnueabihf-gcc -print-sysroot
arm-linux-gnueabihf-gcc -print-sysroot
this show where to look for libc .
这显示在哪里寻找 libc 。
also
还
arm-linux-gnueabihf-gcc -print-search-dirs
arm-linux-gnueabihf-gcc -print-search-dirs
gives you clear picture
给你清晰的画面
回答by anaken78
Vinay's answer is pretty solid. Just a correction when compiling the ncurses library for raspberry pi the option to set your rootfs is --sysroot=<dir>
and not --with-sysroot
. Thats what I found when I was using the following compiler:
维奈的回答非常可靠。只是在为 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 (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.