windows下makefile命令详解

摘要:
vc6:vs2008:为了能正确地使用命令行工具及vc6或vs2008下的函数库,需要对一些环境变量进行设置,最快捷地方式是通过如下方式打开命令行窗口:2.vs的c++工程没有提供导出nmake脚本文件的功能,我们只有借助工具或手动编写nmake脚本文件了++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++3.rc.exe/l0x804//默认语言ID0x804:简体中文0x409:美国更多.../fo"nMakeTest.res"//指定rc文件输出的res名称例:rc.exe/l0x804/fo"nMakeTest.res"/d"_DEBUG"/d"_AFXDLL"“nMakeTest.rc”4.cl.exe常见选项更多.../nologo//不打印版权申明信息/I"../include"//添加头文件查找路径/DWIN32  //预编译宏定义/D_CONSOLE//预编译宏定义/D"_DEBUG"//预编译宏定义/D_CRT_SECURE_NO_DEPRECATE//预编译宏定义(关闭C4996警告。

转自https://blog.csdn.net/xiexievv/article/details/45775005

1. 如果已经有vc6的dsp工程,可直接导出nmake脚本文件(.mak)

“Project - Export Makefile...”

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug"

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug" all

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Release" clean

注:如果未指定/F选项,则使用当前目录下的名为makefile的文件

【nmake /?】 获取更多帮助! vc6:【D:program filesMicrosoft Visual StudioVC98Bin】

vs2008:【D:program filesMicrosoft Visual Studio 9.0VCin】

为了能正确地使用命令行工具及vc6或vs2008下的函数库,需要对一些环境变量进行设置,最快捷地方式是通过如下方式打开命令行窗口(以vs2008为例):

windows下makefile命令详解第1张

2. vs的c++工程没有提供导出nmake脚本文件的功能,我们只有借助工具或手动编写nmake脚本文件了

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3.rc.exe【将.rc资源文本转变成.res二进制文件】

/l0x804//默认语言ID(十六进制数表示) 0x804:简体中文 0x409:美国更多...

/fo"nMakeTest.res"// 指定rc文件输出的res名称

例:rc.exe/l 0x804 /fo"nMakeTest.res" /d "_DEBUG" /d "_AFXDLL" “nMakeTest.rc”

4.cl.exe常见选项 【将.c,.cpp,.cxx编译成obj文件】 更多...

/nologo // 不打印版权申明信息

/I "../include" // 添加头文件查找路径(如果路径中带有空格,一定要用引号括起来)

/DWIN32  // 预编译宏定义(win32程序)

/D_CONSOLE//预编译宏定义(控制台程序)

/D"_DEBUG"//预编译宏定义(Debug版本)

/D_CRT_SECURE_NO_DEPRECATE//预编译宏定义(关闭C4996警告。使用strcpy、strcat等不安全函数时会报C4996警告)

/D_CRT_NONSTDC_NO_DEPRECATE //预编译宏定义(关闭C4996警告。使用strcpy、strcat等不安全函数时会报C4996警告)

/Od//优化选项:带入Debug信息

/O2// 优化选项:最快速度

/O1 // 优化选项:最小尺寸

/W3  // 设置3级警告级别

/WX // 将Warining视为error

/Fp"nMakeTest.pch"// 指定预编译文件名

/Yu"stdafx.h"// 在生成期间使用预编译头文件

/FI"myheader.h"// 在每个源文件的第一行上的#include该文件

/Fd"vcpdb/testpdb"// 会将vc辅助编译的idb及pdb文件(见下面的/Gm选项)输入到vcpdb目录中,

并重命名为testpdb.idb与testpdb.pdb(这里的pdb为projectdatabase文件,用于存工程的数据库信息)

/Fo"objFiles"// 将obj文件输出到objFiles目录中

/c  //编译但不链接

/feMyTest// 编译后,输出MyTest.exe可执行文件

/EHsc //打开"C++例外(Exceptions)",以免出现编译器警告

/LD  //创建动态链接库
/LDd  //创建调试动态链接库

/ML  // 使用 libc.lib 创建单线程可执行文件
/MLd  // 使用 libcd.lib 创建调试单线程可执行文件
/MT  // 使用 libcmt.lib 创建多线程可执行文件
/MTd  // 使用 libcmtd.lib 创建调试多线程可执行文件
/MD  // 使用 msvcrt.lib/msvcrt.dll 创建多线程可执行文件
/MDd  // 使用 msvcrtd.lib/msvcrtd.dll创建调试多线程可执行文件

/Z7  //生成与 C7.0兼容的调试信息
/Zd  //生成行号
/Zi  //生成完整的调试信息

/Gm //启用最小重新生成

编译器在.idb文件中存储源文件和类定义之间的依赖关系。
使用.idb 文件的信息来确定是否需要编译某个源文件。
而不是该源文件只要包含了被修改的.h文件,就必须重新编译。

/link  // 将/link后指定的选项传递给link.exe

// 默认情况下,cl.exe编译完后,会自动调用link.exe进行连接,
// 所以直接用cl.exe编译带main函数的.c或.cpp后,会生成obj与exe文件。

例:cl /c test1.cpp test2.cpp // 编译test1.cpp,test2.cpp

例:cl *.cpp /MD /c /I"G:Visual C++VC98PlatformSDKInclude"

5.link.exe常见选项 【将obj、lib、res链接成dll或exe等可执行文件】

/dll  // 输出dll文件

-lib // 生成lib静态库文件 例:link -lib *.obj/out:test.lib

/libpath:"..PublicSDKlib"// 指定外部lib查找路径(路径中不能带有空格,否则链接时会报LNK1181的错误)

/subsystem:windows[console] // 指定子系统

/machine指定目标平台{AM33|ARM|EBC|IA64|M32R|MIPS|SH3|SH3DSP|SH4|SH5|THUMB|X86|X64},等

/NODEFAULTLIB:libcd.lib // 链接时,忽略libcd.lib库

/debug  // 生成调试信息

/export:myAdd=_Add,@1 // 导出extern "C" Add函数,并将符号名修改为myAdd,同时将导出序号设为1(一种dll动态库导出符号的方法)

/export:_g_isTest,@2 // 导出extern "C"g_isTest变量,并将导出序号设为2(一种dll动态库导出符号的方法)

/def:"nMakeTest.def"// 模块导出文件【如果def文件名称与dll名称一致,则不需要显示地指出】(另外一种dll动态库导出符号的方法)

;nMakeTest.lib 导出DLL函数
;作者:kekec
LIBRARY nMakeTest.def
EXPORTS
Add @ 1
g_isTest @ 2

注:还可以在代码中使用__declspec(dllexport)进行符号的导出

#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif

/************** export.c ***************/
#ifdef __cplusplus
extern "C"
{
#endif
WIN32DLL_API int __stdcall Add(int a, int b)
{
return (a + b);
}

WIN32DLL_API int g_isTest = 0;
#ifdef __cplusplus
}
#endif

/pdb:"nMakeTest.pdb"// 重命名生成的pdb文件(Program Debug Database),保存调试符号等信息

/map:"nMakeTest.map"// 重命名生成的map文件

/out:"nMakeTest.exe"// 重命名生成的exe文件

/implib:"test.lib"  // 生成名为test.lib的导出库

/entry:_DllMainCRTStartup@12// 指定_DllMainCRTStartup函数dll的起始地址

/incremental:yes // 开启增量链接

incremental开关默认是开启的。
开启增量链接产生的exe或dll文件的size要大一些。
因为有代码和数据的填充,增量链接的exe或dll文件会包含跳转trunk来处理函数重定位到新地址。
MSDN上明确指出:为确保最终发布版本不包含填充或者trunk,请关闭增量链接。

例:link gdiplus.lib/subsystem:windows /out:test.exe file1.obj file2.lib file3.res// 生成名为test.exe的windows可执行程序
例:link gdiplus.lib/subsystem:console /out:test.exe *.obj file2.lib file3.res// 生成名为test.exe的控制台可执行程序
例:link gdiplus.lib/subsytem:windows /dll /out:test.dll /implib:test.lib/def:test.def *.obj file2.lib file3.res// 生成名为test.dll动态库

例:link *.obj rc.res /LIBPATH:"G:Visual C++lib" /SUBSYSTEM:WINDOWS /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib OpenGL32.Lib

6.nmake指令说明

(1) 符号说明

#// 注释符(命令所在行不能使用注释符,命令应该与注释都独立使用一行进行书写;如:erase nMakeTest.obj # 删除nMakeTest.obj文件【非法】)

^#abc//表示#abc这个字符串

// 连接符,用于将两行合并为一行;在宏中,分多行写时,一定要用""进行连接

%  // 文件说明符,表示其后的字符串为一文件名

---------------------

若文件名为 c:prog.exe
%s 将为 c:prog.exe
%:F 将为 c:prog.exe
%:dF 将为 c
%:pF 将为 c:
%:fF 将为 prog
%:eF 将为 exe

---------------------

@  // 命令修饰符;防止修饰的命令的结果,被打印出来

! // 命令修饰符

$  // 宏引用符

:  // 依赖符号

?【*】  // 通配符支持

++++++++++++++++++++++++++++++++++++

$@ // 表示所有目标全名(路径+文件名称+扩展名)的挨个值

$$@// 与$@用法含义一致,但仅在作为依赖项中的依赖项时有效

$< // 表示所有依赖目标的挨个值,仅在推理规则的命令中有效

$^ // 表示所有依赖目标的集合,以空格分隔,若有重复,会被去重;

$+// 与$^含义一致,只是不进行去重处理。
$? // 表示所有比目标心的依赖目标的集合,以空格分隔

$* // 当前目标的路径和文件名称,没有文件扩展名
$**// 当前目标的所有依赖项

----------------------------

修饰符 说明
D 驱动器和目录
B 文件名称
F 文件名称和扩展名
R 驱动器、目录和文件名称

----------------------------

(2)长文件名用双引号引起来

例:ALL : nMakeTest.dll  // 文件名较短时,可不需要引号
例:ALL : "$(OUTDIR) MakeTest.exe"// 文件名较长时,特别是路径中有空格的情况,一定要用引号

(3) 预定义规则

.c.obj // 默认操作:cl/c$*.c

也可对默认操作显示地重写:

.c.obj:
cl /c /Ox /DWIN32 $<

(4) 包含文件

!INCLUDE nmake.opt

include makefile.mak

(5) 条件判断 - 01

!IF "$(CFG)" == ""
CFG=nMakeTest - Win32 Debug
!MESSAGE No configuration specified. Defaulting to nMakeTest - Win32 Debug.
!ELSE
!MESSAGE Be specified.
!ENDIF

(6) 条件判断 - 02 【!IFNDEF !IFDEF】

!IFNDEF PRIVATE_RUNTIMEMODE_DEBUG
RUNTIMEMODE_DEBUG = /MDd
!ELSE
RUNTIMEMODE_DEBUG = $(PRIVATE_RUNTIMEMODE_DEBUG)
!ENDIF

(7) 输出消息日志

!MESSAGE Invalid configuration "$(CFG)" specified.

(8) 描述块 - makefile的核心【注:在依赖项(或规则)和命令块之间不能出现空行,commands之前为一个tab字符,多条command之间用;分割】

只要dependences中任意一个文件比targets新,就执行commands命令

targets... : dependences...
commands...

(9) ALL / CLEAN

OUTDIR=.Release
INTDIR=.Release
ALL : "$(OUTDIR) MakeTest.exe"
CLEAN :
-@erase "$(INTDIR) MakeTest.obj"
-@erase "$(INTDIR) MakeTest.pch"
-@erase "$(INTDIR) MakeTest.res"
-@erase "$(INTDIR) MakeTestDlg.obj"
-@erase "$(INTDIR)StdAfx.obj"
-@erase "$(INTDIR)vc60.idb"
-@erase "$(OUTDIR) MakeTest.exe"
-@erase "$(OUTDIR) MakeTest.map"
"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

(10) 编译

CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR) MakeTest.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\" /FD /c
.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<
.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<

(11) 链接

LINK32=link.exe
LINK32_FLAGS=/nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR) MakeTest.pdb" /map:"$(INTDIR) MakeTest.map" /machine:I386 /out:"$(OUTDIR) MakeTest.exe"
LINK32_OBJS=
"$(INTDIR) MakeTest.obj"
"$(INTDIR) MakeTestDlg.obj"
"$(INTDIR)StdAfx.obj"
"$(INTDIR) MakeTest.res"
"$(OUTDIR) MakeTest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<

(12) 文件依赖

SOURCE=. MakeTest.cpp
"$(INTDIR) MakeTest.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR) MakeTest.pch"
SOURCE=. MakeTest.rc
"$(INTDIR) MakeTest.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)

(13) 预编译文件

SOURCE=.StdAfx.cpp
!IF "$(CFG)" == "nMakeTest - Win32 Release"
CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR) MakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\" /FD /c
"$(INTDIR)StdAfx.obj" "$(INTDIR) MakeTest.pch" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
$(CPP_SWITCHES) $(SOURCE)
<<
!ELSEIF "$(CFG)" == "nMakeTest - Win32 Debug"
CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR) MakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\" /Fd"$(INTDIR)\" /FD /GZ /c
"$(INTDIR)StdAfx.obj" "$(INTDIR) MakeTest.pch" : $(SOURCE) "$(INTDIR)"
$(CPP) @<<
$(CPP_SWITCHES) $(SOURCE)
<<
!ENDIF

免责声明:文章转载自《windows下makefile命令详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ROS之服务make clean与make distclean的区别下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

go 学习 (一):环境配置

Go 下载地址:https://golang.google.cn/dl/ 1、右键我的电脑 --> 左上方 “高级系统设置” ---> 环境变量 --> 第二个菜单栏 “系统变量” --> 找到变量名为 “Path” --> 双击并点击新建,添加 go/bin 目录 --> 点击确定才会生效 2、新建文件夹作为源码的...

Linux Makefile analysis for plain usr

一、本文主旨   笔者写了一篇linux内核Makefile整体分析 ,测重于理论分析,对于实际应用不算对头,所以需要写一篇实用性较强的文章,为以后内核、驱动移植做好铺垫。 二、本文内容概要 1、编译哪些文件 2、怎样编译这些文件 3、怎样连接这些文件,它们的顺序如何 三、编译哪些文件   本文的实验源码是对“linux-2.6.30.4”进行移植后的运行...

4通用Makefile编写

a.c #include<stdio.h>#include "a.h" intmain() { printf("hello world "); printf("A= %d ",A); test_fun(); return 0; } a.h #define A 1 b.c #include <st...

makefile学习经验(三)编译生成动态库文件(方式一)

Lunix下生成动态库文件:          之前已经介绍了.o,.a,.so文件类型的含义,.so后缀的文件是动态库文件。         下面介绍在编译过程中链接到动态库文件的方法: 一.   源码文件: so_test.h: void test_a(); void test_b(); void test_c(); test_a.c: #includ...

[原]Windows下openssl的下载安装和使用

安装openssl有两种方式,第一种直接下载安装包,装上就可运行;第二种可以自己下载源码,自己编译。下面对两种方式均进行详细描述。 一、下载和安装openss 方法一:直接使用openssl安装包 Window 的openssl的安装包的下载地址为: http://slproweb.com/products/Win32OpenSSL.html 一般在安装...

Delphi与Windows 7下的用户账户控制(UAC)机制(加小盾牌),注册表没反应

WIN7, Vista提供的UAC机制,它的主要目的是防止对于操作系统本身的恶意修改。对于Delphi程序的影响,UAC主要在于以下几点:1、由于UAC机制,Delphi对于系统的操作可能无声的失败,而同样的程序,在2000/X下面可能运行正常。譬如注册表的改动。。。2、为了避免这样的情况,Delphi程序必须支持Vista UAC标注,也就是说,在UAC...