Makefile学习笔记02|动手编写第一个Makefile
希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢。
这里是目录
1 Makefile文件的命名规则
如果当前目录下只有一个Makefile文件的话,使用makefile或者Makefile就可,但是为了区分Makefile文件与其他文件,我们尽可能使用Makefile这种写法。如果需要多个Makefile文件,则可以将其命名为:文件名.mk。
2 make
2.1 简介
make工程管理器。工程管理器是指用来管理较多文件的工具。make工程管理器就是“自动编译管理器”。
作用:
- 读入Makefile文件来执行具体编译工作。
- 根据文件时间戳自动发现更新过的文件。
- 只编译改动的代码文件,而不用编译所有文件。
2.2 安装make
输入命令:
sudo apt-get install make
2.3 make版本查看
输入命令:
make -v
2.4 make命令格式
make是一个命令工具,它解释Makefile中规则。make命令格式如下:
make [-f filename][options][targets]
- [-f filename]
- make默认在工作目录中寻找名为Makefile、makefile、GNUmakefile的文件作为Makefile输入文件。
- -f 可以指定任意名字的文件作为Makefile输入文件。
- [options]
- -v:显示make工具的版本信息。
- -w:在处理Makefile文件之前和之后显示工作路径。
- -C dir:读取Makefile之前改变工作路径至dir目录。
- -n:只打印要执行的命令但是不执行,一般用于测试。
- -s:执行但是不显示执行的命令。
- [targets]:
- 若使用make命令时没有指定目标,则make工具默认会实现Makefile文件内的第一个目标。
- 指定了make工具要实现的目标,目标可以是一个或多个,多个目标用空格隔开。
3 Makefile语法规则
Makefile由函数、变量、规则组成。
3.1 Makefile基本规则三要素
- 目标:
- 通常是要产生的文件名称,也可以是可执行文件或其他obj文件,还可以是一个动作的名称。
- 依赖文件:
- 用来输入从而产生目标的文件。
- 一个目标通常有几个依赖文件,也可以没有。
- 命令:
- make执行的动作,一个规则可以含有几个命令,也可以没有
- 有多个命令时,每个命令占一行。
3.2 规则
一条规则由目标、依赖列表和命令列表组成,其形式如下:
目标:[依赖列表]
<Tab>命令列表
<Tab>为Tab键,不能由空格键代替。目标左侧不能有空格。依赖列表有时可以为空。
4 文件准备
- ~/make/src/first_make/first_make.cpp
//first_make.cpp
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
cout <<"test make "<<endl;
return 0;
}
5 直接使用make命令
#命令
make first_make
#结果
#g++ first_make.cpp -o first_make
#命令
./first_make
#结果
#test make
这是make的自动推导功能。在make后面传入目标名first_make,make会自动推导出所需的依赖文件first_make.cpp。这就完成了make的第一次使用,感觉是不是很简单呢。
6 使用Makefile做项目配置
首先,需要在代码的同路径,也就是~/make/src/first_make/下创建一个名为Makefile的文件。在我们输入make命令时,make会自动寻找当前目录下的名为Makefile或makefile的文件。下面,我们开始编写第一个Makefile文件。
# Makefile
first_make:first_make.cpp
#注意,很多人会把vim等编辑器的Tab键配置成四个空格,这样会导致错误。建议取消这样的配置。
g++ first_make.cpp -o first_make
接下来我们开始使用刚刚编写的Makefile。
#只需要输入一个make,make程序就可以自动去完成第一个目标。
make
#结果
g++ first_make.cpp -o first_make
如果出现了错误:make: ‘first_make’ is up to date.是因为之前编译时已经生成了first_make这个目标文件。此时可以输入一下命令来删除目标文件first_make。
rm first_make
7 代码中引入了第三方库
让我们修改一下first_make.cpp,引入线程库thread。
// first_make.cpp
#include <iostream>
#include <thread>
using namespace std;
void ThreadMain()
{
cout<<"Thread Main"<<endl;
}
int main(int argc, char *argv[])
{
thread th(ThreadMain);
cout <<"test make "<<endl;
th.join();
return 0;
}
让我们头铁试一下吧。结果出现了undefined reference to 'pthread_create’的错误。既然这样那就修改一下Makefile吧。
# Makefile
first_make:first_make.cpp
g++ first_make.cpp -o first_make -lpthread
改好了,我们再试一下。
#命令
make
#结果
#g++ first_make.cpp -o first_make -lpthread
#生成了可执行文件first_make,让我们运行一下试试看。
./first_make
#打印结果
#test make Thread Main
8 多文件编译
在原目录~/make/src/first_make/下新建两个文件,分别是xdata.h和xdata.cpp。还要修改一下first_make.cpp。
// xdata.h
#ifndef XDATA_H
#define XDATA_H
class XData
{
public:
XData();
};
#endif
// xdata.cpp
#include <xdata.h>
#include <iostream>
using namespace std;
XData::XData()
{
cout<<"Create XData"<<endl;
}
// first_make.cpp
#include <iostream>
#include <thread>
#include "xdata.h"
using namespace std;
void ThreadMain()
{
cout<<"Thread Main"<<endl;
}
int main(int argc, char *argv[])
{
thread th(ThreadMain);
cout <<"test make "<<endl;
th.join();
XData d;
return 0;
}
虽然不是在同一个时间,但是在同一个撤硕,奥利给,编译了啊兄弟们!make一下。果然又出现了错误,这次的错误是:undefined refernce to ‘XData::XData()’,找不到函数定义。
那就再改一下makefile吧。
# Makefile
first_make:first_make.cpp xdata.cpp
g++ first_make.cpp xdata.cpp -o first_make -lpthread
这样再make一下就好了。这是只有这几个文件,动动手就能轻松解决问题。要是项目中有成百上千个文件,那不得累死我嘛😓。不用担心,后面学习了Makefile的语法,自然有办法轻松解决。不管怎么样,这第一步算是迈出去了,相信要不了多久我们就可以掌握Makefile了。
都看到这里了,可以给个点赞或者评论吗?达瓦里希( ̄^ ̄)ゞ