Linux应用开发基础知识——交叉编译与gcc编译(一)

前言:

源文件需要经过编译才能生成可执行文件。在 Windows 下进行开发时,只需 要点几个按钮即可编译,集成开发环境(比如 Visual studio)已经将各种编译 工具的使用封装好了。Linux 下也有很优秀的集成开发工具,但是更多的时候是 直接使用编译工具;即使使用集成开发工具,也需要掌握一些编译选项。 PC 机上的编译工具链为 gcc、ld、objcopy、objdump 等,它们编译出来的 程序在 x86 平台上运行。要编译出能在 ARM 平台上运行的程序,必须使用交叉编 译工具 xxx-gcc、xxx-ld 等(不同版本的编译器的前缀不一样,比如 arm-linuxgcc),下面分别介绍。

目录

一、交叉编译 hello.c

1.gcc编译

​编辑

2 .交叉编译、测试 tslib

二、 hello程序的引申

1.怎么确定交叉编译器中头文件的默认路径?

2.怎么自己指定头文件目录?

3.怎么确定交叉编译器中库文件的默认路径?

4.怎么自己指定库文件目录、指定要用的库文件?

三、GCC 编译器的使用

GCC 编译过程

(1)编译流程

(2)编译步骤

(3)gcc 使用示例

(4)常用编译选项

(5)怎么编译多个文件

(6)制作、使用动态库

(7)制作、使用静态库

(8)动态库与静态库区别

(9)很有用的选项 


一、交叉编译 hello.c

1.gcc编译

hello.c 的源码如下:

#include <stdio.h>


/* 执行命令: ./hello abcd 
 * argc = 2
 * argv[0] = ./hello
 * argv[1] = abcd
 */

int main(int argc, char **argv)
{
	if (argc >= 2)
		printf("Hello, %s!\n", argv[1]);
	else
		printf("Hello, world!\n");
	return 0;
}


在 Ubuntu 中可以执行以下命令编译、执行:


book@100ask:~$ gcc -o hello hello.c
book@100ask:~$
book@100ask:~$ ./hello

        上述命令编译得到的可执行程序 hello 可以在 Ubuntu 中运行,但是如果把 它放到 ARM 板子上去,它是无法执行的。因为它是使用 gcc 编译的,是给 PC 机 编译的,里面的机器指令是 x86 的。 

查看hello文件类型

file hello

2 .交叉编译、测试 tslib

 我们要想给 ARM 板编译出 hello 程序,需要使用交叉编译工具链,比如:

arm-buildroot-linux-gnueabihf-gcc -o hello hello.c

这样编译出来的 hello 程序才可以在 ARM 板子上运行。

Ubuntu目录/home/book/nfs_rootfs挂载到开发板的/mnt中:

[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

交叉编译配置 :

// 对于 IMX6ULL,命令如下
book@100ask:~$ export ARCH=arm
book@100ask:~$ export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
book@100ask:~$ export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin

交叉编译 tslib:

// 对于 IMX6ULL,命令如下
book@100ask:~$ arm-buildroot-linux-gnueabihf-gcc -o hello hello.c
book@100ask:~$ file hello

拷贝到挂载目录上: 

book@100ask:~$ cp hello /home/book/nfs_rootfs/

在开发板上再次执行./hello的程序成功运行 

二、 hello程序的引申

1.怎么确定交叉编译器中头文件的默认路径?

        位于系统目录,进入交叉编译器的目录里,执行:find -name “stdio.h”,它位于一个 “include”目录下的根目录里。这个“include”目录,就是要找的路径。

2.怎么自己指定头文件目录?

        编译时,加上“-I ”这样的选项。

3.怎么确定交叉编译器中库文件的默认路径?

        位于系统目录,进入交叉编译器的目录里,执行:find -name lib,可以得到 xxxx/lib、 xxxx/usr/lib,一般来说这 2 个目录就是要找的路径。如果有很多类似的 lib, 进去看看,有很多 so 文件的目录一般就是要找的路径。

4.怎么自己指定库文件目录、指定要用的库文件?

        编译时,加上“-L ”这样的选项,用来指定库目录;

        编译时,加上“-labc”这样的选项,用来指定库文件 libabc.so。

三、GCC 编译器的使用

GCC 编译过程

(1)编译流程

        一个 C/C++文件要经过预处理(preprocessing)、编译(compilation)、汇 编(assembly)和链接(linking)等 4 步才能变成可执行文件。

通过不同的 gcc 选项可以控制这些过程:

        

        在日常交流中通常使用“编译”统称这 4 个步骤,如果不是特指这 4 个步骤 中的某一个,本教程也依惯例使用“编译”这个统称。

进入事先准备好的文件中  

book@100ask:~/02_options/01_hello$  cd 02_options/01_hello
gcc -o hello hello.c // 输出名为 hello 的可执行程序,然后可以执行./hello

(2)编译步骤

执行“gcc -o hello hello.c -v”时,可以查看到这些步骤

gcc -o hello hello.c -v

cc1 main.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccZfdaDo.o /tmp/ccXCx1YG.s

cc1 sub.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccn8Cjq6.o /tmp/ccXCx1YG.s

collect2 -o test /tmp/ccZfdaDo.o /tmp/ccn8Cjq6.o ....

 可以手工执行以下命令体验一下这4个步骤:

gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o

 1)执行  gcc -E -o hello.i hello.c  生成的hello.i文件

进行预处理把.c文件里的头文件找到,编译开关用起来,宏定义展开

 

2)执行gcc -S -o hello.s hello.i  生成的hello.s文件

进行编译生成各种汇编

3)执行 gcc -c -o hello.o hello.s 生成hello.o文件

进行汇编生成机器语言

4)执行 gcc -o hello hello.o 生成hello文件

进行链接为应用程序

(3)gcc 使用示例

gcc hello.c // 输出一个名为 a.out 的可执行程序,然后可以执行./a.out
gcc -o hello hello.c // 输出名为 hello 的可执行程序,然后可以执行./hello
gcc -o hello hello.c -static // 静态链接
gcc -c -o hello.o hello.c // 先编译(不链接)
gcc -o hello hello.o // 再链接

(4)常用编译选项

        在我们编程中会经常出现找不到头文件的错误,我们可以指定执行当前目录,当前目录没有的时候再去系统文件库里寻找。   

 

(5)怎么编译多个文件

1)一起编译、链接:

gcc -o test main.c sub.c

2)分开编译,统一链接:

gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -o test main.o sub.o

(6)制作、使用动态库

第1步 制作、编译:

book@100ask:~/02_multi_files$ gcc -c -o main.o main.c
book@100ask:~/02_multi_files$ gcc -c -o sub.o sub.c
book@100ask:~/02_multi_files$ gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多个.o 生成动态库)
book@100ask:~/02_multi_files$ gcc -o test2 main.o -L ./ -lsub

 

 第2步 运行:

先把 libsub.so 放到 Ubuntu 的/lib 目录,然后就可以运行 test2程序。

如果不想把 libsub.so 放到/lib,也可以放在某个目录比如/a,然后如下执行: 

book@100ask:~/02_multi_files$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./

(7)制作、使用静态库

book@100ask:~/02_multi_files$ gcc -c -o main.o main.c
book@100ask:~/02_multi_files$ gcc -c -o sub.o sub.c
book@100ask:~/02_multi_files$ ar crs libsub.a sub.o
book@100ask:~/02_multi_files$ gcc -o test main.o libsub.a

运行:不需要把静态库 libsub.a 放到板子上。

注意:执行   arm-buildroot-linux-gnueabihf-gcc -c -o sub.o sub.c   交叉编译需要在最后面加上-fPIC 参数。

(8)动态库与静态库区别

test:链接了静态库libsub.a,但是其他库是动态链接的

test2:链接了动态库libsub.so,其他库也是动态链接的

(9)很有用的选项 

gcc -E main.c // 查看预处理结果,比如头文件是哪个
gcc -E -dM main.c > 1.txt // 把所有的宏展开,存在 1.txt 里
gcc -Wp,-MD,abc.dep -c -o main.o main.c // 生成依赖文件 abc.dep,后面 Makefile 会用
echo 'main(){}'| gcc -E -v - // 它会列出头文件目录、库目录(LIBRARY_PATH)

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/116776.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【复盘】记录一次JVM 异常问题 java.lang.OutOfMemoryError: unable to create new native thread

背景是最新运营提了一个需求&#xff0c;需要根据用户信息拉去三分机构的信贷数据&#xff0c;需要达到一天百万级别&#xff0c;但是经过实际测试&#xff0c;也只能达到40W量级&#xff0c;具体就是通过起多个Spring Boot项目&#xff0c;每个项目1S拉一个用户&#xff0c;基…

【Head First 设计模式】-- 观察者模式

背景 客户有一个WeatherData对象&#xff0c;负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求&#xff0c;让我们利用WeatherData对象取得数据&#xff0c;并更新三个布告板&#xff1a;目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口&#xff1a; …

网络验证码--你到底是爱它还是恨它?

互联网安全防火墙&#xff08;1&#xff09;--网络验证码的科普 1 戏言部分 为了在网络上吸引大家读这个文章&#xff0c;在想标题的时候&#xff0c;也是够了。本来是严肃的科普学术帖&#xff0c;但是却一股强烈的“不转不是中国人&#xff0c;让男孩沉默女孩流泪” 这种…

OpenSSL生成CA证书

基本概念 证书类别 根证书&#xff1a;生成服务端证书&#xff0c;客户端证书的基础。自签名。服务端证书&#xff1a;由根证书签发。配置在服务器上。客户端证书&#xff1a;由根证书签发。配置在浏览器、移动APP等客户端上。 认证方式 单向认证&#xff08;Client鉴权Serv…

《视觉SLAM十四讲》-- 概述与预备知识

文章目录 01 概述与预备知识1.1 SLAM 是什么1.1.1 基本概念1.1.2 视觉 SLAM 框架1.1.3 SLAM 问题的数学表述 1.2 实践&#xff1a;编程基基础1.3 课后习题 01 概述与预备知识 1.1 SLAM 是什么 1.1.1 基本概念 &#xff08;1&#xff09;SLAM 是 Simultaneous Localization a…

第二章 02Java基础-数据类型、标识符、键盘录入

文章目录 前言一、数据类型二、标识符三、键盘录入总结前言 今天我们学习Java基础,数据类型、标识符、键盘录入 一、数据类型 1.数据类型大体上可以分为两类,一类是基本数据类型,另外一类是引用数据类型。今天我们学习基本数据类型。 2.基本数据类型可以分为四类八种,整…

【网络安全技术】公钥密码体制

一、两种基本模型 1.加密模型 A要给B发信息&#xff0c;那就拿B的公钥加密&#xff0c;传给B&#xff0c;B收到后会拿他自己的私钥解密得到明文。 2.认证模型&#xff08;数字签名&#xff09; A用自己的私钥加密&#xff0c;传输之后&#xff0c;别人拿A的公钥解密&#xff…

亚马逊云科技大语言模型下的六大创新应用功能

目录 前言 亚马逊云科技的AI创新应用 ​编辑 Amazon CodeWhisperer Amazon CodeWhisperer产品的优势 更快地完成更多工作 自信地进行编码 增强代码安全性 使用收藏夹工具 自定义 CodeWhisperer 以获得更好的建议 如何使用Amazon CodeWhisperer 步骤 1 步骤 2 具体…

辅助驾驶功能开发-功能规范篇(22)-9-L2级辅助驾驶方案功能规范

1.3.7.2 行人、骑行者(横向)AEB 系统 1.3.7.2.1 状态机 1.3.7.2.2 信号需求列表 同 1.3.2.1.2。 1.3.7.2.3 系统开启关闭 同 1.3.2.1.3。 触发横向 AEB 的目标包括横向运动的行人、骑行者(包括自行车、摩托车、电瓶车和平衡车上的行人)。 1.3.7.2.4 制动预填充 制动系统…

pyusb环境搭建和无法发包问题

pyusb环境搭建和无法发包问题 项目需要对usb设备进行开发调试&#xff0c;选择搭建pyusb环境进行调试测试&#xff0c;这里记录下完整流程和中间解决的一些问题。 我使用的环境是window10 64bit, vscode 1.84.0 , Python 3.11.6 1 安装流程 参考github上的 https://github.…

伪随机序列——m序列及MATLAB仿真

文章目录 前言一、m 序列1、m 序列的产生2、m 序列的性质①、均衡性②、游程分布③、移位相加特性④、自相关函数⑤、功率谱密度⑥、伪噪声特性 二、M 序列1、m 序列的产生2、m 序列的性质 三、MATLAB 中 m 序列1、m 序列生成函数的 MATLAB 代码2、MATLAB 仿真 前言 在通信系统…

Photoshop 2023 v24.7

Photoshop是一款强大的图像编辑软件&#xff0c;被广泛应用于图像处理、图形设计、数字绘画等领域。它提供了丰富的图像编辑功能&#xff0c;可以用于调整图像的色彩、亮度、对比度等&#xff0c;添加特效、滤镜&#xff0c;以及进行复杂的图像合成和修复。 以下是Adobe Photo…

基于动力学模型的机械臂滑膜控制

一、滑模控制设计思路 参考资料&#xff1a;https://zhuanlan.zhihu.com/p/463230163&#xff08;思路理解&#xff09; https://blog.csdn.net/xiaohejiaoyiya/article/details/90271529&#xff08;干扰的处理&#xff09; 滑模控制的思路有两个关键&#xff0c;一个是设计…

一文通透各种注意力:从多头注意力MHA到分组查询注意力GQA、多查询注意力MQA

前言 通过本博客内之前的文章可知&#xff0c;自回归解码的标准做法是缓存序列中先前标记的键(K)和值(V) 对&#xff0c;从而加快注意力计算速度。然而&#xff0c;随着上下文窗口或批量大小的增加&#xff0c;多头注意力 (MHA)模型中与 KV 缓存大小相关的内存成本显着增长 对…

【多线程】Lambda表达式

package org.example;public class TestLambda {public static void main(String[] args) {Like likenew Like();like.lambda();}}//定义一个函数式接口 interface ILike{void lambda(); }//实现类 class Like implements ILike{Overridepublic void lambda() {System.out.prin…

Excel自学三部曲_Part3:Excel工作场景实战(四)

文章目录 四、高级函数与数据连接1. 多窗口操作2. VLOOKUP函数3. XLOOKUP函数4. CSV数据格式 四、高级函数与数据连接 1. 多窗口操作 如何将两张子表数据&#xff08;战区信息、城市信息&#xff09;连接到主表数据&#xff08;成交数据&#xff09;&#xff0c;增加主要数据的…

“一键批量拆分HTML文本,高效整理文件,提升工作效率“

您是否曾经被大量的HTML文本文件困扰&#xff0c;难以找到所需的特定信息&#xff1f;现在&#xff0c;我们向您推荐一款强大的工具&#xff0c;它能够一键拆分HTML文本&#xff0c;让您轻松实现文件整理&#xff0c;提高工作效率&#xff01; 首先&#xff0c;在首助编辑高手…

人工智能基础_机器学习014_BGD批量梯度下降公式更新_进一步推导_SGD随机梯度下降和MBGD小批量梯度下降公式进一步推导---人工智能工作笔记0054

然后我们先来看BGD批量梯度下降,可以看到这里,其实这个公式来源于 梯度下降的公式对吧,其实就是对原始梯度下降公式求偏导以后的梯度下降公式,然后 使用所有样本进行梯度下降得来的,可以看到* 1/n 其实就是求了一个平均数对吧.所有样本的平均数. 然后我们看,我们这里* 1/n那么…

API接口安全设计

简介 HTTP接口是互联网各系统之间对接的重要方式之一&#xff0c;使用HTTP接口开发和调用都很方便&#xff0c;也是被大量采用的方式&#xff0c;它可以让不同系统之间实现数据的交换和共享。 由于HTTP接口开放在互联网上&#xff0c;所以我们就需要有一定的安全措施来保证接口…

C++11 initializer_list 轻量级初始化列表的使用场景(让自定义类可以用初始化列表的形式来实例化对象)

initializer_list 是 C11 中的一个特性&#xff0c;它允许你使用花括号 {} 中的值列表来初始化容器或数组。通常用于初始化标准库容器&#xff0c;比如 std::vector、std::set、std::map 以及数组。 场景一&#xff1a;用初始化列表初始化容器 std::vector<int> arr {…