none
windows下编写makefile文件的一个疑问 RRS feed

  • 问题

  • 我理解windows下makefile文件集成了windows的批处理命令。我编写了一个windows下makefile文件(运行环境是win7 x64, vs 2015),具体内容如下:

    !include <C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\Win32.Mak>
    
    #设置编译标记,初始化为FALSE
    CFGSET     =  FALSE
    
    RUN_CLEAN  =  FALSE
    
    !IF "$(option)"== "1"
    
    CFGSET     =  TRUE
    
    Configuration = Release
    Platform = x64
    #定义release版本的预处理器
    CC_OPTION   = -D_WIN64 -D_NDEBUG -D_WINDOWS
    
    TARGET_MACHINE = X64
    
    !ELSE IF "$(option)"== "2"
    
    CFGSET   =  TRUE
    
    Configuration = Debug
    Platform = x64
    #定义debug版本的预处理器
    CC_OPTION    = -D_WIN64 -D_DEBUG -D_WINDOWS
    
    TARGET_MACHINE = X64
    
    !ELSE IF "$(option)"== "3"
    
    CFGSET   =  TRUE
    
    Configuration = Release
    Platform = Win32
    CC_OPTION   = -D_WIN32 -D_NDEBUG -D_WINDOWS
    
    TARGET_MACHINE = X86
    
    !ELSE IF "$(option)"== "4"
    
    CFGSET   =  TRUE
    
    Configuration = Debug
    Platform = Win32
    CC_OPTION   = -D_WIN32 -D_DEBUG -D_WINDOWS
    
    TARGET_MACHINE = X86
    
    !ELSE IF "$(option)"== "5"
    
    CFGSET   =  TRUE
    RUN_CLEAN  =  TRUE
    
    !ENDIF
     
    CC         = $(CC_OPTION)
     
    # 提示用法
    #
    !IF "$(CFGSET)"== "FALSE"
    !MESSAGE Usage: nmake /f makefile.vc option=1 or 2 or 3 or 4 or 5   
    !MESSAGE
    !MESSAGE where <config> is one of:
    !MESSAGE -  option=1                -  build  x64 release version
    !MESSAGE -  option=2                - build  x64 debug version
    !MESSAGE -  option=3                - build  x86 release version
    !MESSAGE -  option=4                - build  x86 debug version
    !MESSAGE -  option=5                - clear output file
    !MESSAGE
    !MESSAGE
    !ERROR please choose a valid configuration instead"
    !ENDIF
     
    !IF "$(RUN_CLEAN)"== "TRUE"
    
    if exist "../../Intdir/Debug_x64/TestLog" (del "..\..\Intdir\Debug_x64\TestLog\*.obj") else echo Debug_x64不存在
    if exist "../../Intdir/Debug_Win32/TestLog" (del "..\..\Intdir\Debug_Win32\TestLog\*.obj") else echo Debug_Win32不存在
    
    !ELSE
    
    OUTDIR =..\..\OutDir\$(Configuration)_$(Platform)
    INDIR =..\..\Intdir\$(Configuration)_$(Platform)\TestLog
    
    #这里设置输出
    all: $(INDIR) $(OUTDIR) $(OUTDIR)\TestLog.exe
    
    #假如不存在$(INDIR)文件夹,就创建它
    $(INDIR) :
         if not exist "$(INDIR)" mkdir $(INDIR)
    
    #假如不存在$(OUTDIR)文件夹,就创建它
    $(OUTDIR) :
        if not exist "$(OUTDIR)" mkdir $(OUTDIR)
    
    # compile
    $(INDIR)\FileAPI.obj:..\TestFileAPI\FileAPI.cpp
        cl -c  $(CC) /Fo"$(INDIR)\\" /Fd"$(INDIR)\\" ..\TestFileAPI\FileAPI.cpp
    
    $(INDIR)\GetSysError.obj: GetSysError.cpp 
        cl -c  $(CC) /Fo"$(INDIR)\\" /Fd"$(INDIR)\\" GetSysError.cpp
    
    $(INDIR)\StringAPI.obj: StringAPI.cpp
        cl -c  $(CC) /Fo"$(INDIR)\\" /Fd"$(INDIR)\\" StringAPI.cpp
    
    $(INDIR)\SysLog.obj: SysLog.cpp 
        cl -c  $(CC) /Fo"$(INDIR)\\" /Fd"$(INDIR)\\" SysLog.cpp
    
    $(INDIR)\TestLog.obj: TestLog.cpp FileAPI.obj GetSysError.obj StringAPI.obj SysLog.obj
        cl -c  $(CC) /Fo"$(INDIR)\\" /Fd"$(INDIR)\\" TestLog.cpp
    
    # link
    $(OUTDIR)\TestLog.exe: $(INDIR)\TestLog.obj
        link /machine:$(TARGET_MACHINE) /INCREMENTAL:YES /NOLOGO /subsystem:CONSOLE /out:$(OUTDIR)\TestLog.exe $(INDIR)\TestLog.obj $(INDIR)\FileAPI.obj $(INDIR)\GetSysError.obj $(INDIR)\StringAPI.obj $(INDIR)\SysLog.obj kernel32.lib user32.lib
    
    !ENDIF   

         其中在执行命令:nmake /f makefile.vc option=5,但是出错:fatal error U1034: 语法错误: 缺少分隔符,如下图:

    可以看出这是在78行 if exist "../../Intdir/Debug_Win32/TestLog" (del "..\..\Intdir\Debug_Win32\TestLog\*.obj") else echo Debug_Win32不存在  这句出错了。

          然后我写了一个简单的批处理文件来验证:

    @echo off
    
    if exist "../../Intdir/Debug_x64/TestLog" (del "..\..\Intdir\Debug_x64\TestLog\*.obj") else echo Debug_x64不存在
    if exist "../../Intdir/Debug_Win32/TestLog" (del "..\..\Intdir\Debug_Win32\TestLog\*.obj") else echo Debug_Win32不存在

    这个批处理文件却是能够正确运行的。现在我搞不懂makefile文件错在哪里了。

    前无古人,后无来者

    2019年10月10日 9:24

全部回复

  • 需要进行如下修改:

    !IF "$(RUN_CLEAN)" == "TRUE"
    CLEAN:
    	if exist "..\..\Intdir\Debug_x64\TestLog" (del "..\..\Intdir\Debug_x64\TestLog\*.obj") else echo Debug_x64 not exist
    	if exist "..\..\Intdir\Debug_Win32\TestLog" (del "..\..\Intdir\Debug_Win32\TestLog\*.obj") else echo Debug_Win32 not exist
    	if exist "..\..\Intdir\Release_x64\TestLog" (del "..\..\Intdir\Release_x64\TestLog\*.obj") else echo Release_x64 not exist
    	if exist "..\..\Intdir\Release_Win32\TestLog" (del "..\..\Intdir\Release_Win32\TestLog\*.obj") else echo Release_Win32 not exist
    
    !ELSE

    关键点有三点:

    1.必须增加一个块名,比如这里添加了CLEAN:

    2.CLEAN:和if exist之间不能有空行。

    3.if exist之前至少得插入一个tab。

    前无古人,后无来者

    2019年10月11日 4:10
  • 你好,

    感谢你在这里发帖。

    我们感谢你与我们分享了你的解决方案,同时我们也建议你将其标记为答案,通过标记答案,会帮助其他社区成员更快地找到解决方案。

    Best Regards,

    Suarez Zhou

    2019年10月11日 5:13