转自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 files\Microsoft Visual Studio\VC98\Bin】

vs2008:【D:\program files\Microsoft Visual Studio 9.0\VC\bin】

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

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

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

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

/l 0x804  // 默认语言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为project database文件,用于存工程的数据库信息)

/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++\VC98\PlatformSDK\Include"

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

/dll  // 输出dll文件

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

/libpath:"..\PublicSDK\lib" // 指定外部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)\nMakeTest.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)\nMakeTest.exe"
CLEAN :
  -@erase "$(INTDIR)\nMakeTest.obj"
  -@erase "$(INTDIR)\nMakeTest.pch"
  -@erase "$(INTDIR)\nMakeTest.res"
  -@erase "$(INTDIR)\nMakeTestDlg.obj"
  -@erase "$(INTDIR)\StdAfx.obj"
  -@erase "$(INTDIR)\vc60.idb"
  -@erase "$(OUTDIR)\nMakeTest.exe"
  -@erase "$(OUTDIR)\nMakeTest.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)\nMakeTest.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)\nMakeTest.pdb" /map:"$(INTDIR)\nMakeTest.map" /machine:I386 /out:"$(OUTDIR)\nMakeTest.exe" 
LINK32_OBJS= \
  "$(INTDIR)\nMakeTest.obj" \
  "$(INTDIR)\nMakeTestDlg.obj" \
  "$(INTDIR)\StdAfx.obj" \
  "$(INTDIR)\nMakeTest.res"
"$(OUTDIR)\nMakeTest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
   $(LINK32) @<<
  $(LINK32_FLAGS) $(LINK32_OBJS)
<<

(12) 文件依赖

SOURCE=.\nMakeTest.cpp
"$(INTDIR)\nMakeTest.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\nMakeTest.pch"
SOURCE=.\nMakeTest.rc
"$(INTDIR)\nMakeTest.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)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\nMakeTest.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)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\nMakeTest.pch" : $(SOURCE) "$(INTDIR)"
  $(CPP) @<<
 $(CPP_SWITCHES) $(SOURCE)
<<
!ENDIF

windows下makefile命令详解的更多相关文章

  1. windows下route命令详解(转载)

    1.具体功能        该命令用于在本地IP路由表中显示和修改条目.使用不带参数的ROUTE可以显示帮助.            2.语法详解        route [-f] [-p] [co ...

  2. Linux和Windows下ping命令详解(转:http://linux.chinaitlab.com/command/829332.html)

    一.Linux下的ping参数 用途 发送一个回送信号请求给网络主机. 语法 ping [ -d] [ -D ] [ -n ] [ -q ] [ -r] [ -v] [ \ -R ] [ -a add ...

  3. Linux和Windows下ping命令详解

    转:http://linux.chinaitlab.com/command/829332.html 一.Linux下的ping参数 用途 发送一个回送信号请求给网络主机. 语法 ping [ -d] ...

  4. Linux下top命令详解

    Linux下top命令详解 top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器.top是一个动态显示过程,即可以通过用户按键来不断刷 ...

  5. Windows下caffe安装详解(仅CPU)

    本文大多转载自 http://blog.csdn.net/guoyk1990/article/details/52909864,加入部分自己实战心得. 1.环境:windows 7\VS2013 2. ...

  6. Linux下ps命令详解 Linux下ps命令的详细使用方法

    http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...

  7. Linux下rar命令详解

    Linux下rar命令详解 用法: rar <命令> -<选项1> ….-<选项N> < 操作文档> <文件…> <@文件列表…> ...

  8. linux下tar命令详解

     linux下tar命令详解    tar是Linux环境下最常用的备份工具之一.tar(tap archive)原意为操作磁带文件,但基于Linux的文件操作机制,同样也可适用于普通的磁盘文件.ta ...

  9. [r]Ubuntu Linux系统下apt-get命令详解

    Ubuntu Linux系统下apt-get命令详解(via|via) 常用的APT命令参数: apt-cache search package 搜索包 apt-cache show package ...

随机推荐

  1. bugzilla配置邮箱发送邮件问题

    2018-09-25 1.bugzilla注册账号,邮件无法发送 需要登录管理账号,配置邮箱服务 2.Can't locate object method "quit" via p ...

  2. 使用electron构建跨平台Node.js桌面应用经验分享

    by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=6154 本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随 ...

  3. CenctOS6 and CenctOS7 多种姿势解决忘记密码

    -----linux---- 忘记密码啦!!! 忘记密码教程!!! 教你们忘记密码(我原来密码就是123456,忘记是不可能的!假装忘记的样子 0.0) 现在我们忘记密码了!对忘记密码了.我忘记密码了 ...

  4. (转)shell脚本之文件测试操作符及整数比较符

    shell脚本之文件测试操作符及整数比较符 原文:http://www.cnblogs.com/Steward-Xu/p/6722592.html 一.文件测试操作符: 在书写测试表达式是,可以使用一 ...

  5. 一个优秀的app应该考虑的问题

    带着团队做了3个app,需求是客户决定的,甚至连进度都不是项目经理可以控制的(譬如说一个app要在6周内,3个人完成).现在的状态是基本上没有用户量,当然原因是多方面的,下面说一说我认为app设计的原 ...

  6. ArcGIS发布地图服务后直接调用查看方法

    做项目配置了一个地理底图,不知道有没有问题,如何给到客户查看并确认呢? 首先在ArcGIS上发布该地图: 打开地图后->文件->共享为->服务…… 发布成功后,得到可以访问的地图服务 ...

  7. PLC总结

    PLC编程总结 PLC控制部分总体有三大部分组成,PLC硬件,组态以及梯形图程序.PLC硬件应与组态一一对应,不容有任何偏差:而梯形图与操作的组态的IO口也应该一一对应.因此,整个系统达到了由梯形图程 ...

  8. 06.do-while循环的练习

    练习1: namespace _09.do_while循环练习01 { class Program { static void Main(string[] args) { //计算1到100之间的整数 ...

  9. 阻止冒泡 table表格取消选中最后一列

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. Linux 连接 Xshell 及网络配置

    一.准备工具 在WMware上已经装有Linux系统:WMware安装CentOS7文章. xshell连接工具: 二.修改相关配置 切换到root用户下: 配置主机名(可选): #方法一:替换原主机 ...