Linux第七节课gcc与g++

一、补充权限

普通用户无法执行sudo:

通过sudo执行后显示不在sudoers file中!(张三不被信任!)

需要修改配置文件(白名单!)

配置文件位于以下目录:

ls /etc/sudoers -l

只有root才能访问这个文件!

通过root账号打开 sudoers文件:

在第100行下面加上对应自己用户名的权限,添加完后保存退出,即使得对应的用户在白名单中。

二、gcc / g++ 编译使用

gcc / g++ 默认生成的可执行程序的名称为a.out

  • gcc只能编译c语言;
  • g++可以编译c / cpp,编译c也是按照c++的格式编译,但是建议编译c++;

1、编译步骤详解

编译生成可执行程序的步骤:

预处理:

  • 预处理(进行宏替换)

其中包括四部分:去注释;头文件展开;条件编译;宏替换

gcc -E mycode.c -o mycode.i

-E : 告诉gcc,从现在开始进行的程序的翻译,将预处理工作昨晚停下来,不要继续往前!

将c文件预处理,生成预处理后的代码(预处理后就不需要头文件!)

条件编译:根据我们写的宏来灵活的进行选择性的编译。

示例:(如果定义的GEBUG这个宏)

#ifedf DEBUG
    printf("hello debug\n");
#else
    printf("hello release\n");
#endif

除此之外,我们还可以通过不修改代码进行添加宏!

gcc - E mycode.c -o mycode.i -DDEBUG

-DDEBUG 是一个预处理器定义。这意味着在预处理阶段,会定义一个名为 DEBUG 的宏。例如,如果在代码中有 #ifdef DEBUG 这样的条件编译指令,当定义了 DEBUG 这个宏时,相应的代码段就会被包含进来进行处理。 

 条件编译的应用场景:有的软件分为社区版和专业版,社区版的软件是由免费版的裁切过来的。 

预处理之后的代码还为C语言!

编译:

  • 编译(生成汇编)
gcc - S mycode.i -o mycode.s

-S :  开始进行程序的翻译,将编译工作做完就停下来!(可以从.c文件到.s)

汇编:

  • 汇编(生成机器可识别代码 --- 生成二进制代码)
gcc - c mycode.s -o mycode.o

-c :  开始进行程序的翻译,将汇编工作做完就停下来!(可以从.c文件到.s) 

生成的.o文件叫做可重定位目标二进制文件,简称目标文件;在·Windows下被称为.obj文件!

该文件不可以独立执行,虽然已经为二进制文件,但是还需要链接!

可以使用二进制查看工具查看二进制代码

od test.o

链接: 

  • 链接(生成可执行文件 / 库文件)
gcc test.o -o test

2、库 

在我们写c文件的时候,直接调用头文件可以进行库函数的使用,但是头文件中只包含了函数的声明,没有函数的定义!那么函数的声定义位于哪?

函数、方法的实现就在库当中! 

库本质其实就是源文件(.c)经过一定的翻译,然后打包 -- 只给自己提供一个文件即可,不用提供太多的库文件;也可以达到隐藏源文件的目的

gtp4o - mini解释如下:

当你在程序中包含一个头文件,比如 #include <stdio.h>,你会获得库函数,如 printf 的声明。头文件中仅包含函数的原型(即函数的声明),这使得编译器知道如何处理函数调用,并进行类型检查等。

而实际的实现代码则存在于编译器提供的库文件中。例如,在大多数操作系统中,C语言的标准库会被打包成一些动态链接库(如 libc.so 在Linux中,或 msvcrt.dll 在Windows中)或静态库(如 libc.a)。这些库文件包含了所有标准库函数的实际实现。

结论:

头文件提供方法的声明,库文件提供方法的实现 + 自己的代码 = 可执行程序!

库文件的作用就是我们不用自己进行重复的工作(例如不需要自己实现printf函数)

默认链接的时候,连接的是C的标准库!

当运行到哪一步需要调用函数的时候(链接器告诉去对应的哪里链接对应的库)

在Linux系统中,标准库位于

ls /usr/lib64/libc.so

本质上是一个文件! 

  • 在Linux系统中,   .so(动态库)  .a(静态库)
  • 在windows系统中  .dll(动态库) .lib(静态库)

库有自己的命名规则:libname.so.xxx(例如libc.so就是c的标准动态库)

云服务器默认安装的只有动态库,没有安装静态库!

 将可重定位目标二进制文件和库进行链接生成可执行程序!

  • 键盘左上角ESC对应于我们生成的指令!
  • iso为每阶段生成的代码 --- 对应于镜像文件!

 将可重定位目标二进制文件(经汇编生成的二进制文件)和库进行链接生成可执行程序!

为什么能在给Windows / Linxu上进行 C / C++或者其他形式的开发?

因为我们系统中安装的有C / C++开发相关的头文件 / 库文件!

C / C++开发环境不仅仅指的是vs,gcc,g++,更重要的是,语言本身的头文件和库文件!

在Linux系统中,头文件位于一下路径:

ls /usr/include/

因此,安装vs2019, vs2022等,在安装的时候,要选择对应的开发包,同步也在下载c的头文件和库文件;

即C的头文件和库文件,也在WIndows下存在!如下所示:

编译型语言:安装开发包,必定是下载对应的头文件 + 库文件。

注意点:

  • gcc 默认不加选项则直接生成可执行程序。
  • 生成的可执行程序不区分后缀名!例如
    gcc test.c -o test.txt

    文件依旧能正常运行!

  • 推荐生成的可执行程序不加后缀名

    gcc -o test test.c

    -o后面直接加可执行程序名,源代码的位置没有要求!

  • 生成的程序不带 -o则默认打印到显示器上;带-o回输入到我们指定的文件中!

  • 生成可执行程序的选项中后面跟上的是对应的源代码!

在链接的时候需注意:

  • gcc默认链接c的库;
  • g++默认链接c++的库

我们的.o和库如何链接?

3、动态链接与静态链接

  • 动态链接

动态库不能缺失,一旦对应的动态库缺失,影响的不止是一个程序,可能导致很多程序无法正常运行!

通过ldd指令可以查看一个程序所依赖的动态库(若是静态链接不显示),例如

ldd mytest

 Linux系统中好多指令也是用C/C++写的!

ldd /usr/bin/pwd
  • 静态链接

在编译器使用静态库进行静态链接的时候,会将自己的方法拷贝到目标程序中,该程序以后不用再依赖静态库!

结论:

  • 在Linux中,编译形成的可执行程序,默认采用的就是动态链接 -- 提供动态库!
  • 在Linux中,如果要按照静态链接的方式,进行形成可执行程序,需要添加-static选项--提供静态库。

例如:

gcc mycode.c -o mycode-static -static
  • 使用静态库生成的可执行程序比使用动态库的体积大!

没有静态库的时候可以自行安装C的静态库,例如在centos7中:

sudo yum install -y glibc-static

如果需要安装C++对应的静态库,可以使用以下:

sudo yum install -y libstdc++ static

结论:

  • 如果我们没有静态库,但是我们就要使用static,行不行呢?   --- 不行!
  • 如果我们没有动态库,只有静态库,而且gcc能找到,gcc依旧能编译,因为gcc默认优先动态链接! -static的本质是:改变优先级!
  • 生成的可执行程序不一定纯为动态链接 / 静态链接,可能是混合的!(但是static修饰的一定纯为静态链接!)

file指令

可以查看文件的信息(例如文件的链接库)

file mytest

总结:动态库与静态库的优缺点

  • 动态库因为是共享库,可以有效地节省资源(磁盘空间、内存空间、网络空间等)【动态优点】
  • 动态库一旦缺失,导致各个程序无法运行;【缺点】
  • 静态库不依赖库可以独立运行;【优点】
  • 静态库体积大,比较消耗资源【缺点】

4、release与dubug

通过默认的gcc生成的可执行程序是release版本!

debug:可以被追踪调试,形成可执行程序,添加了debug信息(体积一般比release大)

可以通过指定选项来使用debug调试:(加上-g选项)

gcc mycode.c -o mytest-static_debug -sattic -g

可以通过readelf读取可执行程序的代码:

readelf -S mytest_debug

拓展:可执行程序形成的时候,不是无序的二进制构成,而是有自己的格式 -- 可执行程序有自己的二进制格式 -- ELF格式(Linux系统中)

  • g++的选项与gcc一致!
  • make是一条指令!
  • makefile是一个文件!

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一道秘制的小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值