<转>Windows平台下Makefile学习笔记(一)
本文转自:http://blog.csdn.net/clever101/article/details/8147352
决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开发,但我还没安装VS2010,我想在VS2008下编译这些代码);另一方面源码在服务器端编译的话,使用IDE的方式编译还是不太方便。
本文主要分为三部分:第一部分讲述namke工具使用makefile的用法;第二部分讲述makefile的主要语法;第三部分讲述自己动手实践学习写makefile文件。第四部分是编写一个工具将vc工程文件转化为Makefile文件。
首先要清楚的是在VS环境下使用Makefile的工具是nmake。因此我们需要弄明白nmake的使用Makefile文件常用命名行用法。nmake使用Makefile文件常用命名行用法是:
namke /f makefile /x stderrfile [macrodefs] [targets]
其中makefile为makefile文件,/x stderrfile为可选参数,即把namke错误存储到文件stderrfile。
接着介绍makefile的主要语法。makefile的注释以#开头,如:
# this is my first makefile
Makefile的一个重要组成部分是宏。Makefile中的宏和C语言的中宏类似,其实质就是字符串替换。其语法很简单,如下:
macro name = macro value
直译就是宏名 = 宏的值
VS预定义了很多宏,如OUTDIR,你可以在你的Makefile重新定义这些宏以覆盖原来的值。
宏可以使用环境变量,如你的系统有一个OPEN_SOURCE的环境变量,然后你可以这样定义宏:
THIRD_PARTY = $(OPEN_SOURCE)
宏的引用用法是 $(宏名)。
接着介绍Makefile的第二个重要组成部分预处理指令。Makefile的预处理指令和C语言的预处理指令类似,其常用指令如下:
!ERROR string —— 显示错误“string”, 然后停止执行,错误代码为U1050
!MESSAGE string —— 显示字符串,这个一般用于信息显示C语言的#pragma message
!INCLUDE [<]filename[>] —— 包含makefile。
!IF const —— 如果成立(非零),则处理!F和下一个!ELSE或!ENDIF之间的语句
还有诸如!IFDEF macroname、!IFNDEF macroname、!ELSE、!ELSEIF、!ELSEIFDEF、!ELSEIFNDEF、!ENDIF和C语言的#if之类的指令的意义是一致的,这里就不一一详述了。
Makefile的第三个主要组成部分是描述块。描述块的结构如下:
目标:依赖项
命令
这里略微解释下什么叫目标、依赖项和命令。所谓目标就是用户最终希望得到的结果,也就是nmake需要生成的结果。目标可以是一个文件、目录,也可以什么都不是。如果目标不存在或者目标的时间戳(文件的最后修改时间)比依赖项早,或者目标类型不是文件,nmake将运行描述块中的“命令”。
依赖项是指在生成目标所需要使用到的对象。一个目标可以有一个或多个依赖项,也可以没有依赖项。多个依赖项以空格分隔。如果指定的依赖项不存在,则在其他描述块的目标中寻找,但首先需要生成这个目标。
命令是nmake在生成目标时所调用的命令。与用户自己在命令行中执行效果是一样的。
在使用namke进行程序构建时,nmake采用了时间戳判断机制。在生成一个目标时,会判断目标文件是否存在或目标的最后修改时间是否晚于所有依赖项的最后修改时间。如果所有依赖项的最后修改时间都比目标的最后修改时间晚,则说明当前的目标文件是使用现有的依赖项生成,是最新的,没有必要再进行生成。
介绍到这里,可能你对Mdakefile的语法细节有了大致的了解,但估计你对Makefile的常用文件结构还不了解。如果缺少对这一层的理解,你还是对如何编写Makefile文件一头雾水。下面介绍一下常用的Makefile文件结构。Makefile文件结构可以是如下的结构:
# 宏定义
……
# 描述块
学了这么多,我们来实践一下。首先我们来一个简单的控制台工程——ConsoleTest。一切根据工程向导采用默认设置即可。然后在main函数中添加几句简单代码(这个用于判断我们生成的程序是否成功),具体如下:
int _tmain(int argc, _TCHAR* argv[])
{
printf("Hello World! \n");
getchar();
return ;
}
然后我们在ConsoleTest文件夹下新建一个makefile.vc。我们开始正式编写一个makefile文件了。这时我们的大脑可能会一片空白,虽然你学了很多makefile语法,但迈出第一步依然是困难,这是正常的反应。好吧,让我们一步步来吧。首先要告诉你makefile的一个基本原则:以终为始,这个似乎和我们平时进行的过程式编程的原则相悖。所谓以终为始,就是你通过makefile文件首先告诉编译器这个工程是想生成一个exe还是一个dll还是一个静态库。然后告诉编译器要生成这个exe之类需要生成哪些obj文件。在这个例子中,我们要生成一个exe,所以我们在makefile文件的第一行就是:
all:ConsoleTest.exe
接下来就是编译器的一般生成过程:编译加链接命令,具体是
# compile
stdafx.obj: stdafx.cpp
cl -c -D_X86= -DWIN32 -D_DEBUG -D_CONSOLE -Istdafx.h stdafx.cpp ConsoleTest.obj: ConsoleTest.cpp stdafx.obj
cl -c -D_X86= -DWIN32 -D_DEBUG -D_CONSOLE -Istdafx.h ConsoleTest.cpp # link
ConsoleTest.exe: ConsoleTest.obj
link /INCREMENTAL:YES /NOLOGO /subsystem:console /out:ConsoleTest.exe ConsoleTest.obj kernel32.lib
其中cl语句是VC编译器的编译器的命令行编译,link语句是VC链接器的命令行用法,这里只简单叙述cl和link的用法。
cl的一些常用选项:
-c: 编译但不链接
-D: 定义预处理器,如-D_X86=1:指定在x86平台上编译,-D_DEBUG:定义预处理器_DEBUG,
-I:包含的头文件
cl的最后一个参数是所编译的文件。
link的一些常用选项:
/INCREMENTAL:是否启用增量链接,YES为启用,NO为不启用,
/NOLOGO: 取消显示启动版权标志
/SUBSYSTEM:指定子系统,在PC桌面程序上一般是两个选项:console(控制台程序)和WINDOWS(非控制台程序)。
/out: 指定输出的文件。
link最后的参数是需要链接的obj文件和库文件。
cl和link的详细用法请参考MSDN和参考文献2《VC命令行编译C++》。
我们看到生成的obj文件和ConsoleTest.exe是放到当前的源码文件夹下。一般我们想把它放到debug文件夹下。那么我们该怎么做呢?这时就可以用到makefile中的一个常用部分——宏。我们可以这样定义一个宏,然后创建debug文件夹,具体代码是:
OUTDIR = .\Debug
#这里增加了一个输出:$(OUTDIR)
all: $(OUTDIR) $(OUTDIR)\ConsoleTest.exe
#假如不存在$(OUTDIR)文件夹,就创建它
<转>Windows平台下Makefile学习笔记(一)的更多相关文章
- [转]Windows平台下Makefile学习笔记
Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...
- <转>Windows平台下Makefile学习笔记(二)
本文转自:http://blog.csdn.net/clever101/article/details/8286066 上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用 ...
- 【VS开发】Windows平台下Makefile学习笔记
作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开 ...
- windows平台下VLC2.0.5编译
windows平台下VLC2.0.5编译说明 时隔一年多,又要搞流媒体了,不过这次是要做流媒体服务器. 暂时决定使用vlc+ffmpeg+live555,虽然听有些前辈说这个组合的性能较差,只能作为学 ...
- Windows平台下MySQL常用操作与命令
Windows平台下MySQL常用操作与命令 Windows平台下MySQL常用操作与命令,学习mysql的朋友可以参考下. 1.导出整个数据库 mysqldump -u 用户名 -p --defau ...
- Windows平台下Git服务器搭建
第一步:下载Java,下载地址:http://www.java.com/zh_CN/ 第二步:安装Java.安装步骤不再详述. 第三步:配置Java环境变量. 右键”计算机” => ”属性” = ...
- Windows平台下PHP开发环境的配置
Windows平台下PHP开发环境的配置 一.基本环境 1.Windows XP 32位 2.Apache 2.2.25,下载地址:http://mirror.bit.edu.cn/apache/ht ...
- Mac平台与Windows平台下AndroidStudio增量升级
Android Studio增量升级什么情况下使用最合适呢? 比如现在的as版本是2.2版本,而你的as版本2.0版本,这个时候点Check For Updates就没有反应了,因为你已经2个有版本没 ...
- Windows 平台下Git 服务器搭建
由于项目中一直在使用git作为版本管理,自己对git的理解.使用都还不是怎么的熟悉,所以准备深入了解一下git及一些常用命令的使用,于是干脆把服务端架上,通过自己的PC作为服务端同时作为客户端的角色进 ...
随机推荐
- python爬虫beautifulsoup4系列2【转载】
本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/beautifulsoup4/ 前言 本篇详细介绍beautifulsoup4的功能,从 ...
- cmake add_executable 与 include_directories
在cmake里add_executable里如果没有包含.cpp文件,该.cpp文件就不适用include_directories包含文件
- (分享别人的一篇好文章,来自jackson0714)30分钟全面解析-SQL事务+隔离级别+阻塞+死锁()
30分钟全面解析-SQL事务+隔离级别+阻塞+死锁 阅读目录 概述: 一.事务 二.锁 三.阻塞 四.隔离级别 五.死锁 以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQ ...
- 使用keytool生成ssl证书
使用keytool生成ssl证书 在项目中由于要使用https访问项目,然后了解到jdk有一个自带的工具keytool可以用来生成ssl证书,从而可以通过https进行访问. 使用keytool生成s ...
- Southern African 2001 框架折叠 (拓扑序列的应用)
本文链接:http://www.cnblogs.com/Ash-ly/p/5398377.html 题目:考虑五个图片堆叠在一起,比如下面的9 * 8 的矩阵表示的是这些图片的边缘框. 现在上面的图片 ...
- 数学【P2524】 Uim的情人节礼物·其之弐 (康托展开)
因为某人@ZAGER挖坑让我讲一下康托展开,所以发现了这个题,顺便说一下康托展开是个什么东西 题目概括 给定n与一个数列,要求求出给定数列在n的全排列中的排名(按照字典序从小到大排列) 康托展开 先放 ...
- UVA 11990 ”Dynamic“ Inversion(线段树+树状数组)
[题目链接] UVA11990 [题目大意] 给出一个数列,每次删去一个数,求一个数删去之前整个数列的逆序对数. [题解] 一开始可以用树状数组统计出现的逆序对数量 对于每个删去的数,我们可以用线段树 ...
- 八. 输入输出(IO)操作3.面向字符的输出流
面向字符的输出流都是类 Writer 的子类,其类层次结构如图 10-5 所示. 图10-5 Writer的类层次结构图 表 10-3 列出了 Writer 的主要子类及说明. 表 10-3 Writ ...
- SYSPROCESSES 查看连接
原文:SYSPROCESSES 查看连接 SELECT at.text,sp.* FROM[Master].[dbo].[SYSPROCESSES] sp CROSS APPLY sys.dm_exe ...
- Word中如何公式居中标号右对齐
1.鼠标居中 2.插入一行三列表格 3.选中第一个表格,右键-表格属性-单元格-选项:然后回到单元格设置垂直居中,宽度为15%,同理第三个单元格,不过中间单元格也要设置,宽度为70%,这个word没有 ...