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

makefile是一种特殊的文件格式,他将会帮你自动管理你的项目,很强大。
 
下面通过实例一步步讲解如何使用makefile。下面的四段代码。
 
//main.cpp

#include "functions.h" 

int main()

{ 

print_hello(); 

cout << endl; 

cout << "The factorial of 5 is " << factorial(5) << endl; 

return 0; 

} 

//hello.cpp 

#include "functions.h" 

void print_hello()

{ 

cout << "Hello World!"; 

} 

///factorial.cpp

#include "functions.h" 

int factorial(int n)

{ 

if(n!=1)

{ return(n * factorial(n-1)); } 

else return 1; 

} 

//functions.h

void 

print_hello();

 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 通过 我们给的命令进行编译程序

使用依赖

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

all: hello

hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello main.o: main.cpp
g++ -c main.cpp factorial.o: factorial.cpp
g++ -c factorial.cpp hello.o: hello.cpp
g++ -c hello.cpp clean:
rm -rf *o hello

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

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

使用变量和注释

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

# 这是注释,CC 编译器.
CC=g++
# CFLAGS 是选项
CFLAGS=-c -Wall
# 目标文件
OBJECTS=main.o factorial.o hello.o
all: hello hello: $(OBJECTS)
$(CC) main.o factorial.o hello.o -o hello main.o: main.cpp
$(CC) $(CFLAGS) main.cpp factorial.o: factorial.cpp
$(CC) $(CFLAGS) factorial.cpp hello.o: hello.cpp
$(CC) $(CFLAGS) hello.cpp clean:
rm -rf *o hello

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

来应用这些变量

如何继续下去

通过以上简要的介绍,你就可以简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边讲的只是冰山一角

,你可以通过差一些make的文档来写。

CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@ .cpp.o:
$(CC) $(CFLAGS) {1}lt; -o $@

转:教会你如何编写makefile文件的更多相关文章

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

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

  2. 如何编写makefile文件

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

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

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

  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. JDK源码(1.7) -- java.util.Map<K,V>

     java.util.Map<K,V> 源码分析 --------------------------------------------------------------------- ...

  2. ACM -- 算法小结(七)Phone list解题报告

          HDOJ -- Phone list解题报告 问题描述:给出一些电话号码,如果有共同前缀则输出NO,如果没有则输出YES. 解题关键:将电话号码进行字符串排序,相邻的电话号码进行比较 Sa ...

  3. Markdown 简明语法手册 - 作业

    目录 Cmd Markdown 简明语法手册 1. 内容目录 2. 标签分类 3. 删除线 水平线--- 1. 斜体和粗体 2. 分级标题 标题1 标题2 标题3 3. 外链接 4. 无序列表 5. ...

  4. 原来通过修改dns加快app store下载速度的确有效

    说来惭愧,这几天休假,并没有做什么技术上的修行.小伙伴推荐我一款avg游戏<11eyes 罪与罚与被诅咒的少女>,说是神作.但是app store上卖rmb118元,起初并没有什么兴趣去购 ...

  5. require(): open_basedir restriction in effect. 解决方法

    在linux服务器部署thinkphp5的时候PHP报了这个错误, 如下: Warning: require(): open_basedir restriction in effect. File(/ ...

  6. 用C++/CLI搭建C++和C#之间的桥梁(二)—— 基本语法

    托管对象的创建和引用 在前文中我们已经演示过创建一个托管对象,对于如下C#代码: System.Object x = new System.Object(); 其在C++/CLI中的等价代码如下: S ...

  7. 【redis】redis五大类 用法 【转载:https://www.cnblogs.com/yanan7890/p/6617305.html】

    转载地址:https://www.cnblogs.com/yanan7890/p/6617305.html

  8. ARMv7处理器各个模式之间是怎样切换的?模式切换时上下文的保存哪些是硬件在做?哪些是操作系统在做?

    1.ARM处理器各个模式之间是怎样切换的? 答:除用户模式外的其它6种模式称为特权模式,这些模式中,程序能够訪问全部系统资源,也能够随意进行处理器模式的切换.处理器模式能够通过软件控制进行切换(直接设 ...

  9. Android中各级目录的作用

    Android中各级目录的作用 一.目录结构  src目录---存放源代码文件   gen目录---ADT插件生成的文件,(自动生成) R.java文件  drawable类---给图片生产的ID  ...

  10. 深度学习Deep learning

    In the last chapter we learned that deep neural networks are often much harder to train than shallow ...