linux的make和makefile学习

linux的make和makefile学习

  • 准备工作
  • 使用GNU链接库
    • 链接到math库
      • 编写复利程序
    • 创建自己的库
    • 链接到主目录
  • 不同的C标准
  • 系统调用write()
  • 获取头文件信息
  • 功能测试宏

准备工作

安装GCC和Make工具

安装中文输入法
参考:http://t.csdn.cn/eH0Ow

sudo apt-get update
sudo apt-get install ibus
sudo apt-get install ibus-pinyin
sudo apt-get install fcitx
sudo apt-get install fcitx-pinyin

完成后重启
重启进入设置:
在这里插入图片描述

使用GNU链接库

链接到math库

编写复利程序

命名为interest.c

#include <studio.h>
#include <math.h>int main(void)
{int years=15; /*要存多少年 */int savings=99000; /*存多少钱*/float interest=1.5;  /*年利率为1.5%*/printf("The total savings after %d years is %.2f\n", years, savings * pow(1+(interest/100),years));return 0;
}

编译链接程序:
编译链接库:-lz -lrt -lm -lc都是什么库
-lz 压缩库(Z)
-lrt 实时库(real time):shm_open系列
-lm 数学库(math)
-lc 标准C库(C lib)
-dl ,是显式加载动态库的动态函数库

gcc interest.c -o interest -lm
./interest   #运行程序

-o指定编译汇编输出程序名

创建自己的库

1、创建头文件:prime.h
在这里插入图片描述

2、创建库文件:prime.c

int isprime(long int number)
{long int j;  /*长整型*/int prime=1; /*测试是否这个数能被整除,从2开始*/for(j=2;j<number;j++){/*用取余操作测试这个数能否被整除*/if(number%j==0){prime=0; //不是素数}}if(prime==1){return 1;//素数}else{return 0;//非素数}
}

3、编译成目标文件

gcc -Wall -Wextra -pedantic -fPIC -c prime.c

在这里插入图片描述
-Wall:开启所有警告(可以理解为warinig all),使用它能够使GCC产生尽可能多的警告信息。(非常推荐使用该选项)GCC给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。
-Wextra是关于打开警告的,这些警告可能比其他选项更有用或更麻烦(因为它们可能警告程序员可以接受的代码)。
-pedantic 是 GCC 编译器的一个编译选项。这个选项会让编译器严格遵守 C++ 标准,并输出标准要求的诊断信息,对于一些可能不符合 C++ 标准的语法或者行为会给出警告或者错误提示。
-fpic 该选项用于生成位置无关代码(PIC),尤其被用于共享库的创建(如果目标机器架构支持的话)。使用该选项编译出的代码在访问所有常量地址时,会通过全局偏移表(GOT)进行计算得到。
-c参数是用来编译源代码文件,生成目标文件(object file)的选项(.o)。

4、将目标文件打包成库

 gcc -shared -Wl,-soname,libprime.so -o libprime.so prime.o

使用 -shared 选项生成共享库时,最好还是带上 -fpic 或 -fPIC 等选项。
-Wl后面的东西是作为参数传递给链接器ld的
-soname则指定了动态库的soname(简单共享名,Short for shared object name)
这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同
libxxxx.so.major.minor
其中,xxxx是库的名字,major是主版本号,minor 是次版本号
-o指定输出文件名libprime.so
被包含在共享库中的目标文件prime.o
在这里插入图片描述

链接到主目录

1、写程序is-it-a-prime.c,调用共享库libprime.so

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "prime.h"int main(int argc, char *argv[])
{long int num;/*只接收一个参数*/if (argc!=2){fprintf(stderr, "Usage: %s number\n", argv[0]);//stderr -- 标准错误输出设备return 1;}/*只接收数字0-9*/if (strspn(argv[1],"0123456789")!=strlen(argv[1]))//strspn返回字符串s开头连续包含字符串accept内的字符数目。 若strspn()返回的数值为n,则代表字符串s 开头连续有n 个字符都是属于字符串accept内的字符。// strlen函数:当计算长度时,只有遇到'\0'才会停止计算,同时计算的长度不包含'\0'。{fprintf(stderr, "Only numeric values are accepted\n");return 1;}num=atol(argv[1]); //atol() C 标准库 - <stdlib.h> 描述 C 库函数 long int atol(const char *str) 把参数 str 所指向的字符串转换为一个长整数(类型为 long int 型)。if(isprime(num)) //是否素数{printf("%ld is a prime\n", num);}else{printf("%ld is not a prime\n", num);}return 0;
}

2、链接

gcc -L${PWD} is-it-a-prime.c -o is-it-a-prime -lprime #指定共享库路径
export LD_LIBRARY_PATH=${PWD}:${LD_LIBRARY_PATH} #设置环境变量为共享库目录(当前目录)

在这里插入图片描述
-L用来告诉gcc去哪里找库文件。 通常来讲, gcc默认会在程序当前目录、/lib、/usr/lib和/usr/local/lib下找对应的库。
-L /home/hello/lib,表示将/home/hello/lib目录作为第一个寻找库文件的目录, 寻找的顺序是:/home/hello/lib–>/lib–>/usr/lib–>/usr/local/lib
LD_LIBRARY_PATH 这个环境变量是大家最为熟悉的,它告诉loader:在哪些目录中可以找到共享库。可以设置多个搜索目录,这些目录之间用冒号分隔开。
假如现在需要在已有的环境变量上添加新的路径名,则采用如下方式:  LD_LIBRARY_PATH=NEWDIRS:$LD_LIBRARY_PATH.(newdirs是新的路径串)

不同的C标准

C89是1989年发布的,兼容性最好,使用最广泛,实现最完整
C99更新一些
写两个进程,分别用C89和C99编译
1、写c文件no-return.c

#include <stdio.h>int main(void)
{printf("Hello, world\n");
}

2、用C89编译程序

qq@qq-virtual-machine:~/Desktop$ gcc -std=c89 no-return.c -o no-return #用C89标准编译程序
qq@qq-virtual-machine:~/Desktop$ ./no-return #运行程序
Hello, world
qq@qq-virtual-machine:~/Desktop$ echo $? #检查退出码
13

开启所有警告,重新编译

qq@qq-virtual-machine:~/Desktop$ gcc -Wall -Wextra -pedantic -std=c89 no-return.c -o no-return
no-return.c: In function ‘main’:
no-return.c:6:1: warning: control reaches end of non-void function [-Wreturn-type]}^

3、c99标准编译,开启所有警告

qq@qq-virtual-machine:~/Desktop$ gcc -Wall -Wextra -pedantic -std=c99 no-return.c -o no-return
qq@qq-virtual-machine:~/Desktop$ ./no-return #运行程序
Hello, world
qq@qq-virtual-machine:~/Desktop$ echo $?  #检查退出码
0

系统调用write()

1、写一个sys-write.c文件

#include <unistd.h>
int main(void)
{write(1,"hello, world\n",13);return 0;
}

unistd.h为Linux/Unix系统中内置头文件,包含了许多系统服务的函数原型,例如read函数、write函数、getopt函数和getpid函数等。
write和exit是系统级函数,是内核提供给applications的接口,属于系统的一部分,可以直接申请内核服务。
在这里插入图片描述

write系统调用,是把缓存区buf中的前nbytes字节写入到与文件描述符flides有关的文件中,write系统调用返回的是实际写入到文件中的字节数。
一般地,一个程序开始运行时,会自动打开3个文件描述符:
0——–标准输入———-stdin
1——–标准输出———-stdout
2——–标准错误———-stderr

2、编译代码

qq@qq-virtual-machine:~/Desktop$ gcc -Wall -Wextra -pedantic -std=c99 sys-write.c  -o sys-write
qq@qq-virtual-machine:~/Desktop$ ./sys-write #运行程序
hello, world

3、编写相同代码用fputs函数,文件名:write-chars.c

#include <stdio.h>
int main(void)
{fputs("hello, world\n",stdout);return 0;
}
qq@qq-virtual-machine:~/Desktop$ gcc -Wall -Wextra -pedantic -std=c99 write-chars.c -o write-chars
qq@qq-virtual-machine:~/Desktop$ ./write-chars 
hello, world

4、写一个读取用户和系统信息的程序,文件名:my-sys.c
(*)拼音输入不好用解决方案:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/sysinfo.h>int main(void)
{char cwd[100]={0}; /*现在的路径*/struct sysinfo si; /*存系统信息*/getcwd(cwd,100); /*获取当前工作目录*/sysinfo(&si); /*获取系统信息(Linux*/printf("Your user ID is %d\n", getuid()); /*用户ID*/printf("Your effective user ID is %d\n", geteuid()); /*您的有效用户ID是*/printf("Your current working directory is %s\n", cwd); /*目录*/printf("Your machine has %ld megabytes of total RAM\n", si.totalram/1024/1024);printf("Your machine has %ld megabytes of free RAM\n", si.totalram/1024/1024);printf("Currently, there are %d processes running\n", si.procs);printf("This process ID is %d\n", getpid());printf("This parent process ID is %d\n", getppid());return 0;}

unistd.h是unix std的意思,是POSIX标准定义的unix类系统定义符号常量的头文件, 包含了许多UNIX系统服务的函数原型
sys/types.h,中文名称为基本系统数据类型,此头文件还包含适当时应使用的多个基本派生类型,常用于从系统取值。
sys/sysinfo.h获取Linux系统信息。

getcwd(cwd,100)获取当前工作目录,两个参数:cwd表示缓冲区,用于保存路径;100为缓冲区长度。
可以从man 2 intro和man 2 syscalls查看系统调用信息。

5、编译运行程序
在这里插入图片描述
由中文字符引起的错误,修改中文字符即可

qq@qq-virtual-machine:~/Desktop$ gcc -Wall -Wextra -pedantic -std=c99 my-sys.c -o my-sys
qq@qq-virtual-machine:~/Desktop$ ./my-sys 
Your user ID is 1000
Your effective user ID is 1000
Your current working directory is /home/qq/Desktop
Your machine has 1983 megabytes of total RAM
Your machine has 1983 megabytes of free RAM
Currently, there are 576 processes running
This process ID is 3528
This parent process ID is 2818

一般系统调用出错返回-1。

获取头文件信息

1、安装头文件手册(ubuntu系统)

qq@qq-virtual-machine:~/Desktop$ sudo apt install manpages-posix-dev
[sudo] password for qq: 
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

错误原因:有另一个进程正在使用apt命令或dpkg命令,因此无法获得对dpkg锁的访问权限。
解决:重启电脑(虚拟机)

2、阅读手册

qq@qq-virtual-machine:~$ man 2 sysinfo
qq@qq-virtual-machine:~$ man 2 getpid
qq@qq-virtual-machine:~$ man sys_types.h
qq@qq-virtual-machine:~$ man unistd.h

功能测试宏

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot使用logback配置彩色日志

springboot使用logback配置彩色日志 前言一、logback文件二、效果 前言 应该有很多同学发现&#xff0c;使用了logback以后&#xff0c;我们的控制台日志都变成灰色了&#xff0c;网络上搜到的logback配置大多数没有进行配色&#xff0c;所以会把springboot的默认配色方案给覆盖…

【python爬虫】10.指挥浏览器自动工作(selenium)

文章目录 前言selenium是什么怎么用设置浏览器引擎获取数据解析与提取数据自动操作浏览器 实操运用确认目标分析过程代码实现 本关总结 前言 上一关&#xff0c;我们认识了cookies和session。 分别学习了它们的用法&#xff0c;以及区别。 还做了一个项目&#xff1a;带着小…

数据结构 -作用及基本概念

为什么要使用数据结构 学习数据结构是计算机科学和软件工程领域中非常重要的一门课程。以下是学习数据结构的几个重要原因&#xff1a; 组织和管理数据&#xff1a;数据结构提供了一种组织和管理数据的方式。通过学习不同的数据结构&#xff0c;你可以了解如何有效地存储和操作…

Lesson6---案例:人脸案例

学习目标 了解opencv进行人脸检测的流程了解Haar特征分类器的内容 1 基础 我们使用机器学习的方法完成人脸检测&#xff0c;首先需要大量的正样本图像&#xff08;面部图像&#xff09;和负样本图像&#xff08;不含面部的图像&#xff09;来训练分类器。我们需要从其中提取特…

C++学习笔记总结练习:多态与虚函数

1 多态 多态分类 静态多态&#xff0c;是只在编译期间确定的多态。静态多态在编译期间&#xff0c;根据函数参数的个数和类型推断出调用的函数。静态多态有两种实现的方式 重载。&#xff08;函数重载&#xff09;模板。 动态多态&#xff0c;是运行时多态。通过虚函数机制实…

详细介绍如何基于ESP32实现低功耗的电子纸天气显示器--附完整源码

实现界面展示 这是一款天气显示器,由支持 wifi 的 ESP32 微控制器和 7.5 英寸电子纸(又名电子墨水)显示器供电。当前和预测的天气数据是从 OpenWeatherMap API 获取的。传感器为显示屏提供准确的室内温度和湿度。 该项目在睡眠时消耗约 14μA,在约 10 秒的清醒期…

MATLAB制图代码【第二版】

MATLAB制图代码【第二版】 文档描述 Code describtion: This code is version 2 used for processing the data from the simulation and experiment. Time : 2023.9.3 Author: PEZHANG 这是在第一版基础上&#xff0c;迭代出的第二版MATLAB制图代码&#xff0c;第二版的特点是…

不同路径 II【动态规划】

不同路径 II 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上…

NOR型flash vs NAND型flash

FLASH是一种存储芯片&#xff0c;全名叫Flash EEPROM Memory&#xff0c;通过程序可以修改数据&#xff0c;即平时所说的“闪存”。 闪存可以在软件的控制下写入和擦写数据。其存储空间被分割成相对较大的可擦除单元&#xff0c;成为擦除块&#xff08;erase block&#xff09…

没有使用sniffer dongle在windows抓包蓝牙方法分享

网上很多文章都是介绍买一个sniffer dongle来抓蓝牙数据,嫌麻烦又费钱,目前找到一个好方法,不需要sniffer就可以抓蓝牙数据过程,现分享如下: (1)在我资源附件找到相关安装包或者查看如下链接 https://learn.microsoft.com/zh-cn/windows-hardware/drivers/bluetooth/testing-bt…

Doris架构中包含哪些技术?

Doris主要整合了Google Mesa(数据模型)&#xff0c;Apache Impala(MPP Query Engine)和Apache ORCFile (存储格式&#xff0c;编码和压缩)的技术。 为什么要将这三种技术整合? Mesa可以满足我们许多存储需求的需求&#xff0c;但是Mesa本身不提供SQL查询引擎。 Impala是一个…

Docker技术--Docker中的网络问题

1.docker中的网络通信 如果想要弄清楚docker中的网络通信问题,其实需要弄清楚这几个问题就可以:容器与容器之间的通信、容器与外部网络之间的通信、外部网络与容器之间的通信。 -a:容器与容器之间的通信,如下所示: 在默认情况下,docker使用网桥(Bridge模式)与NAT通信。这…

攻防世界-Caesar

原题 解题思路 没出现什么特殊字符&#xff0c;可能是个移位密码。凯撒密码加密解密。偏移12位就行。

MyBatis-Plus —— 初窥门径

前言 在前面的文章中荔枝梳理了MyBatis及相关的操作&#xff0c;作为MyBatis的增强工具&#xff0c;MyBatis-Plus无需再在xml中写sql语句&#xff0c;在这篇文章中荔枝将梳理MyBatis-Plus的基础知识并基于SpringBoot梳理MyBatis-Plus给出的两个接口&#xff1a;BaseMapper和ISe…

机器学习之 Jupyter Notebook 使用

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

容器技术Linux Namespaces和Cgroups

对操作系统了解多少&#xff0c;仅仅敲个命令吗 操作系统虚拟化&#xff08;容器技术&#xff09;的发展历程 1979 年&#xff0c;UNIX 的第 7 个版本引入了 Chroot 特性。Chroot 现在被认为是第一个操作系统虚拟化&#xff08;Operating system level virtualization&#x…

Linux系统编程5(线程概念详解)

线程同进程一样都是OS中非常重要的部分&#xff0c;线程的应用场景非常的广泛&#xff0c;试想我们使用的视频软件&#xff0c;在网络不是很好的情况下&#xff0c;通常会采取下载的方式&#xff0c;现在你很想立即观看&#xff0c;又想下载&#xff0c;于是你点击了下载并且在…

LLM - LLaMA-2 获取文本向量并计算 Cos 相似度

目录 一.引言 二.获取文本向量 1.hidden_states 与 last_hidden_states ◆ hidden_states ◆ last_hidden_states 2.LLaMA-2 获取 hidden_states ◆ model config ◆ get Embedding 三.获取向量 Cos 相似度 1.向量选择 2.Cos 相似度 3.BERT-whitening 特征白化 …

centos安装nginx实操记录(加安全配置)

1.下载与安装 yum -y install nginx2.启动命令 /usr/sbin/nginx -c /etc/nginx/nginx.conf3.新建配置文件 cd /etc/nginx/conf.d vim index.conf配了一个负责均衡&#xff0c;如不需要&#xff0c;可将 server localhost: 多余的去掉 upstream web_server{server localhost…

软件测试/测试开发丨Selenium 高级定位 CSS

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接&#xff1a;https://ceshiren.com/t/topic/27022 一、CSS选择器概念 CSS拥有自己的语法规则和表达式 CSS通常分为相对定位和绝对定位 CSS常和XPATH一起用于UI自动化测试 二、CSS相对定位使用场景 支…