C++makefile入门
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__
class Student{
private:
char name[20];
int age;
bool sex;
public:
void Init(char* name,int age,bool sex);
void read();
void write();
};
#endif
student.cpp
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include"student.h"
#include<cstring>
using namespace 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"
using namespace std;
int main(){
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 | aaa@qq.com | 表示目标 |
3 | $^ | 所有依赖 |
6.3. 预定义变量
预定义变量是makefile已经**定义好的变量,**用户可以在makefile文件中改变变量的值。
程序名变量
变量 | 程序 | 默认 |
---|---|---|
CC | C语言编译程序 | cc |
CXX | C++编译程序 | 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 aaa@qq.com
#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 aaa@qq.com
test:
./Student_Test
clean:
rm -f Student_Test $(OBJS)
7. 其他
注释#
换行\
回显命令@echo(打印后面字符 做提示用)
上一篇: 华为eNSP上进行pppoe配置