zoukankan      html  css  js  c++  java
  • windows下makefile命令详解

    转自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为例):

         

    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++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

  • 相关阅读:
    第二阶段冲刺记录八
    用户体验评价
    找水王
    第二阶段冲刺记录七
    第二阶段冲刺记录六
    第14周学习进度
    第二阶段冲刺记录五
    第二阶段冲刺记录四
    第一阶段意见评论
    IP协议号大全
  • 原文地址:https://www.cnblogs.com/wangshaowei/p/8986161.html
Copyright © 2011-2022 走看看