GCC写个库给你玩,就这?

news2025/1/12 1:08:41

前言

什么是GCC

GCC原名为 GNU C语言编译器

「GCC」(GNU Compiler Collection,GNU编译套件)

是由GNU开发的编程语言编译器。

正文

安装命令

sudo apt-get insatll gcc g++

注意安装版本要大于4.8.5因为4.8.5以后的版本才支持c++11标准

查看版本

gcc -v
gcc --version
g++ -v
g++ --version

gcc和g++的区别

gcc和g++ 都是GNU (组织)的一个编译器。

■ 「误区一」: gcc只能编译c代码,g++只能编译c++代码。

「两者都可以」,请注意:

  1. 「后缀为.c」的,gcc把它当作是「C程序」,而g++当作是c++程序

  2. 「后缀为.cpp」 的,两者都会认为是「C++程序」,C++的语法规则更加严谨一些

  3. 编译阶段,g++会调用gcc, 对于C++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接统统用g++了 ,这就给人一种错觉,好像 cpp 程序只能用 g++ 似的.

■ 误区二: gcc不会定义_cplusplus 宏,而g++会

  1. 实际上,这个宏只是标志着编译器将会把代码按C还是C++语法来解释

  2. 如上所述,如果「后缀为.c」,并且采用gcc编译器,则该宏就是未定义的,否则,就是已定义

■ 误区三:编译只能用gcc,链接只能用g++

  1. 严格来说,这句话不算错误,但是它混淆了概念,应该这样说:编译可以用gcc/g++,而链接可以用g++ 或者gcc -lstdc++

  2. gcc命令不能自动和C++程序使用的库联接,所以通常使用g++来完成联接,但在编译阶段,g++会自动调用gcc,二者等价.

gcc编译过程

在这里插入图片描述

gcc常用参数

选项名作用
-o产生目标(.i、.s、.o、可执行文件等)
-E只运行C预编译器
-S告诉编译器产生汇编程序文件后停止编译,产生的汇编语言文件拓展名为.s
-c通知gcc取消连接步骤,即编译源码,并在最后生成目标文件
-w不产生任何警告信息
-Wall使gcc对源文件的代码有问题的地方发出警告
-Idir指定 include 包含文件的搜索目录
-Ldir指定编译的时候,搜索的库的路径。
-lLib在程序编译的时候,指定使用的库
-g在目标文件中嵌入调试信息,以便gdb之类的调试程序调试
-D允许从编译程序命令行进行宏定义符号

gcc的使用示例:

gcc -E hello.c -o hello.i   #对hello.c文件进行预处理,生成了hello.i 文件
gcc -S hello.i -o hello.s   #对预处理文件进行编译,生成了汇编文件
gcc -c hello.s -o hello.o   #对汇编文件进行编译,生成了目标文件
gcc hello.o -o hello   #对目标文件进行链接,生成可执行文件
gcc hello.c -o hello   #直接编译链接成可执行目标文件
gcc -c hello.c 或 gcc -c hello.c -o hello.o #编译生成可重定位目标文件

「-D参数演示」

测试代码如下:

#include<stdio.h>

int main()
{
#ifdef DEBUG
 printf("DEBUG:\n");
#else
 printf("Normal:\n");
#endif
 for(int i=0;i<3;i++)
  printf("work\n");
 return 0;
}

测试命令

gcc -o Debug Debug.c
./Debug
Normal:
work
work
work
gcc -o Debug Debug.c -DDEBUG
./Debug
DEBUG:
work
work
work

库的介绍

「什么是库?」

库文件是计算机上的一类文件,可以简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类。

库是特殊的一种程序,编写库的程序和编写一般的程序区别不大,只是库不能单独运行。

库文件有两种,静态库和动态库(共享库)

「静态库(.a)」程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。静态库比较占用磁盘空间,而且程序不可以共享静态库。运行时也是比较占内存的,因为每个程序都包含了一份静态库。

「动态库(.so或.sa)」程序在运行的时候才去链接共享库的代码,多个程序共享使用库的代码,这样就减少了程序的体积。

「库的好处」:

1.代码保密

2.方便部署和分发

生成静态库

「静态库命名规则:」

◆ 「Linux」 : libxxx.a

lib : 前缀(固定)

xxx : 库的名字,自己起 .

a : 后缀(固定)

◆ 「Windows」 : libxxx.lib

Linux生成静态库

首先准备几个文件和文件夹,文件树形结构

[root@deroy]# tree
.
├── calc
│   ├── add.c
│   ├── div.c
│   ├── head.h
│   ├── main.c
│   ├── mult.c
│   └── sub.c
└── library
    ├── include
    ├── lib
    └── src

「add.c」

#include<stdio.h>
#include"head.h"

int add(int a,int b)
{
 return a+b;
}

「div.c」

#include<stdio.h>
#include"head.h"

double divide(int a,int b)
{
 if(b==0)
  return (double)a/b;
 else
  return 0;
}

 

「mult.c」

#include<stdio.h>
#include"head.h"

int multiply(int a,int b)
{
 return a*b;
}

「sub.c」

#include<stdio.h>
#include"head.h"

int subtract(int a,int b)
{
 return a-b;
}

「head.h」

#ifndef _HEAD_H_
#define _HEAD_H_

int add(int a,int b);
double divide(int a,int b);
int multiply(int a,int b);
int subtract(int a,int b);

#endif

为了生成 「.a 文件」,我们需要先生成 「.o文件」

[root@deroy]# cd calc/
[root@calc]# gcc -c add.c div.c mult.c sub.c

打包生成静态库

[root@calc]# ar rcs libcalc.a add.o sub.o mult.o div.o

ar 是 gun 归档工具,rcs 表示 replace and create ,如果 libhello 之前存在,将创建新的 libhello.a 并将其替换。

r - 将文件插入备存文件中

c - 建立备存文件

s - 索引

「将库放到指定位置」

[root@calc]# cp libcalc.a ../library/lib/
[root@calc]# cp head.h ../library/include/
[root@calc]# cp add.c div.c mult.c sub.c ../library/src/

库目录结构如下(这个库目录就是发给被人用的)

[root@ecs-x-medium-2-linux-20200312093025 library]# tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.a
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

使用静态库

编辑 main.c 文件

#include<stdio.h>
#include"head.h"
int main()
{
 int a = 20;
 int b = 12;
 printf("a = %d,b = %d\n",a,b);

 printf("a + b = %d\n",add(a,b));
 printf("a - b = %d\n",subtract(a,b));
 printf("a * b = %d\n",multiply(a,b));
 printf("a / b = %d\n",divide(a,b));
 return 0;
}

然后就可以这样来使用静态库libcalc.a

[root@library]# gcc main.c -o app -I ./include/ -lcalc -L./lib
[root@library]# ./app
a = 20,b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 12
其中:
-I  directory 指定include包含文件的搜索目录
-l 在程序编译的时候,指定使用的库
-L directory 指定编译的时候,搜索的库的路径

生成动态库(共享库)

动态库命名规则:

「Linux : libxxx.so」

「lib : 前缀(固定)」

「xxx : 库的名字,自己起」 .

「so : 后缀(固定)」

「在Linux下是一个可执行文件」

Windows : libxxx.dll

使用静态库的测试代码,库目录结构还是一样

[root@deroy]# tree
.
├── calc
│   ├── add.c
│   ├── div.c
│   ├── head.h
│   ├── main.c
│   ├── mult.c
│   └── sub.c
└── library
    ├── include
    ├── lib
    └── src

为了生成 「.so」 文件,我们需要先生成 「.o」 文件得到和位置无关的代码。

[root@calc]# gcc -c -fpic add.c div.c mult.c sub.c

打包生成「动态库」

[root@calc]# gcc -shared add.o sub.o mult.o div.o -o libcalc.so

「将库放到指定位置」

[root@calc]# cp libcalc.so ../library/lib/
[root@calc]# cp head.h ../library/include/
[root@calc]# cp add.c div.c mult.c sub.c ../library/src/

库目录结构如下(这个库目录就是发给被人用的)

[root@library]# tree
.
├── include
│   └── head.h
├── lib
│   └── libcalc.so
└── src
    ├── add.c
    ├── div.c
    ├── mult.c
    └── sub.c

使用动态库

[root@calc]# gcc main.c -o app -I include/ -L lib/ -l calc
[root@calc]# ldd app
        linux-vdso.so.1 =>  (0x00007ffc75cb0000)
        libcalc.so => not found
        libc.so.6 => /lib64/libc.so.6 (0x00007f3605ddb000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f36061a9000)

通过ldd命令查看程序动态库依赖关系

ldd是list dynamic dependencies的缩写,意思是列出动态库依赖关系。

结果发现libcalc.so => not found找不到了

「那么如何让程序找到依赖库呢?这里提供四种方法」

方法一(不推荐)

#拷贝.so文件到系统共享库路径下,一般指/usr/lib或者/lib/目录
sudo cp ./lib/libcalc.so /usr/lib/

方法二(临时环境变量)

[root@library]# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/deroy/library/lib
[root@library]# echo $LD_LIBRARY_PATH
:/root/deroy/library/lib
[root@library]# ldd app
        linux-vdso.so.1 =>  (0x00007fffe1570000)
        libcalc.so => /root/deroy/library/lib/libcalc.so (0x00007f007020f000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f006fe41000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0070411000)
[root@library]# ./app
a = 20,b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 12

运行成功

缺陷:只在当前终端有效,关闭中端后就没用了

方法三(配置用户环境变量)

将环境变量写入到~/.bashrc即可,即将下面内容添加到末尾

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/deroy/library/lib

[root@library]# cd ~
[root@~]# vim .bashrc
[root@~]# . .bashrc   #相当于source .bashrc
[root@~]# source .bashrc
[root@~]# cd deroy/library/
[root@library]# ldd app
        linux-vdso.so.1 =>  (0x00007ffe0d2db000)
        libcalc.so => /root/deroy/library/lib/libcalc.so (0x00007f937669c000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f93762ce000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f937689e000)
[root@library]# ./app
a = 20,b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 12

方法四(配置系统环境变量)

将环境变量写入到~/etc/profile即可,即将下面内容添加到末尾,需要root权限

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/root/deroy/library/lib

[root@library]# vim /etc/profile
[root@library]# source /etc/profile
[root@library]# ldd app
        linux-vdso.so.1 =>  (0x00007ffe08dc3000)
        libcalc.so => /root/deroy/library/lib/libcalc.so (0x00007f0eada81000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f0ead6b3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0eadc83000)
[root@library]# ./app
a = 20,b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 12

 

总结

静态库的优缺点

「优点」

◆ 静态库被打包到应用程序中加载速度快

◆ 发布程序无需提供静态库,移植方便

「缺点」

◆ 消耗系统资源,浪费内存 ◆ 更新、部署、发布麻烦

动态库的优缺点

「优点」

◆ 可以实现进程间资源共享(共享库)

◆ 更新、部署、发布简单

◆ 可以控制何时加载动态库

「缺点」

◆ 加载速度比静态库慢

◆ 发布程序时需要提供依赖的动态库

发送「关键字」获取「Linux安装配置视频」

「GCC详细使用视频」

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

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

相关文章

Vue.js 的数据双向绑定实现原理

Vue.js 的数据双向绑定实现原理 Vue.js 是一款流行的前端框架&#xff0c;它采用了数据双向绑定的方式&#xff0c;让前端开发人员更加方便地管理数据和视图。在本文中&#xff0c;我们将深入探讨 Vue.js 的数据双向绑定实现原理&#xff0c;以及相关的代码示例。 数据双向绑定…

1. TensorRT量化的定义及意义

前言 手写AI推出的全新TensorRT模型量化课程&#xff0c;链接&#xff1a;TensorRT下的模型量化。 课程大纲如下&#xff1a; 1. 量化的定义及意义 1.1 什么是量化&#xff1f; 定义 量化(Quantization)是指将高精度浮点数(如float32)表示为低精度整数(如int8)的过程&…

jmeter性能测试步骤实战教程

1. Jmeter是什么&#xff1f; 2. Jmeter安装 2.1 JDK安装 由于Jmeter是基于java开发&#xff0c;首先需要下载安装JDK &#xff08;目前JMeter只支持到Java 8&#xff0c;尚不支持 Java 9&#xff09; 1. 官网下载地址&#xff1a; http://www.oracle.com/technetwork/java/…

Map、Set和哈希表的应用练习(数据结构系列15)

目录 前言&#xff1a; 练习题&#xff1a; 结束语&#xff1a; 前言&#xff1a; 在上一节博客中小编给大家介绍了Map、Set和哈希表的一些简单的知识点&#xff0c;同时也给大家简单的演示了一下如何使用他们里面的一些基础方法&#xff0c;那么接下来让小编带着你们一起来…

当心!经济学家分析:未来三年内做好随时失业的准备

AI人工智能又来抢饭碗了&#xff0c;这次竟然通过了公认难考的会计行业考试&#xff01; 近期&#xff0c;OpenAI的大语言模型最新版GPT-4已经完成美国注册会计师&#xff08;简称CPA&#xff09;考试&#xff0c;四大主要会计考试所有科目的平均得分为85.1。 而在CPA考试中&…

落地页设计的营销心理学(三)

本文是「落地页设计的营销心理学」这个主题系列文章的收官篇&#xff0c;要给大家分享关于用户行动号召、提高用户参与度和整个营销落地页结构的设计。 回顾系列文章&#xff1a; 《落地页设计的营销心理学&#xff08;一&#xff09;》 《落地页设计的营销心理学&#xff08…

C++进阶 —— 线程库(C++11新特性)

十&#xff0c;线程库 thread类的简单介绍 在C11之前涉及多线程问题&#xff0c;都是和平台相关的&#xff0c;如windows和Linux下各有自己的接口&#xff0c;这使代码的可移植性较差&#xff1b;C11中最重要的特性就是对线程进行支持&#xff0c;使得C在并行编程时不需要依赖…

【社区图书馆】《写作脑科学》

文章目录 前言语言和思维写作技巧创造性思维总结 前言 杨滢著的《写作脑科学》是一本关于写作的科学读物&#xff0c;它深入探讨了人类大脑是如何进行创造性思维和表达的。这本书让我对写作有了全新的认识&#xff0c;也为我提供了一些实用的技巧和策略来提高自己的写作能力。…

整理 钢琴教材 约翰·汤普森现代钢琴教程(大汤)

邮箱不能及时回复,现放到网盘里了,文末按需自取 约翰-汤普森钢琴教程1 文件名:(大汤1)约翰汤普森现代钢琴教程 1 超清PDF 文件大小:9.9 MB 下载地址:https://download.csdn.net/download/qq_36040764/85051148 约翰-汤普森钢琴教程2 文件名:(大汤2)约翰汤普森现…

Python3中goto的用法

Python3代码指定跳转可以使用goto这个库&#xff1a; 安装&#xff1a; pip install goto-statement 一般安装的版本是1.2 需要做以下修改才能正常使用&#xff1a; python 使用goto&#xff0c;遇到的问题解决_奶嘴偷走初吻的博客-CSDN博客python goto 出现报错:Attribut…

Python difflib的使用

今天做了一个从list的内容取出一个与指定内容尽可能相似的内容,做完之后抽个几分钟记录下 difflib的作用 比对2个文件的差异. 使用的时候直接 import difflib 即可 get_close_matches 作用 匹配最大相似的内容返回结果 list1 ["abc", "acd", "…

NIO编程

目录 1、什么是NIO编程&#xff1f; 为什么说Java NIO是非阻塞的&#xff1f; 2、Java NIO 通道(Channel)详解 如何获取Channel对象&#xff1f; 3、Java NIO 缓冲区(Buffer)详解 &#xff08;1&#xff09;获取缓冲区对象 &#xff08;2&#xff09;将数据写入Buffer以…

没学过编程,本科学历,Java学到什么程度才能找工作?

好程序员之前写过多篇Java找工作方面的文章&#xff0c;今天说说零Java基础找工作的事情。首先请大家明确如下的要点。 1、在没有真实Java工作项目经验的前提下&#xff0c;靠自学&#xff0c;哪怕到培训班学&#xff0c;一定是无法真正掌握到能干Java项目的地步&#xff0c;原…

SpringData 基础篇

Spring Data 故事背景一&#xff1a;基础概念1.1 什么是SpringData1.2 为什么要用SpringData 二&#xff1a;JPA与Hibernate、MyBatis关系2.1 JPA与JDBC2.1.1 特点2.1.2 JPA规范提供2.1.3 JDBC的不足 2.2 Hibernate与JPA2.2.1 关系 2.3 mybatis 和Hibernate 三&#xff1a;Hibe…

裁剪与复原

目录 模型假设 模型建立 模型求解 通过建立匹配模型实现对破碎文件的拼接复原。 模型假设 模型建立 首先对每个图片按像素值进行二值化量化&#xff0c;可以得到19个1980*72的矩阵&#xff0c;再提取每个举证最左和最右的像素值采用绝对距离法建立像素匹配模型。 二值化是图…

大数据时代——生活、工作与思维的重大变革

最近读了维克托迈尔 – 舍恩伯格的《大数据时代》&#xff0c;觉得有不少收获&#xff0c;让我这个大数据的小白第一次理解了大数据。 作者是大数据的元老级先驱。 放一张帅照&#xff0c;膜拜下。 不过这本书我本人不推荐从头读一遍&#xff0c;因为书中的核心理念并不是特…

Django实现接口自动化平台(二)认证授权登录【持续更新中】

上一章&#xff1a; Django实现接口自动化平台&#xff08;一&#xff09;日志功能【持续更新中】_做测试的喵酱的博客-CSDN博客 下一章&#xff1a; Django实现接口自动化平台&#xff08;三&#xff09;实现注册功能【持续更新中】_做测试的喵酱的博客-CSDN博客 一、认证与…

FineBI6.0基础学习第二课 集团毛利率下滑的原因

【案例背景】 在本期分析案例中,您将扮演一个大型商品零售集团的数据分析师,应对经理交给你的任务——发现集团毛利率下滑的原因,并给出建议; 随着您一步一步的探索分析,您将通过对商品和订单的相关历史数据的分析,逐步找出影响毛利率的关键要素,并给出相应的分析结论,…

静态误差分析

分类 随机误差、系统误差、粗大误差。 随机误差&#xff1a; 大部分随机误差满足正态分布&#xff0c;具有对称性、单峰性、有界性、抵偿性。 对称性&#xff1a;绝对值相等的正负误差出现的次数相等。 单峰性&#xff1a;绝对值越小的误差出现次数越多。 有界性&#xff1…

GIS在地质灾害危险性评估与灾后重建中的实践

第一章 基本概念与平台介绍 1、基本概念 地质灾害类型 地质灾害发育特征与分布规律 地质灾害危害特征 地质灾害孕灾地质条件分析 地质灾害诱发因素与形成机理 ​ 2、GIS原理与ArcGIS平台介绍 GIS简介 ArcGIS基础 空间数据采集与组织 空间参考 空间数据的转换与处理 …