gcc编译和交叉编译_32位生命支持:与GCC交叉编译

gcc编译和交叉编译

如果您是创建二进制程序包(例如RPM,DEB,Flatpak或Snap)的开发人员,则必须为各种不同的目标平台编译代码。 典型目标包括32位和64位x86和ARM。 您可以在不同的物理或虚拟机上进行构建,但这意味着要维护多个系统。 相反,您可以使用GNU编译器集合( GCC )进行交叉编译,从而在一台构建机器上为几种不同的体系结构生成二进制文件。

假设您有一个想要交叉编译的简单掷骰子游戏。 在大多数系统上,用C编写的东西相对容易,因此为了现实起见,我增加了复杂性,我用C ++编写了这个示例,因此程序依赖于C中不存在的东西(特别是iostream )。


   
   
#include <iostream>
#include <cstdlib>

using namespace std ;

void lose ( int c ) ;
void win ( int c ) ;
void draw ( ) ;

int main ( ) {
  int i ;
    do {
      cout << "Pick a number between 1 and 20: \n " ;
      cin >> i ;
      int c = rand ( ) % 21 ;
      if ( i > 20 ) lose ( c ) ;
      else if ( i < c ) lose ( c ) ;
      else if ( i > c ) win ( c ) ;
      else draw ( ) ;
      }
      while ( 1 == 1 ) ;
      }

void lose ( int c )
  {
    cout << "You lose! Computer rolled " << c << " \n " ;
  }

void win ( int c )
  {
    cout << "You win!! Computer rolled " << c << " \n " ;
    }

void draw ( )
    {
      cout << "What are the chances. You tied. Try again, I dare you! \n " ;
    }

使用g ++命令在您的系统上编译它:

 $  g++ dice.cpp -o dice 

然后运行它以确认它是否有效:


   
   
$ . / dice
Pick a number between 1 and 20 :
[ ... ]

您可以使用file命令查看刚刚生成的二进制文件类型


   
   
$ file . / dice
dice: ELF 64 -bit LSB executable, x86- 64 , version 1 ( SYSV ) , dynamically
linked ( uses shared libs ) , for GNU / Linux 5.1.15, not stripped

同样重要的是,它使用ldd链接到哪些库:


   
   
$ ldd dice
linux-vdso.so.1 = > ( 0x00007ffe0d1dc000 )
libstdc++.so.6 = > / usr / lib / x86_64-linux-gnu / libstdc++.so.6
( 0x00007fce8410e000 )
libc.so.6 = > / lib / x86_64-linux-gnu / libc.so.6
( 0x00007fce83d4f000 )
libm.so.6 = > / lib / x86_64-linux-gnu / libm.so.6
( 0x00007fce83a52000 )
/ lib64 / ld-linux-x86- 64 .so.2 ( 0x00007fce84449000 )
libgcc_s.so.1 = > / lib / x86_64-linux-gnu / libgcc_s.so.1
( 0x00007fce8383c000 )

您已经从这些测试中确认了两件事:您刚运行的二进制文件是64位,并且已链接到64位库。

这意味着,为了交叉编译为32位,必须告诉g ++

  1. 产生一个32位二进制文​​件
  2. 链接到32位库,而不是默认的64位库

设置您的开发环境

要编译为32位,您需要在系统上安装32位库和标头。 如果运行纯64位系统,则没有32位库或头文件,并且需要安装基本集。 至少,您需要C和C ++库( glibclibstdc ++ )以及32位版本的GCC库( libgcc )。 这些软件包的名称可能因发行版本而异。 在Slackware上, Alien BOB提供的multilib软件包提供了具有32位兼容性的纯64位发行版。 在Fedora,CentOS和RHEL上:


   
   
$ yum install libstdc++- * .i686
$ yum install glibc- * .i686
$ yum install libgcc.i686

无论使用什么系统,都必须安装项目使用的所有32位库。 举例来说,如果你在项目中包含YAML-CPP,则必须安装YAML-CPP的32位版本,或者在许多系统上,开发包YAML的CPP(例如在Fedora YAML-CPP-devel的 ),然后进行编译。

处理完之后,编译就相当简单了:

 $  g++ -m32 dice.cpp -o dice32 -L / usr / lib -march =i686 

-m32标志告诉GCC以32位模式进行编译。 -march = i686选项进一步定义了要使用的优化类型(有关选项列表,请参阅info gcc )。 -L标志设置要GCC链接到的库的路径。 对于32位,这通常是/ usr / lib ,但是根据系统的设置,它可能是/ usr / lib32甚至是/ opt / usr / lib或您知道保留32位库的任何位置。

代码编译后,请参见构建证明:


   
   
$ file . / dice32
dice: ELF 32 -bit LSB executable, Intel 80386 , version 1 ( SYSV ) ,
dynamically linked ( uses shared libs ) [ ... ]

而且,当然, ldd ./dice32指向您的32位库。

不同的架构

当您针对同一系列进行交叉编译时,可以期望找到与64位库相同的一组32位库,因为您的Linux发行版同时维护了这两个库。 在为完全不同的体系结构进行编译时,您可能必须寻找代码所需的库。 您所需的版本可能不在发行版本的存储库中,因为您的发行版本可能未提供目标系统的软件包,或者未在方便的位置镜像所有软件包。 如果您要编译的代码是您自己的代码,那么您可能对它的依赖项以及可能在哪里找到它们有个好主意。 如果代码是您下载的并且需要编译,则您可能不熟悉其要求。 在这种情况下,请研究正确构建代码所需的内容(它们通常列在README或INSTALL文件中,当然也包含在源代码本身中),然后收集组件。

例如,如果您需要为ARM编译C代码,则必须首先在Fedora或RHEL上安装gcc-arm-linux-gnu (32位)或gcc-aarch64-linux-gnu (64位),或arm- Ubuntu上的linux-gnueabi-gccbinutils-arm-linux-gnueabi 。 这提供了(至少)构建简单C程序所需的命令和库。 另外,您需要代码使用的任何库。 您可以将头文件放在通常的位置(在大多数系统上为/ usr / include ),也可以将它们放在您选择的目录中,并使用-I选项将GCC指向它。

编译时,请勿使用标准的gccg ++命令。 而是使用您安装的GCC实用程序。 例如:


   
   
$ arm-linux-gnu-g++ dice.cpp \
  -I / home / seth / src / crossbuild / arm / cpp \
  -o armdice.bin

验证您构建的内容:


   
   
$ file armdice.bin
armdice.bin: ELF 32 -bit LSB executable, ARM, EABI5 version 1 ( SYSV ) [ ... ]

图书馆和交付品

这是有关如何使用交叉编译的简单示例。 在现实生活中,您的源代码可能产生的不仅仅是一个二进制文件。 虽然您可以手动进行管理,但没有充分的理由这样做。 在我的下一篇文章中,我将演示GNU Autotools,它完成了使代码可移植的大部分工作。

翻译自: https://opensource.com/article/19/7/cross-compiling-gcc

gcc编译和交叉编译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
armgcc交叉编译的文件无法运行可能有多种原因,以下是一些常见的解决方法: 1. 确认交叉编译器是否正确安装:在命令行中输入arm-none-linux-gnueabi-gcc -v,确认是否能够正确输出版本信息。如果不能输出,则需要重新安装交叉编译器。 2. 确认编译选项是否正确:在编译时需要指定正确的交叉编译器和选项,例如:arm-none-linux-gnueabi-gcc -o output_file input_file.c -static。如果编译选项不正确,可能会导致生成的文件无法运行。 3. 确认目标平台是否正确:在交叉编译时需要指定目标平台的架构和操作系统,例如:arm-none-linux-gnueabi-gcc -march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -o output_file input_file.c。如果目标平台不正确,可能会导致生成的文件无法运行。 4. 确认库文件是否正确链接:在交叉编译时需要指定正确的库文件路径和链接选项,例如:arm-none-linux-gnueabi-gcc -o output_file input_file.c -L/path/to/lib -lmylib。如果库文件链接不正确,可能会导致生成的文件无法运行。 5. 确认文件权限是否正确:在生成可执行文件后,需要使用chmod命令修改文件权限,例如:chmod +x output_file。如果文件权限不正确,可能会导致无法运行。 针对iMX287A交叉编译环境搭建,需要根据具体的操作系统和开发环境来选择交叉编译器和库文件等。一般的步骤如下: 1. 下载安装交叉编译器:可以从官方网站下载适用于iMX287A的交叉编译器,例如imx28-gcc-4.6.2.tar.bz2。 2. 配置环境变量:将交叉编译器的路径添加到PATH环境变量中,例如:export PATH=/path/to/cross-compiler/bin:$PATH。 3. 下载安装库文件:需要根据具体的需求下载并安装iMX287A所需要的库文件,例如libxml2、zlib、openssl等。 4. 配置编译选项:在编译时需要指定正确的交叉编译器和选项,例如:arm-none-linux-gnueabi-gcc -o output_file input_file.c -I/path/to/include -L/path/to/lib -lmylib。 5. 生成可执行文件:使用交叉编译器生成可执行文件,例如:arm-none-linux-gnueabi-gcc -o output_file input_file.c。 6. 调试和测试:将生成的可执行文件烧录到iMX287A开发板上,并进行调试和测试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值