Folder operation in .bat is unstable? - windows

I write a .bat to automate generating and compiling a cmake project. The batch file will
optional rmdir build
mkdir build if not exist
cd build
cmake .. generate a nmake project from upper folder
nmake compile project
the source:
#ECHO OFF
set "OpenCV_LIB=C:\Program Files (x86)\OpenCV2.1"
echo !! OpenCV Library: [ %OpenCV_LIB% ]
IF NOT EXIST "%OpenCV_LIB%" (
echo Can't find OpenCV Library, please change OpenCV_LIB setting
GOTO END
)
if %PROCESSOR_ARCHITECTURE%==x86 set BUILD_ARCH=x86
if %PROCESSOR_ARCHITECTURE%==AMD64 set BUILD_ARCH=x86_amd64
if %PROCESSOR_ARCHITECTURE%==IA64 set BUILD_ARCH=x86_IPF
echo !! Target architecture [ %BUILD_ARCH% ]
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" %BUILD_ARCH%
cd "sikuli-script"
set /p answer=Do you want to make clean first? (Y/N):
if %answer% == Y ( IF EXIST build rmdir /s /q build )
if %answer% == y ( IF EXIST build rmdir /s /q build )
IF NOT EXIST build mkdir build
cd build
IF NOT EXIST CMakeCache.txt ( cmake -G "NMake Makefiles" -D CMAKE_BUILD_TYPE=Release -D "OpenCV_DIR=%OpenCV_LIB%" .. )
nmake
:END
pause
After i run this .bat over and over, i notice that cd build failed sometimes, so i change my code to test it:
#ECHO ON
set /p answer=Do you want to make clean first? (Y/N):
if %answer% == Y ( IF EXIST build rmdir /s /q build )
if %answer% == y ( IF EXIST build rmdir /s /q build )
:DO_MKDIR_CD
IF NOT EXIST build mkdir build
cd build
if errorlevel 1 (
pause
GOTO DO_MKDIR_CD
)
It comes out the error happens every time choose to clean up build, even the build is at small size (e.g. after interrupted compiling, size 3.08 MB, 183 files, 67 dirs).
!! OpenCV Library: [ C:\Program Files (x86)\OpenCV2.1 ]
!! Target architecture [ x86_amd64 ]
Setting environment for using Microsoft Visual Studio 2010 x64 cross tools.
D:\repo\sikuli>cd "sikuli-script"
D:\repo\sikuli\sikuli-script>set /p answer=Do you want to make clean first? (Y/N):
Do you want to make clean first? (Y/N):y
D:\repo\sikuli\sikuli-script>if y == Y (IF EXIST build rmdir /s /q build )
D:\repo\sikuli\sikuli-script>if y == y (IF EXIST build rmdir /s /q build )
D:\repo\sikuli\sikuli-script>IF NOT EXIST build mkdir build
D:\repo\sikuli\sikuli-script>cd build
Access is denied.
D:\repo\sikuli\sikuli-script>if errorlevel 1 (
pause
GOTO DO_MKDIR_CD
)
Press any key to continue . . .
So every time after remove and recreate build, the cd build fails, then cmake start messing up my source tree.
The error check and loop trying could fix this problem, but why is the file system not stable? or am i writing it in a wrong way?

That build directory check:
IF NOT EXIST build mkdir build
Will create the directory if both directory and file named "build" are not exist.
One way to check a directoy existence is:
if exist build\nul echo directory exist
If you want to make sure a directory exist use:
if not exist build\nul mkdir build
or better:
if not exist build\nul (
mkdir build
if not exist build\nul (
echo mkdir failed
goto :eof
)
)

Related

How do I save cmd output from msbuild to a log file in a for loop?

I have several Visual Studio 2015 solution files that I would like to build using a command line. I would like the output stored in a single file
Here is the contents of a batch file that builds the solutions.
echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
set _SCRIPT_DRIVE=%~d0
echo DRIVE %_SCRIPT_DRIVE%
set baseDir=%_SCRIPT_DRIVE%\Source\Service\4.0\Branches\ARES
echo baseDir = %baseDir%
set buildLog=%baseDir%\Build.log
rem these are the directory names / solution name of the projects I want to build
rem you can build 'n' solutions and use your own instead of me giving you the solution and code
set thirdParty=Cert,ManagedHooks,NLog,Newtonsoft.Json,RabbitMQ,MDTE
echo.
echo building %thirdParty%
echo.
for %%p in (%thirdParty%) do (
echo.
echo building %%p
cd %%p
set thirdPartySolutionFile=%%p%.sln
echo solution file : %thirdPartySolutionFile%
MSBuild %thirdPartySolutionFile% /t:Rebuild /m /p:Configuration=Debug > %buildLog%
cd ..
)
I only get the last project build information stored in the log file
>> is the answer
https://www.tutorialspoint.com/batch_script/batch_script_appending_files.htm
> overwrites the %buildLog% file.
>> will append the input to this file
so the line where you call the build tool and send the output to the file shoul d be changed to have the >> in it instead of >
MSBuild %thirdPartySolutionFile% /t:Rebuild /m /p:Configuration=Debug >> %buildLog%

Unable to build vim on windows with MinGW

I tried building vim and gvim with MinGW according to this instruction. For convenience I'm posting them here
#echo off
REM Run this batch file from any directory to build gvim.exe and vim.exe.
REM But first edit the paths and Python version number.
REM --- Specify Vim /src folder ---
set VIMSRC=C:\Downloads\vim\src
REM --- Add MinGW /bin directory to PATH ---
PATH = C:\MinGW\bin;%PATH%
REM --- Also make sure that PYTHON, PYTHON_VER below are correct. ---
REM get location of this batch file
set WORKDIR=%~dp0
set LOGFILE=%WORKDIR%log.txt
echo Work directory: %WORKDIR%
echo Vim source directory: %VIMSRC%
REM change to Vim /src folder
cd /d %VIMSRC%
REM --- Build GUI version (gvim.exe) ---
echo Building gvim.exe ...
REM The following command will compile with both Python 2.7 and Python 3.3
mingw32-make.exe -f Make_ming.mak PYTHON="C:/Python27" PYTHON_VER=27 DYNAMIC_PYTHON=yes PYTHON3="C:/Python35" PYTHON3_VER=35 DYNAMIC_PYTHON3=yes FEATURES=HUGE GUI=yes gvim.exe > "%LOGFILE%"
REM --- Build console version (vim.exe) ---
echo Building vim.exe ...
REM The following command will compile with both Python 2.7 and Python 3.3
mingw32-make.exe -f Make_ming.mak PYTHON="C:/Python27" PYTHON_VER=27 DYNAMIC_PYTHON=yes PYTHON3="C:/Python35" PYTHON3_VER=35 DYNAMIC_PYTHON3=yes FEATURES=HUGE GUI=no vim.exe >> "%LOGFILE%"
echo Moving files ...
move gvim.exe "%WORKDIR%"
move vim.exe "%WORKDIR%"
echo Cleaning Vim source directory ...
REM NOTE: "mingw32-make.exe -f Make_ming.mak clean" does not finish the job
IF NOT %CD%==%VIMSRC% GOTO THEEND
IF NOT EXIST vim.h GOTO THEEND
IF EXIST pathdef.c DEL pathdef.c
IF EXIST obj\NUL RMDIR /S /Q obj
IF EXIST obji386\NUL RMDIR /S /Q obji386
IF EXIST gobj\NUL RMDIR /S /Q gobj
IF EXIST gobji386\NUL RMDIR /S /Q gobji386
IF EXIST gvim.exe DEL gvim.exe
IF EXIST vim.exe DEL vim.exe
:THEEND
pause
I'm getting the following error during a build process:
Building gvim.exe ...
diff.c: In function 'ex_diffpatch':
diff.c:891:12: error: storage size of 'st' isn't known
stat_T st;
^
diff.c:891:12: warning: unused variable 'st' [-Wunused-variable]
mingw32-make.exe: *** [gobjx86-64/diff.o] Error 1
Building vim.exe ...
diff.c: In function 'ex_diffpatch':
diff.c:891:12: error: storage size of 'st' isn't known
stat_T st;
^
diff.c:891:12: warning: unused variable 'st' [-Wunused-variable]
mingw32-make.exe: *** [objx86-64/diff.o] Error 1
Does anyone know what could be the problem?
I figured out what was the problem. I was using a 32 bit MinGW instead of the one for 64 bit system. In other words I needed to download MinGW-w64 from https://mingw-w64.org/doku.php instead of downloading MinGW from http://www.mingw.org/.
I don't know what this problem is; but if I were you I would follow the instructions by Antoine Mechelynck, which are very detailed. I've used his guide for building at Unix/Linux guide and they are very good.
You could consider downloading the binary from vim.org if you still have problems to build it. There is also a portable version (from PortableApps), which doesn't requires privileges to install and even run from USB stick.

In Visual Studio 2013 copy files to the release directory only

I have some files in my project that are used for unit testing, and than files that will be used in the actual release.
Currently have 'Copy to output directory' copy always turned on.
Is there a more direct way to send only certain files to the 'Release' directory and others to the 'Debug' directory when building?
I ended using the command line build events property in the MAIN/Solution project.
yourproject > properties > build events
Pre build event command line
First i cleaned out the directory
rd /s /q "$(TargetDir)Configs"
Post-build event command line
Next on Debug, copy all.
And on Release, del everyting that was for testing.
if "$(ConfigurationName)"=="Debug" (
xcopy "$(ProjectDir)Configs\*.*" "$(TargetDir)Configs\" /y
del "$(TargetDir)Configs\_notes.*"
)
if "$(ConfigurationName)"=="Release" (
xcopy "$(ProjectDir)Configs\*.*" "$(TargetDir)Configs\" /y
del "$(TargetDir)Configs\test*.*"
del "$(TargetDir)Configs\_notes.*"
)
IN the test Project, used the same PRE command.
Had to change the POST command a little.
if "$(ConfigurationName)"=="Debug" (
xcopy "$(SolutionDir)$(SolutionName)\Configs\*.*" "$(TargetDir)Configs\" /y
del "$(TargetDir)Configs\_notes.*"
)
if "$(ConfigurationName)"=="Release" (
xcopy "$(SolutionDir)$(SolutionName)\Configs\*.*" "$(TargetDir)Configs\" /y
del "$(TargetDir)Configs\test*.*"
del "$(TargetDir)Configs\_notes.*"
)
I think this could be slimmed down, but its working.

xcopy in Windows x64 : File not found

This script to copy All file and folder in %programfiles% or %programfiles(x86) to destination folder. if my windows architecture x86, copy %programfiles%, copying file/folder successful, but not if my windows architecture x64.
Script
#echo Off
set Arch=x64
if "%PROCESSOR_ARCHITECTURE%" == "x86" (
if not defined PROCESSOR_ARCHITEW6432 set Arch=x86
)
echo Arsitektur Prosesor Windows Anda %Arch%
set /P drive=Folder backup akan disimpan di drive apa : %=%
if %Arch% == "x64" (
if not exist "%drive%:\BACKUP_ESPT\C" mkdir "%drive%:\BACKUP_ESPT\C"
if not exist "%drive%:\BACKUP_ESPT\VIRTUALSTORE" mkdir "%drive%:\BACKUP_ESPT\VIRTUALSTORE"
xcopy /Y /S "%ProgramFiles(x86)%\DJP\*.*" "%drive%:\BACKUP_ESPT\C"
xcopy /Y /S "%localappdata%\VirtualStore\Program Files (x86)\DJP\*.*" "%drive%:\BACKUP_ESPT\VIRTUALSTORE"
) else (
if not exist "%drive%:\BACKUP_ESPT\C" mkdir "%drive%:\BACKUP_ESPT\C"
if not exist "%drive%:\BACKUP_ESPT\VIRTUALSTORE" mkdir "%drive%:\BACKUP_ESPT\VIRTUALSTORE"
xcopy /y /S "%ProgramFiles%\DJP\*.*" "%drive%:\BACKUP_ESPT\C"
xcopy /y /S "%localappdata%\VirtualStore\Program Files\DJP\*.*" "%drive%:\BACKUP_ESPT\VIRTUALSTORE"
)
ECHO Proses Backup e-SPT selesai
pause
Result
Arsitektur Prosesor Windows Anda x64
Folder backup akan disimpan di drive apa : D
File not found - *.*
0 File(s) copied
File not found - *.*
0 File(s) copied
Proses Backup e-SPT selesai
Press any key to continue . . .
what's wrong? correct me please. thanks
I am looking at your script, and correct me if I am wrong, but when the processor architecture is x64, then you're accessing the x86 folders (as in your case). Is that what you want?
By the way: you are using the /s option for xcopy. That is the option to copy entire directories. You don't need the *.* postfix then: just specify the directory and it'll copy it entirely.
if %Arch% == "x64" (
should be
if "%Arch%"=="x64" (
A string-match is absolutely literal; x64 and "x64" are not the same thing, so the else branch would be taken and the targets don't exist.

Problems working with different drive units in a batch file

This is my first batch file, and also my first time with batch language (I usually use UNIX and don't know a lot about Windows commands).
I'm creating a batch file called install.bat which does all the work to install a Java application from source files. Here a snapshot of the install section:
#ECHO off
SET INSTALL_DIR=%1\
SET SRC_DIR=sources\
SET LIB_DIR=lib\
SET IMG_DIR=img\
SET BIN_DIR=bin\
SET INIT_DIR=%CD%
SET MAIN_CLASS=%SRC_DIR%\main\Main.java
SET CLASS_PATH=%LIB_DIR%log4j.jar;%LIB_DIR%jdom.jar;
SET JAR_NOM=myApp.jar
SET JAR_MF=MANIFEST.MF
:BEGIN
CLS
ECHO Checking directory...
IF EXIST %INSTALL_DIR% (
GOTO Ask_Overwrite
) ELSE (
GOTO Install
)
:Ask_overwrite
SET OVERW=Y
SET /P OVERW="The program is already installed. Overwrite? ([Y]/N): "
IF %OVERW%==N GOTO Cancel
IF %OVERW%==n GOTO Cancel
IF %OVERW%==Y (
RD /S /Q %INSTALL_DIR% <--- Here was the error
GOTO Install
)
IF %OVERW%==y (
RD /S /Q %INSTALL_DIR% <--- Here was the error
GOTO Install
)
GOTO Ask_overwrite
:Install
MD %INSTALL_DIR%
XCOPY . %INSTALL_DIR% /E
CD /D %INSTALL_DIR%
MD %BIN_DIR%
ECHO Compiling...
javac -cp %CLASS_PATH% -sourcepath %SRC_DIR% %MAIN_CLASS% -d %BIN_DIR%
ECHO Creating JAR file...
jar cfm %JAR_NOM% %JAR_MF% -C %BIN_DIR% .
ECHO Succes! The application has been installed in %INSTALL_DIR%
GOTO CleanUp
:Abort
ECHO Abort! The application has not been installed.
GOTO CleanUp
:Cancel
ECHO Canceled by user. The application has not been installed.
GOTO END
:Cleanup
REM Code for clean up
GOTO END
:END
CD /D %INIT_DIR%
PAUSE
NOTE: The javac and jar commands are correct, at least work in my machine.
Well, the script works correctly when I test it with the INSTALL_DIR belonging to the same drive where I execute it, but if I use a target directory out of the drive where I'm executing, I have problems.
Executions without problems (called in a cmd.exe session):
C:\Users\TC\testInstall> install.bat .\..\installTarget
C:\Users\TC\testInstall> install.bat C:\Users\TC\installTarget
Execution with problems (called in a cmd.exe session):
C:\Users\TC\testInstall> install.bat D:\Documents\installTarget
The problems happen when I try to copy files specially, but also making and removing directories.
I hope someone can tell to me which options I must use in order to fix the problems.
Regards!
Well, I have two mistakes that I fixed and then the script work correctly.
The first was that I didn't use the /d option in cd command in order to change also the drive unit. It means, C:Users\TC> cd D:\Documents is wrong, the correct command is the following: C:Users\TC> cd /d D:\Documents as well as the MS-DOS manual page indicates.
The second error, it wasn't actually an error, I put rm -rf %INSTALL_DIR% (like in Linux) instead of the correct Windows command rd /s/q %INSTALL_DIR%
Now all the problems have been fixed and the script works properly :)
It has to do with batch files not accessing other drives than the C:\ drive by default. Even if you open up your command line, you shouldn't be able to CD D:\. Try this (not sure if this will work as I have never tried it)
PUSHD D:\
C:\Users\TC\testInstall> install.bat D:\Documents\installTarget
Or else, use PUSHD D:\ then move the install file to D:\ temporarily and install. Only solutions I can think of.

Resources