首页 > 其他分享 >编译相关基础知识-探究helloWorld背后的原理

编译相关基础知识-探究helloWorld背后的原理

时间:2024-04-03 16:25:49浏览次数:20  
标签:可执行文件 gcc main 指定 helloWorld 基础知识 编译 动态

1、file hello 查看文件类型

可以看到文件类型是x86_64,它是不能在ARM架构上运行的,因为它们的指令集不同。我们需要使用交叉编译工具比如arm-linux-gnueabihf-gcc来编译hello.c才能得到在ARM上运行的可执行文件

可以看的此时是32bit,ARM架构上的可执行文件

点击查看代码
#include <stdio.h>


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

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



根据上面代码,有以下几个问题:
(1).c文件有什么作用,和.h文件有什么区别
.h文件是头文件,通常包含一些函数或变量的声明
.c文件是通常包含的是函数或变量的定义

(2)include的头文件在哪里?
(3)printf函数在哪?
下面的回答来自韦东山老师教程

2、gcc编译过程
gcc是编译器的统称,包括PC平台、交叉编译工具链的gcc都是类似的功能,只是名称不一样,用法基本相同
编译过程分为四步:预处理、编译(生成汇编.s文件)、汇编(生成.o二进制文件)、链接(将.o文件链接成为可执行文件)
根据实际情况,编译可以统称上述四个步骤,也可以单独指编译生成汇编文件这一步

如何编译多个文件?

如何制作、使用动态库
什么是动态库?
动态库(Dynamic Library)是一种共享的库文件,它在程序运行时被加载到内存中,并由多个程序共享使用。在链接时,可执行文件只包含对动态库的引用,而不包含实际的库代码。运行时,动态库会被加载到操作系统指定的内存位置,并可被多个程序共享使用。因此,程序运行时依赖动态库,需要动态库保持正确性。
静态库(Static Library)是一组编译好的目标文件的集合,它们被链接到最终的可执行文件中。在编译时,静态库的代码会被完整地复制到可执行文件中,因此最终的可执行文件独立于库的存在。也因此,在运行时程序不依赖于库是否存在,但是增加了可执行文件的大小从而增加了内存使用。

动态库制作编译代码示例

点击查看代码
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多个.o 生成动态库)
从代码中我们将多个.o文件通过关键词shared链接成为动态库,并在当前目录下生成libsub.so动态库文件,.so动态库文件的后缀。编译生成动态库后我们应该如何使用? 回看上文的GCC编译常用命令,-l可以指定链接的库名称,-L可以指定编译时链接的动态库的文件路径,因此我们可以如下编译main.o文件得到可执行文件
点击查看代码
gcc -o test main.o -lsub -L /libsub.so/所在目录/
gcc -o test main.o -lsub -L ./
//其中-l指定动态库名称会省略lib前缀和.so后缀,也即-lsub相当于libsub.so,后面的./表示在当前路径下寻找动态库
这时候问题来了,我们执行生成的可执行文件,得到如下结果

提示加载时找不到链接时的动态库!为什么?
链接的时候动态库的位置和运行时是一样的吗?踩坑!
程序在运行时和编译时查找的动态库路径是不一样的,编译时你可以指定动态库所在的任意一个路径,因此编译时只是包含了对库的名称以及函数的引用,但是运行时需要将库加载到指定的内存位置,此时系统会去环境变量指定的路径中查找,比如各种/lib,/usr/lib等各种lib路径下查找,但是你的动态库并没有放到指定的路径下,因此有两种方法解决:
(1)将制作的动态库放到环境变量指定的动态库路径下,比如/lib
(2)导出环境变量,增加动态库所在的路径,比如

点击查看代码
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a
//$LD_LIBRARY_PATH表示原动态库路径,在后面加上/a表示加上/a也成为动态库路径
//但是这种方式只是单次有效,最好还是把动态库放到环境变量指定路径中

制作使用静态库

点击查看代码
ar crs libsub.a sub.o sub2.o sub3.o(可以使用多个.o 生成静态库)
//ar就是压缩的意思。.a是静态库的后缀名。通过ar命令生成静态库
使用静态库时也可以使用-l -L分别指定静态库名称和路径,并且静态库在编译时就会被复制到可执行文件中,因此在运行时独立于静态库的存在,不会出现使用动态库时的运行问题,但是增加了可执行文件的大小。

一些有用的编译选项

点击查看代码
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)

总结一下内容

在编译时,头文件使用尖括号<>,会在指定的目录查找,也可以使用-I 指定查找目录。对于库,指定库名后也会在指定的目录查找,也可以使用-L指定目录
运行时,对于动态链接,会去环境变量指定的编译器的各种lib目录下查找,比如/lib,/usr/lib等,也可以使用export导出增加指定的动态库文件路径,但是只能在本次生效

标签:可执行文件,gcc,main,指定,helloWorld,基础知识,编译,动态
From: https://www.cnblogs.com/starstxg/p/18111532

相关文章

  • Java基础知识
    1.Java中的几种数据类型除了8种简单数据类型之外的所有数据类型都被称为引用数据类型,引用数据类型变量的内存大小统一为4字节,记录的是其引用对象的地址。2.全局变量与局部变量实例变量、类变量、常量都是属于成员变量的,成员变量又被称为全局变量。被static关键字修饰的变量,叫......
  • 编译和链接
    一个软件的开发,一行代码的实现,实际上是由两个环节所构成的:翻译以及运行。而这两个环节是在两个环境下所进行的:翻译环境和运行环境。翻译环境负责将源代码转换为可执行的机器指令,也就是计算机能听懂的语言。运行环境负责实际执行代码的操作。翻译环境可以被分为两个部分:编译......
  • mathematical-expression(MAE)数学表达式 数学函数 解析编译库,有效的快速和简单易用的数
    数学表达式SwitchtoEnglishDocument介绍本框架是一种针对数学公式解析的有效工具,能够解析包含嵌套函数,包含函数,数列步长累加等数学公式,返回值是一个数值的结果对象,同时也可以进行比较运算的操作,再进行比较的时候,返回值是一个布尔值结果对象。PS请尽量使用1.3.1版......
  • 机器学习编译MLC
    陈天奇-《机器学习编译》课程主页:https://mlc.ai/summer22-zh课程笔记:https://mlc.ai/zh/机器学习编译概述1.1什么是机器学习编译机器学习编译(machinelearningcompilation,MLC)是指,将机器学习算法从开发阶段,通过变换和优化算法,使其变成部署状态。开发形式是指......
  • 在aarch64上编译,fstack: master分支:5b97230c858598a10e1b82c tag: v1.23, origin/mast
    F-Stack一个基于DPDK的开源和高性能网络框架 基于DPDK23.11需要做如下操作sed替换:sed-n'/DEV_RX_OFFLOAD_IPV4_CKSUM/p'drivers/net/macb/*sed-i's/ETH_/RTE_ETH_/g'*.csed-i's/DEV_/RTE_ETH_/g'*.c f-stack适配dpdk20.11sed-i's/RTE_MBUF_F_RX_I......
  • Eval-Expression.NET: 在运行时计算、编译和执行C代码和表达式。
    https://www.5axxw.com/wiki/content/8ahrg3 在运行时评估、编译和执行动态C代码和表达式从简单的C数学表达式。。。intresult=Eval.Execute<int>("X+Y",new{X=1,Y=2});要解析的复杂代码。intresult=Eval.Execute<int>(@"varlist=newList<int>(){1......
  • 【爬虫】第一章-Web基础知识
    目录HTML标签分类空标签/单标签闭合标签/双标签块级元素内联元素(行内元素)几种主要网页编码Unicode(统一码、万国码、单一码)UTF-8GB2312GBKHTML标签分类空标签/单标签1)<meta/>元信息2)<img/>图片标签3)<br/>换行标签4)<hr/>水平线5)<link/>引入标签6)<base......
  • 自然语言处理基础知识入门(二) Word2vec模型,层次softmax,负采样算法详解
    文章目录前言一、Word2vec模型1.1什么是Word2vec模型?1.2Word2vec模型是如何训练?1.3Word2vec最简单版本整体过程1.4Word2vec详细过程1.5CBOW整体过程1.6Skip-gram整体过程二、优化算法2.1层次softmax2.1.1哈夫曼树2.1.2算法详细逻辑2.2负采样策略总结......
  • Linux 编译升级内核
    要在CentOS上手动编译并安装Linux内核4.19.311,你需要遵循一系列步骤。以下是一个简化的流程概述,但请注意实际操作时需要根据你的CentOS版本、内核源码以及实际情况稍作调整:准备工作:登录到具有足够权限的用户(最好是root或使用sudo)。更新系统:sudoyumupdate-y安装编译......
  • windows下编译paho.mqtt
    1、准备(1)Github仓库地址:https://github.com/eclipse/paho.mqtt.chttps://github.com/eclipse/paho.mqtt.cpp(2)VisualStudio2022以及CMakehttps://visualstudio.microsoft.com/zh-hans/vs/community/https://cmake.org/download/2、编译C库首先clone源码到本地文件......