Check if a file exists at compile time

From NSIS Wiki
Jump to navigationJump to search
Author: ChrisMorgan (talk, contrib)


Description

This script provides a macro for conditional compilation based on whether or not a file exists. NfUtils' ${nfu.!IncludeTextIfExist} can also be used (in a roundabout manner), though this is simpler. It works like !ifmacrodef but on the condition of a file's, rather than a macro's, existence.

The Script

; See http://nsis.sourceforge.net/Check_if_a_file_exists_at_compile_time for documentation
!macro !defineifexist _VAR_NAME _FILE_NAME
	!tempfile _TEMPFILE
	!ifdef NSIS_WIN32_MAKENSIS
		; Windows - cmd.exe
		!system 'if exist "${_FILE_NAME}" echo !define ${_VAR_NAME} > "${_TEMPFILE}"'
	!else
		; Posix - sh
		!system 'if [ -e "${_FILE_NAME}" ]; then echo "!define ${_VAR_NAME}" > "${_TEMPFILE}"; fi'
	!endif
	!include '${_TEMPFILE}'
	!delfile '${_TEMPFILE}'
	!undef _TEMPFILE
!macroend
!define !defineifexist "!insertmacro !defineifexist"

Usage

${!defineifexist} var_name file_name

var_name is defined if the file exists.

file_name is the file to check the existence of.

This is different from most scripts in that it is a compile-time macro, and not runtime. For runtime usage, see the command IfFileExists or the LogicLib variant ${If} ${FileExists}.

Examples

Identify the Bazaar repository revision number if it's there (a straight !searchparse throws an error if the file doesn't exist... even with /noerrors which serves a different purpose).

${!defineifexist} LAST_REV_EXISTS ..\..\.bzr\branch\last-revision
!ifdef LAST_REV_EXISTS
	!searchparse /noerrors /file ..\..\.bzr\branch\last-revision "" BZR_REVISION " "
	!echo "Building development snapshot from r${BZR_REVISION}"
	!undef LAST_REV_EXISTS
!endif

(${VersionCompleteXXXN} is useful in conjunction with this sort of example to generate a revision number in the version info (e.g. 1.2.0.8765).)

The File command has a /nonfatal argument, meaning it will just not be included if it's not there - but what if you want a whole section to vanish if a file or folder isn't there at compile time? Here's a solution.

${!defineifexist} SHARE_EXAMPLES_DIR_EXISTS share\examples
!ifdef SHARE_EXAMPLES_DIR_EXISTS
	Section "Examples" SecExamples
		SetOutPath $INSTDIR\share\examples
		File /a share\examples\readme.txt
		File /a share\examples\*.foo
	SectionEnd
	!undef SHARE_EXAMPLES_DIR_EXISTS
!endif