I have a batch file that checks if a previously compiled exe file exists. If not, it will recompile, otherwise it will check if any files have been modified since the creation of the exe file. If modified files are found, it will recompile. It then checks through the directory, keeping track of the names and timestamps for the file contents.
I am wondering how to do this, so that I don't have to manually list:
file[0]=
file[1]=
file[2]=
etc.
Now I already have a list in here that is able to be modified whenenever, and works, but its modified like:
set SOURCES=!SOURCES! "%%F"
and my timestamp list is like:
set LIST=!LIST! %FILE_TIMESTAMP_FORMAT%
I've already checked a lot of sources, and none of them are dynamic, or just dont work for me. Also does anyone know why the format wont be echo
ed.
@echo off
setlocal enabledelayedexpansion
cd /d "C:\Users\ealos\OneDrive\Desktop\C++ Project"
echo Current directory: %CD%
set SOURCES=
set FILES_CHANGED=false
set LIST=
rem Check if cppgame.exe exists and get its timestamp
if exist cppgame.exe (
for %%F in (cppgame.exe) do (
set EXE_TIMESTAMP=%%~tF
)
echo cppgame.exe last modified: !EXE_TIMESTAMP!
rem Convert cppgame.exe timestamp to comparable format
set EXE_TIMESTAMP_FORMAT=!EXE_TIMESTAMP:~6,4!!EXE_TIMESTAMP:~0,2!!EXE_TIMESTAMP:~3,2!!EXE_TIMESTAMP:~11,2!!EXE_TIMESTAMP:~14,2!
echo EXE Timestamp Format: !EXE_TIMESTAMP_FORMAT!
) else (
echo cppgame.exe does not exist or was just created.
set FILES_CHANGED=true
)
rem Loop through all .cpp files and check if any are newer than cppgame.exe
for %%F in (*.cpp) do (
echo -----------
rem Add the .cpp file to the SOURCES variable for compilation
set SOURCES=!SOURCES! "%%F"
rem Get the timestamp of the current .cpp file
set FILE_TIMESTAMP=%%~tF
rem Convert .cpp file timestamp to comparable format
set FILE_TIMESTAMP_FORMAT=!FILE_TIMESTAMP:~6,4!!FILE_TIMESTAMP:~0,2!!FILE_TIMESTAMP:~3,2!!FILE_TIMESTAMP:~11,2!!FILE_TIMESTAMP:~14,2!
echo Checking: %%F (Modified: !FILE_TIMESTAMP!)
echo File Timestamp Format: (!FILE_TIMESTAMP_FORMAT!)
rem Add the formatted timestamp to the LIST for comparison
set LIST=!LIST! "%FILE_TIMESTAMP_FORMAT%"
echo list: %LIST%
)
rem Now compare each timestamp in LIST with cppgame.exe's timestamp
echo %LIST%
for /f "tokens=1, delims==" %%a in (%LIST%) do (
echo Comparing: %%a with !EXE_TIMESTAMP_FORMAT!
if %%a GTR %EXE_TIMESTAMP_FORMAT% (
set FILES_CHANGED=true
echo File has changed, setting FILES_CHANGED=true
)
echo EXE Timestamp Format: !EXE_TIMESTAMP_FORMAT!
echo File Timestamp Format: %%a
)
rem If no files have changed, just run the existing executable
if "!FILES_CHANGED!"=="false" (
echo No files changed, running existing executable...
cppgame.exe
pause
exit /b
)
rem If no .cpp files are found, exit
if "%SOURCES%"=="" (
echo No .cpp files found in the directory!
pause
exit /b
)
rem Compile all .cpp files into a single executable (cppgame.exe)
echo Compiling...
g++ %SOURCES% -o cppgame.exe
rem Check if compilation was successful
if %ERRORLEVEL% NEQ 0 (
echo Compilation failed!
pause
exit /b
)
rem Run the compiled executable
echo Running cppgame...
cppgame.exe
rem Pause to keep the console open after execution
pause
I believe the following would suit your requirement:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following setting for the directory is a name
rem that I use for testing and deliberately includes spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.
SET "sourcedir=u:\your files"
SET "logfilename=%sourcedir%\q79528112.txt"
SET "filesrequired=*.cpp final.exe"
SET "abort="
CALL :existing
IF DEFINED abort GOTO cleanup
FC "%logfilename%" "%logfilename%.new" >NUL 2>nul
IF ERRORLEVEL 1 (
ECHO recompile game
CALL :existing
MOVE /y "%logfilename%.new" "%logfilename%" >NUL
)
ECHO run game
:cleanup
DEL "%logfilename%.new" 2>nul
GOTO :EOF
:: Set #?? to current datestamp of required files & record in %logfile%.new
:existing
:: remove variables starting #
FOR /F "delims==" %%e In ('set # 2^>Nul') DO SET "%%e="
PUSHD "%sourcedir%"
FOR %%e IN (%filesrequired%) DO (
IF EXIST "%%e" (SET "#%%e=%%~te") ELSE SET "abort=y"&ECHO %%e NOT found
)
popd
SET #>"%logfilename%.new"
GOTO :eof
The name of the logfile simply suits my testing setup.
The routine existing
sets #filename
to the datestamp of each file found on the filesrequired
list, sets abort
to y
if any are missing and writes the list of filenames/datestamps to logfile.new
.
Then check whether the new logfile is the same as the old. If not, or one of the files is missing then recompile, reset the #variables with the new versions and re-write the log file.
Then run the game and clean up any unwanted files.