Given the bin\
directory inside the Delphi project contains the files Cert.pem
and Key.pem
, the below Delphi post-build event only copies both files if C:\Binaries\Cert.pem
does not exist:
if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR))
if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR))
As soon as C:\Binaries\Cert.pem
exists, the Key.pem
file is never copied.
How can I solve this in the post-build event?
Edit: unlike my 2014 post, this is indeed possible using parentheses. See my answer below.
The problem with Delphi post-build events is that they are not batch files.
It means that statements that look like lines are being concatenated by the Delphi IDE into one big &
ampersand separated statement. This ensures the commands are executed in sequence, as per Command Redirection, Pipes - Windows CMD - SS64.com:
commandA & commandB Run commandA and then run commandB
So this is the actual statement that gets executed:
if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR))&if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR))
The problem here is that now the second if
is seen as a continuation of the "then" part of the first if
statement: the second if
never executes when the $(OUTPUTDIR)Cert.pem
exists.
What helps is a little known feature that you can wrap each command inside parentheses. Normally this is to allow one command to span multiple lines (especially for if
, and for
..do
loops), but it also works on one line.
Wrapping each line having an if
statement inside parentheses ensures they become standalone statements not affecting the other lines, even if they are being concatenated with &
ampersand separators.
In the dialog it looks like this:
(if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR)))
(if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR)))
That way, the IDE translates it into one statement:
(if not exist $(OUTPUTDIR)Cert.pem (copy bin\Cert.pem $(OUTPUTDIR)))&(if not exist $(OUTPUTDIR)Key.pem (copy bin\Key.pem $(OUTPUTDIR)))
Now it works as intended:
$(OUTPUTDIR)Cert.pem
exists but $(OUTPUTDIR)Key.pem
does not, only $(OUTPUTDIR)Cert.pem
is copied$(OUTPUTDIR)Cert.pem
does exists but $(OUTPUTDIR)Key.pem
does, only $(OUTPUTDIR)Key.pem
is copiedI did not know this "trick" when writing my 2014 post Delphi prebuild/prelink/postbuild events, so I need to write an update for it.
Searching for batch file parentheses site:microsoft.com -site:social.technet.microsoft.com -site:answers.microsoft.com did not reveal it in the official documentation, but I am not surprised as it grew hysterically, instead of being designed. Or like the Old New Thing attributes h2g2:
Much like the universe, if anyone ever does fully come to understand Batch then the language will instantly be replaced by an infinitely weirder and more complex version of itself. This has obviously happened at least once before ;)
The best documentation I could find was at Parenthesis/Brackets - Windows CMD - SS64.com:
Parenthesis can be used to split commands across multiple lines. This can make code more readable. Variables will be evaluated for the code block just as if the command was a single line.
(command) ( command command )
Things that break inside parenthesis The CMD shell does not use any great intelligence when evaluating parenthesis, so for example the command below will fail:
IF EXIST MyFile.txt (ECHO Some(more)Potatoes)
...
Use multiple build events instead of putting both commands in the same event.
Executing the source lines of a build event.
I can cut this short very easily: build events are not batch files.
What happens is that all lines in your build event are concatenated together using ampersand (&) signs which are used to execute multiple commands on one command line.
This means that all the fancy control structures (if statements, setlocal, for loops) are not possible inside build events.
ref: Pasted from a blog post: Delphi prebuild/prelink/postbuild events written by Jeroen W. Pluimers
Makes me wonder why you asked since it looks like you wrote the answer in 2014. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With