GNU GCC 编译

这篇起源于我试用g++指令编译c文件可以,gcc指令编译cpp文件出错了,加-lstdc++参数可以,。(以为gcc只编译c g++只编译cpp)哎,只想说我对这个世界一无所知。。。😢

GNU(GNU‘s Not Unix)🔗官网

GNU是一个自由软件操作系统—就是说,它尊重其使用者的自由。GNU操作系统包括GNU软件包(专门由GNU工程发布的程序)和由第三方发布的自由软件。GNU的开发使你能够使用电脑而无需安装可能会侵害你自由的软件。

GNU计划

GNU计划,是由Richard Stallman在1983年9月27日公开发起的。它的目标是创建一套完全自由的操作系统 (GNU)。Richard Stallman最早是在net.unix-wizards新闻组上公布该消息,并附带《GNU宣言》等解释为何发起该计划的文章,其中一个理由就是要“重现当年软件界合作互助的团结精神”。为保证GNU软件可以自由地“使用、复制、修改和发布”,所有GNU软件都有一份在禁止其他人添加任何限制的情况下授权所有权利给任何人的协议条款,GNU通用公共许可证(GNU General Public License,GPL)。即“反版权”(或称Copyleft)概念。

RSM成立了自由软件基金会(Free Software Foundation,FSF)起草了GPL。

做了编辑器Emacs和编译器GCC,调试器GDB。

一个完整的操作系统需要内核、编译套件、shell。

没事看看之前大事纪,虽然发生在我未出生的年代,但这不应该是对这个世界一无所知的理由-_-!

Linux

Linux是内核:它是为你运行的其他程序分配计算机资源的程序。内核是操作系统的基本部分,但是它自己并无用处;它只能在完整的操作系统框架下才能发挥作用。Linux一般和GNU操作系统一起使用:整个系统基本上就是GNU加上Linux,或叫GNU/Linux。所有被叫做**“Linux”的发行版**实际上是GNU/Linux发行版。

常用GNU软件包

  • 编辑器:vim,Emacs,
  • 程序开发:gcc(GNU C Compiler, GNU C++ Compiler,),make,
  • glibc:GNU C Library,GNU/Linux系统中最底层的API,大多运行库都会依赖它。主要支持GNU Hurd和Linux两种内核。Glibc主要由两部分组成,一部分是头文件;另一部分是库的二进制文件,包括动态和静态两个版本。
  • shell:大多GNU/Linux上的shell都是BASH(Bourne Again Shell)

GNU开发工具

  • 编辑器
  • 预编译器(cpp):源代码进行预编译
  • 编译器 (gcc):把 .c文件编译成汇编 .s文件
  • 汇编器(as):把汇编文件编译成目标文件 .o文件
  • 链接器(ld):把多个目标文件及库文件连接成可执行 .exe文件
  • 库生成器(ar):将一个或多个目标文件连接成库文件
  • 调试器(gdb):对程序进行单步跟踪调试
  • 二进制代码查看器(readelf):查看可执行二进制文件的相关信息
  • 工程管理器(make):对源码文件进行管理

GCC(GNU Compiler Collection)

目前 Linux 下最常用的 C 语言编译器是 GCC ( GNU Compiler Collection ),GNU编译器套件,它是 GNU 项目中符合 ANSI C 标准的编译系统,能够编译用 C 、 C++ 、Java和 Object C 等语言编写的程序。

语法

gcc [选项] 准备编译的文件 [选项] [目标文件]

gcc 与 g++命令
  • gcc 编译c文件时调用GCC中的GNU C Compiler(C编译器),编译成C型目标文件,使用的于定义宏比较少;gcc 编译cpp文件,g++编译c/cpp文件时,调用GCC中的GNU C++ Compiler(C++编译器),编译成C++型目标文件,会加入额外的宏。

  • gcc*.c*.cpp文件分别当作c与cpp文件编译;g++把两者统一当作cpp文件编译

  • gcc编译文件时不会自动链接STL库, 在使用其编译cpp文件时,为了能使用STL库,需要加参数-lstdc++g++会自动链接STL库。

    gcc nanami.cpp -lstdc++ -o nanami.exe

  • gcc编译C文件,使用的预定义宏比较少;gcc在编译cpp文件,g++编译c/cpp文件时候,会加入额外的宏。

c与cpp混合编译及extern “C” { }

按照这个的test
makefile

target : main.o mycpp.o myc.o
	g++ -o target main.o mycpp.o myc.o

main.o : main.cpp
	g++ -c main.cpp

mycpp.o : mycpp.cpp
	g++ -c mycpp.cpp

myc.o : myc.c
	gcc -c myc.c

clean:
	rm -f *.o *exe

C型目标文件,使用nm查看 *.o文件的符号,函符号为原函数名

C++型目标文件,*.o,函数符号在原函数名上有增加内容。由于C++支持函数重载,所以生成的目标文件函数符号会增加参数等一些相关信息。所以,如果使用g++编译c文件(没有使用extern "C"{}指定),生成C++型目标文件,函数名function_c会变化。

在这里插入图片描述

extern "C"{}:被它修饰的目标是"extern"的;被它修饰的目标代码是"C"的。

extern “C” { }

在c文件的头文件声明处使用

#ifndef MYC_H /*防止头文件被重复引用*/
#define MYC_H

#ifdef __cplusplus /*cpp文件默认定义了该宏*/
extern "C"{  /*但cpp文件包含c头文件时,告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的*/
#endif
    /*...*/
	void function_c();
 
#ifdef __cplusplus
}
#endif

#endif /*MYC_H*/

在调用c文件头文件的cpp文件中使用,这个时候需要注意makefile只能用gcc指令编译myc.c,因为期望调用的是C型目标文件,不然会出现错误:

mycpp.o:mycpp.cpp:(.text+0x2b): undefined reference to `function_c
collect2.exe: error: ld returned 1 exit status
mingw32-make: *** [makefile:2: target] Error 1

/*cpp文件*/
#include <iostream>
#include "stdio.h"
#include "mycpp.h"    

extern "C"{ /*myc.c的头文件*/
#include "myc.h"
}
using namespace std;

void functionCpp(){
    cout<<__func__<<endl;
    function_c();
}

可执行文件生成过程回顾

链接

四个阶段:预处理、编译、汇编、链接。

预处理阶段:将源码中所有宏定义展开,删除#define;处理条件编译指令(#if,#ifdef等);处理#include预编译指令,通过递归的方式将被包含的文件插入到预编译指令的位置;删除所有注释;添加代码行号;

编译阶段:对预处理完的文件进行一系列的词法,语法分析,最终生成汇编代码。

汇编阶段:汇编代码转变成机器可以执行的二进制代码

链接阶段:解决多个文件之间的符号引用问题。链接器会把所有目标文件链接到一起,确定各个符号最终的地址,生成可执行文件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值