Windows批处理中SET对errorlevel的影响

今天折腾自己编译QT,在configure阶段遇到了一点麻烦,网上也没看到解决方法,所以纪录在此。

按文档说明,写了一长串命令之后确认运行:

configure.bat -static -release -debug -confirm-license -opensource -opengl desktop -platform win32-g++ -prefix "C:\Documents\dev\lib\qt-5-build\mingw-7.2.0-posix-static" -sql-sqlite -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype -make libs -nomake tools -nomake examples -nomake tests -skip qtwebview -skip qtwebengine -skip qtactiveqt -skip qtandroidextras -skip qtcanvas3d -skip qtcharts -skip qtfeedback -skip qtgamepad -skip qtlocation -skip qtquick1 -skip qtquickcontrols -skip qtquickcontrols2 -skip qtsensors -skip qtserialbus -skip qtserialport -skip qtspeech -skip qtwebchannel

然而,只出了一句提示说“正在运行qtbase下的configure”之后就没了,瞬间结束。本来应该bootstrap出来一个qmake.exeqtbase/bin目录是空的,echo %errorlevel%显示为1,显然是脚本出错了。

搜索半天后确认没有任何中文或者鸟语资料提到这个,于是在qtbase下的configure.bat的顶端打开了echo on,确定问题出在这里:

:wastoplevel
 
set SYNCQT=
set PLATFORM=
set MAKE=
call :doargs %ARGS%
if errorlevel 1 exit /b
goto doneargs

运行到if errorlevel 1 exit /b一句时,脚本发现errorlevel为1,就直接退出了。

添加很多echo %errorlevel%之后再次运行,发现,刚刚进入:wastoplevelerrorlevel是好着的,但是运行到call :doargs %ARGS%时,就变成坏的了。这让我很惊讶,看似人畜无害的set SYNCQT=也会出错?

再经过一番尝试,发现了SET XXX=命令的作用是:

  1. 如果XXX变量已经存在,则什么也不做,而不是我之前理解的把这个变量置为空!
  2. 如果XXX变量不存在,则将errorlevel置为1.

这么来看,这句话的作用实质上应该是检查变量XXX是否存在,不存在则报错。而Qt编译脚本中为啥放上了这一句但又不在文档中提及就不得而知了,也许是以前:doargs函数中有什么命令可以刷掉错误的errorlevel,但可以确认在5.9版本中是没有的。

知道原因后,解决就很简单了,首先读一下脚本确定那三个变量的意思,然后在执行configure之前先把他们设置一下:

SET SYNCQT=false
set PLATFORM=win32-g++
set MAKE=mingw32-make

再继续按官方文档搞就好了。

  • 最后更改: 2019/05/29 15:00