最近一直在学习makefile是如何编写的。
      当我们写的程序文件比较少的时候,敲入gcc /g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷。linux有一个自带的make命令,它让你的工作省去了很大的力气,但是你要学习如何编写makefile文件。
      makefile是一种特殊的文件格式,他将会帮你自动管理你的项目,很强大。它是这样工作的:
    1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
    2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
    3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
    4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
    5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生命make的终极任务,也就是执行文件edit了
 
下面通过实例一步步讲解如何使用makefile。下面的四段代码。
 
 
  1. /////main.cpp
  2. #include "functions.h"
  3. int main()
  4. {
  5. print_hello();
  6. cout << endl;
  7. cout << "The factorial of 5 is " << factorial(5) << endl;
  8. return 0;
  9. }
  10. ///hello.cpp
  11. #include "functions.h"
  12. void print_hello()
  13. {
  14. cout << "Hello World!";
  15. }
  16. ///factorial.cpp
  17. #include "functions.h"
  18. int factorial(int n)
  19. {
  20. if(n!=1)
  21. { return(n * factorial(n-1)); }
  22. else return 1;
  23. }
  24. //functions.h
  25. void
  26. print_hello();
  27. int factorial(int n);

请将以上文件放到一个目录下。

 

请注意: 我用的是g++进行编译的,你也可以按照你自己的选择来编译程序

make的作用

如果你运行:    make命令, 它将会自动的在你的目录下寻找makefile文件,然后执行它,如果你几个makefile文件,你可以指定某一个特定的makefile文件 使用如下命令:

make -f  mymakefile

如果你想知道更多的make 用法,可以执行man  make 命令

执行过程

  1. 编译器将会编译你的源文件,然后输出目标文件
  2. 链接器执行目标文件然后创建一个可执行文件。
手动编译  
 

最不理想的一种执行方式就是

g++ main.cpp hello.cpp factorial.cpp -o hello

 

akefile 基本规则

makefile的基本规则是有以下构成:

target: dependencies

[tab] system command

利用以上语法编写如下

all:

g++main.cpp hello.cpp factorial.cpp -o hello

然后运行你的makefile,如下

make -f Makefile-1

如上代码叙述,所写的目标是all,all是makefile默认的目标,如果没有其他规定,make语法将要执行这个目标文件。

我们还发现,all 目标并没有依赖的,所以按照命令让他安全的执行。

最后,make 通过 我们给的命令进行编译程序

使用依赖

这是因为,如果你修改一个单独的文件在你的项目,你不必重新编译一切,只有你修改。 请看下边的例子

  1. all: hello
  2. hello: main.o factorial.o hello.o
  3. g++ main.o factorial.o hello.o -o hello
  4. main.o: main.cpp
  5. g++ -c main.cpp
  6. factorial.o: factorial.cpp
  7. g++ -c factorial.cpp
  8. hello.o: hello.cpp
  9. g++ -c hello.cpp
  10. clean:
  11. rm -rf *o hello

我们看到目标all 只有依赖,没有系统命令。为了去执行正确,它必须满足所有的目标所依赖的。目标都回去搜索所有的依赖,然后去执行它。

在例子中,我们看到了clean的目标,clean 这个目标就是清楚中间生成的.o文件和那些可执行文件

使用变量和注释

当你写makefile文件的时候,当你想改变一些编译的一些选项的时候,他是非常有用处的。

 
  1. # 这是注释,CC 编译器.
  2. CC=g++
  3. # CFLAGS  是选项
  4. CFLAGS=-c -Wall
  5. #  目标文件
  6. OBJECTS=main.o factorial.o hello.o
  7. all: hello
  8. hello: $(OBJECTS)
  9. $(CC) main.o factorial.o hello.o -o hello
  10. main.o: main.cpp
  11. $(CC) $(CFLAGS) main.cpp
  12. factorial.o: factorial.cpp
  13. $(CC) $(CFLAGS) factorial.cpp
  14. hello.o: hello.cpp
  15. $(CC) $(CFLAGS) hello.cpp
  16. clean:
  17. rm -rf *o hello

你可以看到,使用这些有时候是非常有用的。你可以使用它们,赋值,当你想改变一些变量值的时候,然后你可以使用$(var),来应用这些变量。

如何继续下去

通过以上简要的介绍,你就可以简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边讲的只是冰山一角,你可以通过拥有变量和函数的make的文档来写。

Makefile有三个非常有用的变量.分别是$@,$>,$<代表的意义分别是:
$@--目标文件,$>--所有的依赖文件,$<--第一个依赖文件.
经过简化后我们的Makefile是简单了一点,不过人们有时候还想简单一点.这里我们学习
一个Makefile的缺省规则
..c.o:
gcc -c $<
这个规则表示所有的 .o文件都是依赖与相应的.c文件的.

  1. CC=g++
  2. CFLAGS=-c -Wall
  3. LDFLAGS=
  4. SOURCES=main.cpp hello.cpp factorial.cpp
  5. OBJECTS=$(SOURCES:.cpp=.o)
  6. EXECUTABLE=hello
  7. all: $(SOURCES) $(EXECUTABLE)
  8. $(EXECUTABLE): $(OBJECTS)
  9. $(CC) $(LDFLAGS) $(OBJECTS) -o $@
  10. .cpp.o:
  11. $(CC) $(CFLAGS) {1}lt; -o $@

如何编写makefile文件的更多相关文章

  1. 教会你如何编写makefile文件

    最近一直在学习makefile是如何编写的.当我们写的程序文件比较少的时候,敲入gcc /g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷.linux有一个自带的make命令,它让你的 ...

  2. 根据给定文件编写Makefile文件 两种方法编译

    实例一 1.分析源文件代码依赖关系 mian.c #include "test1.h" #include "test2.h" #include <stdi ...

  3. 转:教会你如何编写makefile文件

    最近一直在学习makefile是如何编写的.当我们写的程序文件比较少的时候,敲入gcc /g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷.linux有一个自带的make命令,它让你的 ...

  4. 为多个文件夹下的C源代码编写Makefile文件

    上一篇文章写了如何为在同一个文件夹下的C源代码,本篇文章为多个文件夹下的C源代码编写Makefile文件. 建立两个文件夹,分别为abs与src.其最终目录结构如下: 1 $ ls * 2 jun.c ...

  5. 单文件夹下的C程序如何编写Makefile文件

    通过学习已经学会了GCC的一些基础的命令,以及如何将C语言源代码编译成可执行文件. 我们已经知道在linux环境下编译源码时,常会有以下三个步骤: ./configure make make clea ...

  6. 简单编写makefile文件,实现GCC4.9编译项目,增加boost库測试等等。。

    一.须要用到的hw.cpp hw.h funtest.cpp funtest.h makefile 几个測试文件 1.hw.cpp代码例如以下: #include "hw.h" # ...

  7. C++ Makefile文件编写

    对现有的一个C++动态库文件和调用程序,分别编写Makefile文件,从零开始,这里把自己弄明白的一些东西分享给大家. 1.必须明确Linux下,C++的编译器是g++,C语言的是gcc.网上大多数又 ...

  8. 如何快速编写大项目的Makefile文件

    在构建C++的后台服务时,经常需要自己来编写makefile文件,而如果没有合适的方法或模板时,编写makefile文件是一件很费时费力的事情.因此,为了帮助程序员高效准确的编写makefile文件, ...

  9. Makefile文件学习总结

    Makefile文件相当于是一种脚本编程语言,目的是实现自动化编译.编写makefile文件的过程中可以使用变量.控制结构和函数等一般编程语言的特性. Makefile文件的组成内容.makefile ...

随机推荐

  1. 如何学习、了解Kubernetes?

    欢迎访问网易云社区,了解更多网易技术产品运营经验 [Kubernetes官方文档](https://kubernetes.io/docs/tutorials/)是最基本的入门教材,这里的内容是最官方, ...

  2. 附2 volatile

    注:在阅读本章之前,先要了解Java内存模型,见上一章<附1 Java内存模型与共享变量可见性>,链接如下: http://www.cnblogs.com/java-zhao/p/5124 ...

  3. 前端分享----JS异步编程+ES6箭头函数

    前端分享----JS异步编程+ES6箭头函数 ##概述Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只 ...

  4. git小白使用教程(一)

    本文所涉及命令基本可以涵盖日常开发场景, 对于开发者平时很少使用的命令不再列举,这样不至于让刚刚使用git的小伙伴们看的脑袋大...如有特殊使用可以联系我单独回复. 首先通过一张图了解git的工作流程 ...

  5. jQuery核心函数的四种不同用法

    核心函数根据实参的不同,有四种不同的用法. ①传一个函数作为参数 例如:$(function(){}) 作用:和window.onload = function(){}类似,它会在文档加载完成之后运行 ...

  6. pythonweb框架Flask学习笔记03-变量规则

    #-*- coding:utf-8 -*- from flask import Flask app=Flask(__name__) @app.route('/post/<int:postid&g ...

  7. C++基础知识 基类指针、虚函数、多态性、纯虚函数、虚析构

    一.基类指针.派生类指针 父类指针可以new一个子类对象 二.虚函数 有没有一个解决方法,使我们只定义一个对象指针,就可以调用父类,以及各个子类的同名函数? 有解决方案,这个对象指针必须是一个父类类型 ...

  8. Redhead安装VMware Tools

    Redhead安装VMware Tools VMware Tools 是款插件,便于在图形化界面中移动鼠标和复制拖动文件,对于redhead等命令符界面用处不大. 2.挂载光盘安装方法

  9. vue微信分享链接添加动态参数

    微信分享时 分享链接携带参数可能不是固定的 需要在分享的前一刻才知道 这里就是动态设置分享链接的基本写法 代码不是那么详尽 但大致流程如下 1.安装引用jssdk npm install --save ...

  10. 7.xamarin.android 发布签名与控制apk大小

    概述 做了xamarin android 后大家想打包一个apk,发布给其他人使用本章我们将带领大家如何打包签名一个apk. 打包 对于VS2017 或者是VS MAC来说打包一个APK非常简单. 首 ...