博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gcc编译和交叉编译_32位生命支持:与GCC交叉编译
阅读量:2528 次
发布时间:2019-05-11

本文共 6197 字,大约阅读时间需要 20 分钟。

gcc编译和交叉编译

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

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

#include 
#include
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上, 提供的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,它完成了使代码可移植的大部分工作。

翻译自:

gcc编译和交叉编译

转载地址:http://lhizd.baihongyu.com/

你可能感兴趣的文章
小D课堂 - 零基础入门SpringBoot2.X到实战_第4节 Springboot2.0单元测试进阶实战和自定义异常处理_21、SpringBoot2.x配置全局异常返回自定义页面...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_32..SpringBoot2.x持久化数据方式介绍...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_34、SpringBoot整合Mybatis实操和打印SQL语句...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_36、SpringBoot整合mybatis之事务处理实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第8节 数据库操作之整合Mybaties和事务讲解_35、事务介绍和常见的隔离级别,传播行为...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_40、Redis工具类封装讲解和实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_37、分布式缓存Redis介绍...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_42、SpringBoot常用定时任务配置实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第9节 SpringBoot2.x整合Redis实战_39、SpringBoot2.x整合redis实战讲解...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第14节 高级篇幅之SpringBoot多环境配置_59、SpringBoot多环境配置介绍和项目实战...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_41、SpringBoot定时任务schedule讲解...
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第10节 SpringBoot整合定时任务和异步任务处理_43、SpringBoot2.x异步任务实战(核心知识)...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_1_01课程简介
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第11节 Logback日志框架介绍和SpringBoot整合实战_45、SpringBoot2.x日志讲解和Logback配置实战...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_汇总
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_01传统架构演进到分布式架构
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_02 微服务核心基础讲解
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_2_04微服务下电商项目基础模块设计...
查看>>
小D课堂 - 新版本微服务springcloud+Docker教程_3-01 什么是微服务的注册中心
查看>>