《Linux学习笔记》:Makefile的使用

本文详细介绍了如何使用GCC进行预处理、编译、汇编和连接四个步骤,以及如何通过Makefile自动化这些过程。文章提供了一个具体的文件夹结构,包括bin、include、obj和src四个文件夹,分别存放可执行文件、头文件、目标文件和源文件。此外,还展示了如何在src、include和obj文件夹中创建和编辑Makefile,以实现编译过程的自动化。
摘要由CSDN通过智能技术生成

1.首先创建一个干净的文件夹名字为Topdir

2.在该文件夹内创建名字为 bin include src obj 四个文件夹,以及AgeRank.c    InfInt.c  main.c           NameRank.c  SwapEach.c GrSumRank.c  InfOut.c  MaxAgeAddress.c  SumAll.c几个子函数以及一个主函数文件main.c,以及一个头文件stuInfAct.h

 通过这几个文件来进行makefile的使用案例来说明,这些文件以及代码我会放在文章后,需要的可以自行拿取,也可以用自己的文件进行测试。

3.gcc的过程可以分为四个过程

(1).预处理:gcc -E 文件名.c -o 文件名.i ----------处理头文件(#开头)

(2).编译:gcc -S 文件名.i -o 文件名.s     ----------生成汇编语言

(3).汇编:gcc -c 文件名.s -o 文件名.o    ----------将汇编语言转换成机器代码

(4).连接:gcc  文件名.o -o 文件名         ----------将所有的机器代码汇集生成一个可执行文件 文件名(也就是 说(1)-(3)所有的步骤仅仅需要对应生成即可,到最后所有的.o文件生成一个 文件名

4.文件夹说明

        bin:存放可执行文件

        include:存放头文件(xxxx.h)

        obj:存放.o文件

        src:存放.c文件

5.

 (1)将所有的.c文件移动到当前目录下的src文件夹中

mv *.c src

(2)将所有的.h文件移动到当前目录下的include文件夹中

mv *.h ./include    //mv *.h include也可以

6.

(1)在当前目录下新建一个名为Makefile的文件

vim Makefile
#本文件为顶层Makefile
#给=后面的的参数起了给别名叫做前面的,便于之后的工程文件修改
GC:=gcc
GOP:=-c
EXE:=main
OBJS:=AgeRank.o InfInt.o main.o NameRank.o SwapEach.o GrSumRank.o  InfOut.o  MaxAgeAddress.o SumAll.o
RM:=rm -i

#本Makefile执行的命令
DO:
        make -C /src
        make -C /include

#将顶层Makefile别名传递到下级目录
export:GC GOP OBJS RM EXE

.PHONY:clean#防止因为当前文件夹内存在名字为 clean的文件,使得下面的 make clean 不能正确执行

#执行一行代码清除命令 make clean
clean:
        $(RM) ./src/*.o
        $(RM) ./bin/*
                      

 之后退出vim编辑器(不知如何使用vim编辑器的去看我的另外一篇关于vim的文章)

:wq

(2)

进入src文件夹中,新建一个Makefile文件  

cd src

注意!由于.h文件在include文件夹中所以这里的.c文件的头文件需要在""内加入其存在的地址,例如

vim Makefile

 目标文件:依赖文件

 (Tab)依赖文件如何生成目标文件

下列代码的作用是生成所有的.o,然后把.o都放到obj当中

MOVES:$(OBJS)
        mv $^ ../obj 
        
AgeRank.o:AgeRank.c
        $(GC) $(GOP) $< -o $@   
InfInt.o:InfInt.c  
        $(GC) $(GOP) $< -o $@   
main.o:main.c           
        $(GC) $(GOP) $< -o $@   
NameRank.o:NameRank.c  
        $(GC) $(GOP) $< -o $@   
SwapEach.o:SwapEach.c
        $(GC) $(GOP) $< -o $@   
GrSumRank.o:GrSumRank.c
        $(GC) $(GOP) $< -o $@   
InfOut.o:InfOut.c  
        $(GC) $(GOP) $< -o $@   
MaxAgeAddress.o:MaxAgeAddress.c  
        $(GC) $(GOP) $< -o $@   
SumAll.o:SumAll.c
        $(GC) $(GOP) $< -o $@   

(3)退出src,进入到obj当中,新建一个Makefile

cd ..
cd obj
vim Makefile
MOVES:$(EXE)
        mv $< ../bin
$(EXE):$(OBJS)
        $(GC) $^ -o $@

(4)回到顶层文件夹Topdir

make

测试代码如下:

#AgeRank.c
#include "../include/stuInfAct.h"
//编写一个子函数将结构体按照年龄进行排序
//参数1:结构体指针
//参数2:计算的人数
//返回值:void
void AgeRank(Stu *p,int count)
{
	int i=0,j=0;
	int max=p->age;
	for(i=0;i<N-1;i++)
	{
		for(j=0;j<N-i-1;j++)
		if(((p+j)->age)>((p+j+1)->age))
		{
			SwapEach((p+j+1),(p+j));
		}
	}
}

#GrSumRank.c
#include "../include/stuInfAct.h"
//编写一个子函数实现按照三科总成绩进行排序
//参数1:结构体指针
//参数2:计算的人数
//返回值:void
void GrSumRank(Stu *p,int count)
{
	int i=0,j=0,k=0;
	float sum1=0,sum2=0;
	/*for(k=0;k<count-1;k++)
	{
		for (j=0;j<count-1-k;j++)
		{
			sum1=0;
			sum2=0;
			for(i=0;i<N;i++)//计算一f对相邻的数的成绩的数值
			{
				sum1+=(p+j)->grades[i];
				sum2+=(p+1+j)->grades[i];
			}
			printf("sum1=%.1f,sum2=%.1f\n ",sum1,sum2);
			if(sum1>sum2)
			{

				SwapEach((p+j),(p+1+j));
			}
			
			
		}
	}	*/
	for(i=0;i<N-1;i++)//计算一f对相邻的数的成绩的数值
	{
		for(j=0;j<N-1-i;j++)
		{
			if(SumAll((p+j)->grades,N)>SumAll((p+1+j)->grades,N))
			{
				printf("%f VS %f\n",SumAll((p+j)->grades,N),SumAll((p+1+j)->grades,N));
				SwapEach((p+j),(p+1+j));
			}
		}
	}
}

#InfInt
#include "../include/stuInfAct.h"
//编写一个函数对ps所指向的空间进行输出
//参数1:结构体指针
//参数2:计算的人数
//返回值:void
void InfInt(Stu *p,int count)
{	
	int i=0,j=0;

	for(i=0;i<3;i++)
	{
		printf("请输入%d/%d名同学的名字、年龄、%d门成绩\n",i+1,count,N);
		scanf("%s",(p+i)->name);
		scanf("%d",&(p+i)->age);
		for(j=0;j<N;j++)
		{	
		//	printf("请输入第%d门的成绩:\n",j);
			scanf("%f",&((p+i)->grades[j]));
		}	
	//	printf("=====i=%d\n",i);
	}	
}

#InfOut.c
#include "../include/stuInfAct.h"

//编写一个子函数对ps所指向的进行输出
//参数1:结构体指针
//参数2:计算的人数
//返回值:void
void InfOut(Stu *p,int count)
{
	int i=0,j=0;
	for(i=0;i<count;i++)
	{
		
		printf("%s的年龄为%d,三门成绩分别为:\n",(p+i)->name,(p+i)->age);
		for(j=0;j<N;j++)
		{
			printf("%.1f ",(p+i)->grades[j]);
		}
		printf("\n");
	}
}
#main.c
#include "../include/stuInfAct.h"

int main()
{
	int op=0;
	Stu *p=(Stu *)malloc(sizeof(Stu)*PNum);	

	while(1)
	{
		printf("请输入选项:\n");
		printf(" 1-----InfInt\n");
		printf(" 2-----InfOut\n");	
		printf(" 3-----AgeRank\n");
		printf(" 4-----NameRank\n");
		printf(" 5-----GrSumRank\n");
		printf(" 6-----MaxAgeAddress\n");
		printf("-1-----退出\n");

		scanf("%d",&op);
		if(-1 == op)
		{
			break;
		}
		else
		{
			switch(op)
			{
				case 1:
					InfInt(p,PNum);
					break;
				case 2:
					InfOut(p,PNum);
					break;
				case 3:
					AgeRank(p,PNum);
					break;
				case 4:
					NameRank(p,PNum);
					break;
				case 5:
					GrSumRank(p,PNum);
					break;
				case 6:
					printf("%p\n",MaxAgeAddress(p,PNum));
					break;
				default:
					printf("输入有误!");	
			}	
		
		}
	}
	free(p);//free释放空间 ,p的值保留
	p = NULL;
	return 0;
}

#MaxAgeAddress.c
#include "../include/stuInfAct.h"
//编写一个子函数输出年龄最大的学生的首地址
//参数1:结构体指针
//参数2:计算的人数
//返回值:指向年龄最大的学生的结构体指针的首地址
Stu *MaxAgeAddress(Stu *p,int count)
{
//	int max=p->age;
//	int *address=0;
	
	Stu *PMax=NULL;
	PMax=p;
	int i=0;
	for(i=0;i<count;i++)
	{
		if(((p+i)->age)>PMax->age)
		{
			PMax=(p+i);
			//add=(p+i);
		}
	}
	return PMax;
}

#NameRank.c
#include "../include/stuInfAct.h"
//编写一个子函数将结构体按照名字进行排序
//参数1:结构体指针
//参数2:计算的人数
//返回值:void
void NameRank(Stu *p,int count)
{
	int i=0,j=0;
	for(i=0;i<count-1;i++)
	{
		for(j=0;j<count-1-i;j++)
		{
			if(strcmp((p+j)->name,(p+j+1)->name)>0)
			{
				SwapEach((p+1+j),(p+j));
			}
		}
	}	
}

#SumAll.c
#include "../include/stuInfAct.h"
//编写一个计算三科总成绩的子函数
//参数1:数组
//参数2:数组内元素个数
//返回值:计算的总成绩
float SumAll(float p[],int count)
{
	int i=0;
	float sum =0;
	for(i=0;i<count;i++)
	{
		sum+=p[i];

	}

	return sum;
}


#SwapEach.c
#include "../include/stuInfAct.h"

//编写一个子函数对ps地址内的结构体进行交换位置
//参数1:要交换的的指针1
//参数2:要交换的指针2
//返回值:void
void SwapEach(Stu *p,Stu *p2)
{
	Stu temp={0};
	temp=*p;
	*p=*p2;
	*p2=temp;
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小囧豆豆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值