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

news2025/4/8 16:57:34

前言:

源文件需要经过编译才能生成可执行文件。在 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)

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

x264交叉编译(ubuntu+arm)

1.下载源码 https://code.videolan.org/videolan/x264 在windows下解压&#xff1b;复制到ubuntu&#xff1b; 2.进入源码文件夹-新建脚本文件 touch sp_run.sh 3.在sp_run.sh文件中输入 #!/bin/sh./configure --prefix/home/alientek/sp_test/x264/sp_install --enable-…

Gradle中的依赖Dependencies说明与使用总结

【1】依赖的方式 Gradle 中的依赖分别为直接依赖&#xff0c;项目依赖&#xff0c;本地jar 依赖。 dependencies {//①.依赖当前项目下的某个模块[子工程]implementation project(:subject01)//②.直接依赖本地的某个jar文件implementation files(libs/foo.jar, libs/bar.jar…

Vue3.0 路由

简介 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。功能包括&#xff1a; 嵌套路由映射动态路由选择模块化、基于组件的路由配置路由参数、查询、通配符展示由 Vue.js 的过渡系统提供的过渡效果细致的导航控…

思考的起点(一): 事实与判断

事实与判断是思考的主要组成部分&#xff0c;深入理解事实与判断的基本概念&#xff0c;了解其应用可以提升个体的思考质量; 关于事实真相 事实是认知的基础 1.很多事情没有真相, 或者说真相陷入历史的迷雾中, 无法被发现; 2.世界不需要真相&#xff0c;真相往往都是复杂又残…

算法题:144.二叉树的前序遍历(递归、迭代)Java Python部分

1、递归法 其实递归法提交结果也挺好看的&#xff0c;代码如下&#xff1a; class Solution {//前序遍历public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res new ArrayList<Integer>();preorder(root, res);return res;}public vo…

木马捆绑+签名修改(CobaltStrike免杀)

今天我们就来聊一下什么是捆绑木马,说起捆绑木马我相信一些人肯定觉得很陌生。在日常中我相信大家经常可能会遇到这样的一个问题,在一些网站上下载一个电脑软件结果电脑上就被莫名其妙的安装上了一个全家桶(流氓软件)。这就是通过简单的捆绑技术将一些你不需要的广告软件安…

【漏洞复现】Apache_HTTP_2.4.50_路径穿越漏洞(CVE-2021-42013)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证方式一 curl方式二 bp抓捕 1.5、修复建议 说明内容漏洞编号CVE-2021-42013漏洞名称…

CUMT-----Java课后第五章编程题

文章目录 一、题11.1 问题描述1.2 代码块1.3 运行截图 二、题22.1 问题描述2.2 代码块2.3 运行截图 一、题1 1.1 问题描述 (1)使用继承编写人类、教师、学生类的实体类。(2)编写测试类&#xff0c;实例化教师和学生类对象并显示。 1.2 代码块 public class Human {private S…

【Spring Security】Spring Security 认证过程源码分析

项目启动 我们在前面有了解到可以在application.yml中配置用户名密码,那么可以猜想:肯定是在项目启动的时候加载的,我们通过鼠标点击 进入SecurityProperties,我们在User中的getName上打断点,这样项目启动的时候就可以走到这里 之后我们通过点击:Drop Frame可以往回走进…

MapReduce WordCount程序实践(IDEA版)

环境 Linux&#xff1a;Hadoop2.x Windows&#xff1a;jdk1.8、Maven3、IDEA2021 步骤 编程分析 编程分析包括&#xff1a; 1.数据过程分析&#xff1a;数据从输入到输出的过程分析。 2.数据类型分析&#xff1a;Map的输入输出类型&#xff0c;Reduce的输入输出类型&#x…

C++指针笔记

一.定义 是什么&#xff1f; 指针就是地址&#xff0c;相当于门牌号。通过 0x0000也可以拿到该地址里的数据&#xff0c; 可是如果每创建一个变量都要去记住地址编号不太方便我们使用数据&#xff0c;所以才有变量。作用&#xff1f; 通过指针(地址)间接访问内存。内存的编号…

YOLO目标检测数据集大全【含voc(xml)、coco(json)和yolo(txt)三种格式标签+划分脚本+训练教程】(持续更新建议收藏)

一、作者介绍&#xff1a;资深图像算法工程师&#xff0c;YOLO算法专业玩家&#xff1b;擅长目标检测、语义分割、OCR等。 二、数据集介绍&#xff1a; 真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;分享的绝大部分数据集已应用于各种实际落地项目。所有数据…

在CARLA中获取CARLA自动生成的全局路径规划

CARLA生成全局路径规划的代码在 carla/PythonAPI/carla/agents/navigation 在自己的carla客户端py文件中 from agents.navigation.basic_agent import BasicAgent # pylint: disableimport-error 如果是pycharm开发&#xff0c;要在pycharm的Settings - Project Structure…

高防CDN:游戏应用抵御DDoS攻击的坚固堡垒

在当今的数字时代&#xff0c;游戏应用已经成为人们生活的一部分&#xff0c;而面临的网络威胁也日益复杂。其中&#xff0c;DDoS&#xff08;分布式拒绝服务&#xff09;攻击是游戏应用的一项严重威胁&#xff0c;可能导致游戏服务不可用&#xff0c;用户流失&#xff0c;以及…

卷积与反卷积

文章目录 1 卷积1.1 卷积后的输出维度 2 反卷积2.1 来源2.2 原理2.3 使用2.3.1 padding2.3.2 strideoutput_padding 2.3 意义 1 卷积 1.1 卷积后的输出维度 设输入维度为i x i&#xff0c;卷积核大小为k x k&#xff0c;padding为p&#xff0c;strides为s&#xff0c;则输出维…

NSSCTF第10页(3)

[LitCTF 2023]彩蛋 第一题&#xff1a; LitCTF{First_t0_The_k3y! (1/?) 第三题&#xff1a; <?php // 第三个彩蛋&#xff01;(看过头号玩家么&#xff1f;) // R3ady_Pl4yer_000ne (3/?) ?> 第六题&#xff1a; wow 你找到了第二个彩蛋哦~ _S0_ne3t? (2/?) 第七题…

中文sd:SkyPaint-AI-Diffusion

https://huggingface.co/SkyworkAIGC/SkyPainthttps://huggingface.co/SkyworkAIGC/SkyPainthttps://github.com/SkyWorkAIGC/SkyPaint-AI-Diffusionhttps://github.com/SkyWorkAIGC/SkyPaint-AI-Diffusion从model_index.json看&#xff0c;应该算是标准的sd1.5架构了。 {&quo…

LangChain+LLM实战---向量数据库介绍

原文&#xff1a;Vector Databases Embeddings是由人工智能模型(如大型语言模型)生成的&#xff0c;具有大量的属性或特征&#xff0c;使其表示难以管理。在人工智能和机器学习的背景下&#xff0c;这些特征代表了数据的不同维度&#xff0c;这些维度对于理解模式、关系和底层…

win10 + cmake3.17 编译 giflib5.2.1

所有源文件已经打包上传csdn&#xff0c;大家可自行下载。 1. 下载giflib5.2.1&#xff0c;解压。 下载地址&#xff1a;GIFLIB - Browse Files at SourceForge.net 2. 下载CMakeLists.txt 及其他依赖的文件 从github上的osg-3rdparty-cmake项目&#xff1a; https://github.…

加密解密基础知识Crypto Basics

base64编码 编码不是真正的密码学&#xff0c;但它在围绕加密功能的各种标准中被大量使用。尤其是 Base64 编码。 Base64 编码是一种用于将各种字节转换为特定字节范围的技术。此特定范围是 ASCII 可读字节。 这样&#xff0c;您可以更轻松地传输二进制数据&#xff0c;例如密…