最近要在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. Flink资料(4) -- 类型抽取和序列化

    类型抽取和序列化 本文翻译自Type Extraction and Serialization Flink处理类型的方式比较特殊,包括它自己的类型描述,一般类型抽取和类型序列化框架.该文档描述这些概念 ...

  2. GDB调试方法(转)

    一:列文件清单 1. List (gdb) list line1,line2 ************************************************************* ...

  3. 【异常处理】java.lang.NoClassDefFoundError

    Exception in thread"main" java.lang.NoClassDefFoundError:org/apache/commons/lang/exception ...

  4. OSG事件回调

    OSG中的节点主要使用回调(CallBack)来完成用户临时.需要每帧执行的工作.根据回调功能被调用的时机划分为更新回调(Update CallBack)和人机交互时间回调(Event CallBac ...

  5. 如何解决”无法将类型为“System.DateTime”的对象强制转换为类型“System.String”。“

    字段Time在数据库中为datetime类型 dr.GetString(3).ToString() dr.GetString(3).ToString() => dr.GetDateTime(3) ...

  6. material风格的日期/时间选择:SublimePicker

    介绍: 一个material风格的view,提供了各种关于日期选择的功能,可以选择日期,选择时间,选择重复次数等,可以在不离开选择器的情况下在不同的选择界面间切换.其实这些功能是从5.0的日历中抠出来 ...

  7. 九度OnlineJudge之1021:统计字符

    题目描述:     统计一个给定字符串中指定的字符出现的次数. 输入:     测试输入包含若干测试用例,每个测试用例包含2行,第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串.注 ...

  8. python访问cloudstack的api接口

    1.CloudStack API 如同 AWS API 一样,CloudStack API 也是基于 Web Service,可以使用任何一种支持 HTTP 调用的语言(例如 Java,python, ...

  9. ReactNative遇到的一些坑

    1. 如果通过一个url进行下载上传操作,这个url中包含有中文的话,一定要记得将这个url转为URLEncode编码. 如: encodeURI('http://test/有中文.doc'); 2. ...

  10. Loading Image

    Android doesn’t handle animated gifs, but here’s one way to display an animated loading image that i ...