【问题标题】:Cross compilation requirements for CC 的交叉编译要求
【发布时间】:2010-11-08 00:24:48
【问题描述】:

我有一些关于编译 C 的基本知识,但需要回答几个通用的交叉编译问题。就我而言,我试图在我的 Fedora Linux 机器上交叉编译一个程序,该程序将在 ARM 单板计算机上运行。

  1. 我的第一个问题是关于标题的。我已经下载了 arm Linux 工具包,它包含头文件,例如包含目录中的 stdio.h。当我交叉编译时,我应该使用这个“目标”包含目录而不是我的系统包含目录吗?还是可以指向我系统的包含目录,例如 /usr/include? (当我对它们进行比较时,这些头文件似乎有所不同。)

  2. 如果头文件不存在会发生什么。就我而言,我还计划在 ARM 板上使用 cURL 库。我可以简单地指向我下载的 curl 源包中存在的包含目录而不用担心目标架构吗?如果是,这是否意味着我的第一个问题无关紧要?

  3. 假设我想静态链接到一个库。在发生这种情况之前,是否需要为目标 ARM 平台编译这个静态库?或者我可以直接使用我系统上安装的静态库(希望交叉编译过程能够处理业务)?

  4. 如果我决定动态链接到一个库,唯一的要求是目标系统已经为 ARM 编译了这个库并安装在 ARM 板上的 LD_LIBRARY_PATH 目录之一中,对吗?

感谢您的帮助。

【问题讨论】:

    标签: c arm cross-compiling


    【解决方案1】:
    1. 始终使用目标标头。它们可能与您的主机标头不同。编译器应该已经将它们作为标准问题的默认包含路径的一部分,例如 libc。
    2. 您需要使用交叉编译器将 cURL 构建到一个虚假的“目标”系统目录中,并在此目标目录中使用 cURL 构建您的应用程序。由于您还需要一个 cURL 库,因此您必须使用交叉编译器。对于对交叉编译不友好的编译(例如构建程序并作为编译的一部分运行),您将需要修改构建过程。有时fakeroot 对脏构建系统很有帮助。
    3. 您不能随意将静态库用于与您的系统不同的体系结构。它们必须由交叉编译器构建。
    4. 不正确。图书馆通常必须在场。

    【讨论】:

    • 扩展第 1 点:应该已经设置了交叉编译器环境,以便裸 #include <stdio.h> 引用头文件的 ARM 版本(即,它应该在 @987654323 以外的地方寻找@)。
    • 能否请您详细说明第二项?我对“因为你也需要一个 cURL 库,所以你必须使用交叉编译器”感到特别困惑。句子。您在第一句话中不是已经介绍了这一步吗?
    • @Burak:您的 ARM 交叉编译器极不可能附带 cURL。如果没有,您需要构建一个迷你“根文件系统”以允许编译和链接工作。存在诸如 buildroot 和 OpenEmbedded 之类的框架是有原因的 - 交叉编译可能会很痛苦
    【解决方案2】:

    您打算使用的任何库(包括 libc)都必须针对目标平台构建,然后才能链接到它。使用目标标头而不是主机标头进行构建,这样您就可以放心使用正确的 API。

    【讨论】:

      【解决方案3】:

      如果您可以控制两个编译器中的包含路径和工具链,则需要确保您为每个要编译的系统都有一个特定于平台的实现。嵌入式系统通常会创建模拟头来满足常用的头,例如<stdio.h><stdlib.h><math.h>。然后,平台特定的编译器/设置使用这些公共头文件的不同库进行编译。因此,使用裸 #include <stdio.h> 没有问题。

      如果您可以访问编译器可以创建单独的包含路径,您可以为每个平台构建单独的库。

      如果您像我一样无法直接访问编译器(供应商 SDK 将其隐藏,使其难以解决),那么您需要创建一个模拟标头,该标头根据获取的标签定义标头在编译时由上游依赖项设置。应该有一些由编译器在上游标头中设置的魔术标志,您可以查找这些标志以确定是否应该为嵌入式与主机系统创建标头,例如 #if defined(__TMS320C6X__) && defined(__TI_EABI__) 以帮助区分。您可以在嵌入式库中挖掘包含文件以获取示例(stddef.h 通常是一个很好的参考)。对于嵌入式系统,使用具有唯一名称(例如 #define _MyHeader_H)的标头保护来标记标头已定义。最后,您可以使用#ifndef _MyHeader_H 创建主机系统标头作为后备案例。

      考虑一个你需要<complex.h>的情况,它是为嵌入式系统而不是主机系统定义的。

      您将拥有 3 个头文件:一个用于区分需要哪个交叉编译的虚拟头文件、一个嵌入式系统实现和一个主机实现。

      complex_choice.h

      #if __STDC_VERSION__ >= 199901L
      #include <complex.h>
      #endif //using a C99 compiler
      #include <complex_host.h>  // ! using a C99 compiler
      

      复杂的.H

      #ifndef _COMPLEX_H
      #define _COMPLEX_H
      //Embedded system implmentation here
      #endif /* _COMPLEX_H */
      

      complex_host.H

      #ifndef _COMPLEX_H
      #define _COMPLEX_H
      //Host system implmentation here
      #endif /* _COMPLEX_H */
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-15
        • 2018-01-10
        • 2017-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多