C++makefile入门

2022-07-10 10:45:15

1.Makefile基本语法与执行

1.1实例

all:test.o set.o set1.o #这样就可以执行全部了

test.o:test.c #如果依赖文件找不到直接报错
	g++ test.c-o test.o
#但是只执行第一个
set.o:set.c
	g++ set.c-o set.o
set1.o:set1.c
	g++ set1.c-o set1.o
clean:
	rm-f test.o
	rm-f set.o
	rm-f set1.o

编译: make

清空: make clean

1.2构成

Makefile主要由多条规则构成,每条规则由三部分构成:目标(target)、依赖(prerequiries)和命令(command)。
目标:最终要生成什么东西
依赖:用那些东西来生成
命令:执行的命令(每个命令行前面必须是一个Tab字符,即命令行第一个字符是Tab。这是不小心容易出错的地方。)
格式

目标(target): 依赖(prerequiries)...
  命令(command)

2 Makefile多文件编译

2.1代码

student.h

#ifndef __STUDENT_H__#define __STUDENT_H__classStudent{private:char name[20];int age;bool sex;public:voidInit(char* name,int age,bool sex);voidread();voidwrite();};#endif

student.cpp

#include<iostream>#include<cstdio>#include<cstdlib>#include"student.h"#include<cstring>usingnamespace std;void Student::Init(char* name,int age,bool sex){strcpy(this->name,name);this->age=age;this->sex=sex;}void Student::read(){
	cin>>name>>age>>sex;}void Student::write(){
	cout<<"姓名:"<<name<<endl<<"年龄:"<<age<<endl<<"性别:"<<sex<<endl;}

student.test

#include<iostream>#include<cstdio>#include"student.h"usingnamespace std;intmain(){char name[20]={"lvke"};int age=18;bool sex=1;
	Student student;
	student.Init(name,age,sex);	

	student.write();//	student.read();int n=0;
	cin>>n;#ifdef VAR_ARRAY
	Student arr[n];for(int i=0;i<n;i++){
		arr[i].read();}for( i=0;i<n;i++){
		arr[i].write();}#endif
	Student* p=new Student[n];for(int i=0;i<n;++i){
		p[i].read();}for(int k=0;k<n;++k){
		p[k].write();}delete[] p;
	p=NULL;}

2.2 makefile

Student_Test:student_test.o student.o
	g++-o Student_Test student_test.o student.o
student_test.o:student_test.cpp student.h
	g++-c student_test.cpp
student.o:student.cpp student.h
	g++-c student.cpp
test:./Student_Test
clean:
	rm-f Student_Test student_test.o student.o

2.3结果

在这里插入图片描述

3使用变量简化makefile

3.1概念

每次增加新的文件,需要在makefile的很多地方增加依赖,容易导致遗漏。可以使用变量可以简化,避免这种出错的可能。

变量定义:变量 = 字符串
变量使用:$(变量名)

3.2示例

#变量定义:变量= 字符串
OBJS= student_test.o student.o
Student_Test:$(OBJS)#变量使用:$(变量名)
	g++-o Student_Test $(OBJS)
student_test.o:student_test.cpp student.h
	g++-c student_test.cpp
student.o:student.cpp student.h
	g++-c student.cpp
test:./Student_Test
clean:
	rm-f Student_Test $(OBJS)

4命令自动推导

4.1概念

make提供一种简化写法,可以自动推导出该规则

文件名.o:文件名.cpp 头文件
  g++-c 文件名.cpp

可以推导成下面的(这种简化规则称为隐含规则,非简化规则成为具体规则。)

文件名.o:头文件

4.2示例

OBJS= student_test.o student.o
Student_Test:$(OBJS)
	g++-o Student_Test $(OBJS)
student_test.o: student.h
student.o: student.h#student_test.o:student_test.cpp student.h#	g++ -c student_test.cpp#student.o:student.cpp student.h#	g++ -c student.cpp
test:./Student_Test
clean:
	rm-f Student_Test $(OBJS)

如果
在这里插入图片描述

4.3优化

通常,规则按照目标进行分组。规则也可以按照依赖分组。例如,例子中student.o和studentTest.o都依赖String.h。那么,可以这两个合并到一个规则中。

OBJS= student_test.o student.o
Student_Test:$(OBJS)
	g++-o Student_Test $(OBJS)
student_test.o student.o: student.h#student.o: student.h#student_test.o:student_test.cpp student.h#	g++ -c student_test.cpp#student.o:student.cpp student.h#	g++ -c student.cpp
test:./Student_Test
clean:
	rm-f Student_Test $(OBJS)

5. 假想目标

5.1问题:

例如例子中的clean,只是执行清理动作。如果,makefile同级目录存在与假象目标同名的文件(例如:clean),那么会导致命令不会被执行

5.2解决方法

表达动作的目标称为假想目标。所以需要把目标显示声明为假想目标。因为通常规则会生成或者更新与目标的同名文件,但是假想目标不生成文件,只是作为几个命令组成特殊规则的名称。

5.3实例

OBJS= student_test.o student.o.PHONY: clean test

Student_Test:$(OBJS)
	g++-o Student_Test $(OBJS)
student_test.o student.o: student.h

test:./Student_Test
clean:
	rm-f Student_Test $(OBJS)

5.4常用假想目标

6. 通配符与变量

6.1. 通配符

通配符主要用于匹配文件名,makefile中使用%作为通配符。从匹配目标格式的目标名中依据通配符抽取部分字符串,再按照抽取字符串分配到每一个依赖格式中产生依赖名。例如,使用%.o:%.cpp。

6.2自动变量

自动变量是在规则每次执行时都基于目标和依赖产生新值的变量。下面是常用的自动变量。

No.自动变量含义
1$<表示第一个匹配的依赖
2$@表示目标
3$^所有依赖

在这里插入图片描述

6.3. 预定义变量

预定义变量是makefile已经**定义好的变量,**用户可以在makefile文件中改变变量的值。

程序名变量
变量程序默认
CCC语言编译程序cc
CXXC++编译程序g++
CPP带有标准输出的C语言预处理程序$(CC) -E
程序运行参数的变量:两个都为空
变量程序参数
CFLAGS用于C编译器的额外标志
CXXFLAGS用于C++编译器的额外标志

6.4变量值

VAL=hello
test:
	echo $(VAL)
	echo $(CXX)
	echo $(CC)
	echo $(CXXFLAGS)
	echo $(CFLAGS)

在这里插入图片描述

6.5代码

OBJS= student_test.o student.o.PHONY: clean test

Student_Test:$(OBJS)#	g++ -o Student_Test $(OBJS)
	$(CXX)  $(OBJS)-o $@#student.o: student.h#student_test.o:student_test.cpp student.h#	g++ -c student_test.cpp#student.o:student.cpp student.h#	g++ -c student.cpp
$(OBJS):%.o:%.cpp student.h
	$(CXX)-c $(CXXFLAGS) $<-o $@

test:./Student_Test
clean:
	rm-f Student_Test $(OBJS)

7. 其他

注释#
换行\
回显命令@echo(打印后面字符 做提示用)
  • 作者:。。
  • 原文链接:https://blog.csdn.net/weixin_45639955/article/details/104311039
    更新时间:2022-07-10 10:45:15