2015-09-24 2 views
1

Я пишу командный файл, который проверяет политику заголовка (каждый заголовок должен включать/разрешать свои собственные зависимости), но, похоже, cl.exe возвращает успех даже хотя на самом деле провал ..Ошибка пакетного файла или cl.exe для компиляции result/exit

Script без комментариев:

@echo off 

set FNAME=temp 
set OBJFILE=%FNAME%.obj 
set SRCFILE=%FNAME%.cc 

for /f "delims=|" %%i in ('dir /b /s ..\include\*.h') do (
    (echo #include "%%i" & echo void test^(^){}) > %SRCFILE% 
    echo %%i 
    "%VCINSTALLDIR%\bin\cl.exe" /c /W4 %SRCFILE% > NUL 2>&1 

    if not ERRORLEVEL 0 goto failed 
) 
goto success 

:failed 
echo. 
echo Compile failed. 
goto fin 

:success 
echo. 
echo Success. 
goto fin 

:fin 
if exist %OBJFILE% del %OBJFILE% > NUL 
if exist %SRCFILE% del %SRCFILE% > NUL 

Я подозреваю, что вина лежит обнаружение Равно (я прочитал raymond chens article, а также другие SO сообщения о его предостережениях), но все попытки вариации также потерпели неудачу таким же образом, заставив меня думать cl.exe is lying. Я мог быть совершенно неправым, поэтому я собирался проверить с ProcMon, но, к сожалению, сейчас он рушится.

Является ли это просто тем, что я глуп?

В настоящее время я принуждая неудачу в заголовочном файле с помощью FakeType blah;, который cl.exe делает вывод, если перенаправить в файл:

...\include\fail.h(1) : error C2146: syntax error : missing ';' before identifier 'blah' 
...\include\fail.h(1) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
+1

Попробуйте 'if! ERRORLEVEL! neq 0 goto failed' с 'setlocal EnableDelayedExpansion', потому что' if not ERRORLEVEL 0 ...' означает: «Если уровень ошибок меньше 0». Внимательно прочитайте описание в 'if /?' – Aacini

+1

Попробуйте 'if ERRORLEVEL 1 goto failed', поскольку, вероятно, нет [Delayed Expansion] (http://ss64.com/nt/delayedexpansion.html). – JosefZ

+0

@ Аасини Это тот! Нюансы с 'if' ... вы можете выразить это как ответ, и я соглашусь, спасибо. – ZXcvbnM

ответ

3

программы обычно возвращают код ошибки через значение ERRORLEVEL больше нуля ; однако cl.exe может возвращать положительные или отрицательные значения ERRORLEVEL, когда есть ошибка, и значение нуля, если оно ОК. Обычная форма:

if errorlevel num ... 

верно, если Равно больше или равен, чем заданное число, так что

if not ERRORLEVEL 0 goto failed 

будет верно, когда Равно меньше нуля. Есть два способа, чтобы проверить, если Равен точно ноль:

if errorlevel 0 if not errorlevel 1 goto success 

что, если Равен больше или равно нулю и меньше 1. Возможно, наглядным является непосредственно сравнить значение Errorlevel:

if !errorlevel! equ 0 goto success 

Помните, что эта форма требует команды setlocal EnableDelayedExpansion.

+0

kudos для дополнительной информации, надеюсь, что это поможет другим в будущем. Я выбираю последнюю форму, поскольку она выглядит более синтаксически действительной;) – ZXcvbnM

+0

Но 'if! Errorlevel! equ 0 goto success' выпрыгивает из цикла 'for', возможно, прерывается. Следовательно, вам нужно использовать либо 'if! Errorlevel! neq 0 goto failed' или два последовательных '' '' '' '' '' '' '' '' '' '' '' '' '' 'если не ERRORLEVEL 0 goto failed 'и назад к спине', если ERRORLEVEL 1 goto failed' – JosefZ

+0

Правильно - я имел в виду использование метода в отличие от фактическое содержание :) – ZXcvbnM

Смежные вопросы