最近要在unix系统上开发c++应用程序,但默认情况下unix编译c++程序需要使用makefile。其实makefile语法还是比较简单,看上去有点像ant。废话不说了,直接上helloworld。

编写了3个文件,分别是file1.c、file2.c和file2.h。

file1.c代码:

  1. #include <stdio.h>
  2. #include "file2.h"
  3. int main() {
  4. printf("print file1$$$$$$$$$$$$$$$$$$$$$$$$\n");
  5. File2Print();
  6. return 0;
  7. }

file2.c代码:

  1. #include <stdio.h>
  2. #include "file2.h"
  3. void File2Print() {
  4. printf("Print file2**********************\n");
  5. }

file2.h代码:

  1. #ifndef FILE2_H_
  2. #define FILE2_H_
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. void File2Print();
  7. #ifdef __cplusplus
  8. }
  9. #endif
  10. #endif

先来个比较基础的makefile列子:

  1. helloworld : file1.o file2.o
  2. gcc file1.o file2.o -o helloworld
  3. file1.o : file1.c file2.h
  4. gcc -c file1.c -o file1.o
  5. file2.o : file2.c file2.h
  6. gcc -c file2.c -o file2.o
  7. clean :
  8. rm -rf *.o helloworld

一个makefile 主要含有一系列的规则,如下:
A: B
(tab)<command>
(tab)<command>

每个命令行前都必须有tab符号。

上面的makefile文件目的就是要编译一个helloworld的可执行文件。让我们一句一句来解释:
helloworld : file1.o file2.o: helloworld依赖file1.o file2.o两个目标文件。
 gcc File1.o File2.o -o helloworld: 编译出helloworld可执行文件。-o表示你指定 的目标文件名。
 
file1.o : file1.c: file1.o依赖file1.c文件。
gcc -c file1.c -o file1.o: 编译出file1.o文件。-c表示gcc 只把给它的文件编译成目标文件, 用源码文件的文件名命名但把其后缀由“.c”或“.cc”变成“.o”。在这句中,可以省略-o file1.o,编译器默认生成file1.o文件,这就是-c的作用。

file2.o : file2.c file2.h
gcc -c file2.c -o file2.o

这两句和上两句相同。

clean: rm -rf *.o helloworld

当用户键入make clean命令时,会删除*.o 和helloworld文件。
 
如果要编译cpp文件,只要把gcc改成g++就行了。

写好Makefile文件,在命令行中直接键入make命令,就会执行Makefile中的内容了。
 
到这步我想你能编一个Helloworld程序了。

来个进阶的列子,主要是使用变量:

  1. OBJS = file1.o file2.o
  2. CC = gcc
  3. CFLAGS = -Wall -O -g
  4. helloworld : $(OBJS)
  5. $(CC) $(OBJS) -o helloworld
  6. file1.o : file1.c file2.h
  7. $(CC) $(CFLAGS) -c file1.c -o file1.o
  8. file2.o : file2.c file2.h
  9. $(CC) $(CFLAGS) -c file2.c -o file2.o
  10. clean:
  11. rm -rf *.o helloworld

这里我们应用到了变量。要设定一个变量,你只要在一行的开始写下这个变量的名字,后 面跟一个= 号,后面跟你要设定的这个变量的值。以后你要引用 这个变量,写一个$ 符号,后面是围在括号里的变量名。
 
CFLAGS = -Wall -O –g,解释一下。这是配置编译器设置,并把它赋值给CFFLAGS变量。
-Wall: 输出所有的警告信息。
-O: 在编译时进行优化。
-g: 表示编译debug版本。

这样写的Makefile文件比较简单,但很容易就会发现缺点,那就是要列出所有的c文件。如果你添加一个c文件,那就需要修改Makefile文件,这在项目开发中还是比较麻烦的。

再来一个更通用的写法,使用函数、变量来构成makefile程序。

  1. CC = gcc
  2. XX = g++
  3. CFLAGS = -Wall -O –g
  4. TARGET = ./helloworld
  5. SOURCES = $(wildcard *.c *.cpp)
  6. OBJS = $(patsubst %.cpp, %.o, $(SOURCES))
  7. $(TARGET):$(OBJS)
  8. $(XX) $(OBJS) -o $(TARGET)
  9. chmod a+x $(TARGET)
  10. clean:
  11. rm -rf *.o helloworld

函数1:wildcard
产生一个所有以'.c' 结尾的文件的列表。
SOURCES = $(wildcard *.c *.cpp)表示产生一个所有以.c,.cpp结尾的文件的列表,然后存入变量SOURCES 里。
 
函数2:patsubst
匹配替换,有三个参数。第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的列表。

OBJS = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCES)))表示把文件列表中所有的.c,.cpp字符变成.o,形成一个新的文件列表,然后存入OBJS变量中。

最后说下比较有用的两个表达方式的用法$@和$<

  1. %.o:%.c
  2. $(XX) $(CFLAGS) -c $< -o $@
  3. @echo $@
  4. %.o:%.cpp
  5. $(XX) $(CFLAGS) -c $< -o $@
  6. @echo $@

makefile简单helloworld的更多相关文章

  1. Gcc的Makefile简单使用

    Gcc的Makefile简单使用http://blog.chinaunix.net/uid-9330295-id-2425867.html

  2. makefile编写helloworld

    相信在unix下编程的没有不知道makefile的,刚开始学习unix平台 下的东西,了解了下makefile的制作,觉得有点东西可以记录下. 下面是一个极其简单的例子: 现在我要编译一个Hello ...

  3. [编译] 1、第一个makefile简单例子

    前言 本篇用一个最简单的例子引入makefile,教你编写第一个makefile 正文 在Download/aa文件夹下有a.c和makefile文件 litao@litao:~/Downloads/ ...

  4. SpringMVC学习简单HelloWorld实例

    首先还是从一个简单的Hello World项目说起: 我机器的开发环境为: Ubuntu12.04(不同操作系统对本系列项目没有影响): 开发工具:Eclipse For JavaEE: 数据库:My ...

  5. makefile简单学习

    前言 在C语言中,我们需要将源代码生成可执行的程序.这里面其实要经过非常多的步骤.参看下图: 这中间主要通过make命令,读取一种名为“makefile”或“Makefile”的文件来实现软件的自动化 ...

  6. MATLAB---make与makefile简单介绍

    1 make.makefile概述 makefile定义了一系列的规则,来规定哪些部分先编译,哪些部分后编译,写好makefile以后,只需一个make命令就可以让整个工程完全自动编译,所以简单的说, ...

  7. Makefile简单编写实例

    介绍一下Makefile的简单编写例子. 编写Makefile的规则就是: 目标文件:依赖文件 (tab)编译规则 现在我有一个文件目录结构为: 解释一下这几个文件.首先我创建makefile目录,底 ...

  8. makefile 简单介绍

    使用与来源: makefile文件(可由./configure创建)被make命令读取,make 命令执行时,需要一个 Makefile 文件,以告诉 make 命令需要怎么样的去编译和链接程序. 功 ...

  9. 【Linux学习】 包含子目录的makefile简单应用

    1 .目录结构 practice6 / ui / ui.h   ui.c practice6 / dal / dal.h dal.c practice6 / bll / bll.h  bll.c pr ...

随机推荐

  1. 如何寻找java的安装路径问题

    关于不知道JAVA安装在linux的哪 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans ...

  2. jQuery中的类型判断

    在JQuery中有一个type方法,在1.11.2中是这样写的 var class2type = {}; var toString = class2type.toString; jQuery.each ...

  3. codeforces 553D . Nudist Beach 二分

    题目链接 有趣的题. 给一个图, n个点m条边. 有k个点不可选择. 现在让你选出一个非空的点集, 使得点集中strength最小的点的strength最大. strength的定义:一个点周围的点中 ...

  4. Java+Python+Jython环境变量配置

    一.Java 环境变量配置: 新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.7.0变量名:CLASSP ...

  5. svn 同步到web目录

    windows  hook 下 @echo offSET REPOS=%1SET REV=%2SET DIR=%REPOS%/hooksSET PATH=%PATH%;SET WORKING=D:/w ...

  6. ReentrantLock(重入锁)以及公平性

    ReentrantLock(重入锁)以及公平性 标签(空格分隔): java NIO 如果在绝对时间上,先对锁进行获取的请求一定被先满足,那么这个锁是公平的,反之,是不公平的,也就是说等待时间最长的线 ...

  7. JAVA代码静态检测之PMD

    今天再次想启动Java代码静态检测工具的利用问题,主要再次尝试用了PMD,发现不少代码编码规范问题和好的代码建议,并学到不少自己之前没有注意到的Java方便的基础知识,感觉很不错,把相关明白的好的规则 ...

  8. S3C6410嵌入式应用平台构建(二)

    [2014-4/11~4/14]经过之前的实验,对Uboot已经有了大体的了解,前我们已经把led灯给点亮,但这不是我们的根本目的,我们是要进入boot启动,经过两天的分析代码和反复的实验,终于可以进 ...

  9. VB6关于判断模态窗体的问题

    模态窗体也有人叫模式窗体,是否为模态窗体由Show方法的参数决定: 语法 object.Show style, ownerform Show 方法的语法包含下列部分: 部分 描述 object 可选的 ...

  10. 配置tomcat的https通信(单向认证)

    1.首先用jdk带的工具生成证书库 打开cmd命令行窗口,cd 到tomcat安装目录的bin下面执行 keytool -v -genkey -alias tomcat -keyalg RSA -ke ...