Quantcast
Channel: Planet Object Pascal
Viewing all articles
Browse latest Browse all 1725

The Wiert Corner - irregular stream of stuff: jpluimers

$
0
0

Ever since the Delphi build engine got changed to MS Build in Delphi 2007, many people use Delphi build events. Their order is prebuild, prelink and postbuild (or maybe better spelled pre-build, pre-link and post-build).

Before Delphi 2007, you had to fiddler with project groups and dependencies to fake pre-build and post-build events. For an example see Pre and Post-Build Automation in Delphi.

One of the really good things about these events is that build events appear in the output tab of the messages window.

One of the really bad things is that there is hardly any documentation about the build events.

At least two important things are missing:

  1. How the lines of a build event are actually executed
  2. How parameter expansion works inside build events

Let’s explain these.

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.

The alternative is to call a batch file from a build event, and have your control structures there.

But for that, you have to pass parameters, which leads to the expansion of $() parameters:

Expansion of the $() parameters inside build events

I could not find any official documentation of the $() parameters on the Embarcadero sites.

Ken White took the effort to type the parameters from Delphi 2010 into a StackOverflow answer (that list is gone in Delphi XE, but the bug reports on that got fixed in Delphi XE2 and up), and since then they have not changed:

BDS                 The environment variable $(BDS)
DEFINES             The project's conditional defines
DIR                 The environment variable $(DIR)
INCLUDEPATH         The project's include path
INPUTDIR            The input file's directory
INPUTEXT            The input file's extension
INPUTFILENAME       The input file's name, with extension
INPUTPATH           The input file's full path
LOCALCOMMAND        Local command entered by user in project manager
OUTPUTDIR           The output file's directory
OUTPUTEXT           The output file's extension
OUTPUTFILENAME      The output file's name, with extension
OUTPUTNAME          The output file's name, without extension
OUTPUTPATH          The output file's full path
Path                The environment variable $(PATH)
PROJECTDIR          The project's directory
PROJECTEXT          The project's extension
PROJECTFILENAME     The project file's name, with extension
PROJECTNAME         The project's name
PROJECTPATH         The project file's full path
SAVE                Save the input file to disk before it's compiled
SystemRoot          The environment variable $(SYSTEMROOT)
WINDIR              The environment variable $(WINDIR)

A nice list, but it doesn’t tell you what the values are (apart from the environment variables). So I compared the output of build-events like this:

>> %temp%\pre-build.txt echo BDS: $(BDS)
>> %temp%\pre-build.txt echo Config: $(Config)
>> %temp%\pre-build.txt echo DEFINES: $(DEFINES)
>> %temp%\pre-build.txt echo DIR: $(DIR)
>> %temp%\pre-build.txt echo INCLUDEPATH: $(INCLUDEPATH)
>> %temp%\pre-build.txt echo INPUTDIR: $(INPUTDIR)
>> %temp%\pre-build.txt echo INPUTEXT: $(INPUTEXT)
>> %temp%\pre-build.txt echo INPUTFILENAME: $(INPUTFILENAME)
>> %temp%\pre-build.txt echo INPUTNAME: $(INPUTNAME)
>> %temp%\pre-build.txt echo INPUTPATH: $(INPUTPATH)
>> %temp%\pre-build.txt echo LOCALCOMMAND: $(LOCALCOMMAND)
>> %temp%\pre-build.txt echo OUTPUTDIR: $(OUTPUTDIR)
>> %temp%\pre-build.txt echo OUTPUTEXT: $(OUTPUTEXT)
>> %temp%\pre-build.txt echo OUTPUTFILENAME: $(OUTPUTFILENAME)
>> %temp%\pre-build.txt echo OUTPUTNAME: $(OUTPUTNAME)
>> %temp%\pre-build.txt echo OUTPUTPATH: $(OUTPUTPATH)
>> %temp%\pre-build.txt echo Path: $(Path)
>> %temp%\pre-build.txt echo Platform: $(Platform)
>> %temp%\pre-build.txt echo PROJECTDIR: $(PROJECTDIR)
>> %temp%\pre-build.txt echo PROJECTEXT: $(PROJECTEXT)
>> %temp%\pre-build.txt echo PROJECTFILENAME: $(PROJECTFILENAME)
>> %temp%\pre-build.txt echo PROJECTNAME: $(PROJECTNAME)
>> %temp%\pre-build.txt echo PROJECTPATH: $(PROJECTPATH)
>> %temp%\pre-build.txt echo SAVE: $(SAVE)
>> %temp%\pre-build.txt echo SystemRoot: $(SystemRoot)
>> %temp%\pre-build.txt echo WINDIR: $(WINDIR)
"$(INPUTDIR)Copy_FastMM_FullDebugMode_Dll_PostBuildEvent.bat""$(Platform)""$(INPUTDIR)..\..\..\..\..\fastmm.sourceforge.net\FullDebugMode DLL\Precompiled\""$(OUTPUTDIR)"

I ran it using the project C:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent.dproj

The objective was to copy the correct FastMM FullDebugMode DLL into the directory of the .EXE (more on that later).

Observations of the events:

  • pre-link is not executed
  • pre-build and post-build get executed
  • pre-build and post-build give the same output

Output of pre-build.txt converted to a html table (too bad you cannot have code or pre tags around a table tag):

BDSc:\program files (x86)\embarcadero\rad studio\11.0
ConfigDebug
DEFINESDEBUG;FullDebugMode;
DIR
INCLUDEPATHc:\program files (x86)\embarcadero\rad studio\11.0\lib\Win64\release;C:\Users\Developer\Documents\RAD Studio\11.0\Imports;c:\program files (x86)\embarcadero\rad studio\11.0\Imports;C:\Users\Public\Documents\RAD Studio\11.0\Dcp\Win64;c:\program files (x86)\embarcadero\rad studio\11.0\include;C:\Program Files (x86)\FastReports\LibD18x64;C:\Program Files (x86)\Raize\CS5\Lib\RS-XE4\Win64
INPUTDIRC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\
INPUTEXT.dproj
INPUTFILENAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent.dproj
INPUTNAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent
INPUTPATHC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent.dproj
LOCALCOMMAND
OUTPUTDIRC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Win64\Debug\
OUTPUTEXT.exe
OUTPUTFILENAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent.exe
OUTPUTNAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent
OUTPUTPATHC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Win64\Debug\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent.exe
PathC:\Users\Public\Documents\InterBase\redist\InterBaseXE3\win32_togo;C:\Users\Public\Documents\InterBase\redist\InterBaseXE3\win64_togo;C:\Program Files (x86)\Embarcadero\RAD Studio\11.0\Redist\boost\win64;C:\Program Files (x86)\Embarcadero\RAD Studio\11.0\Redist\boost\win32;C:\Program Files (x86)\CollabNet;C:\Program Files (x86)\Embarcadero\RAD Studio\11.0\bin;C:\Users\Public\Documents\RAD Studio\11.0\Bpl;C:\Program Files (x86)\Embarcadero\RAD Studio\11.0\bin64;C:\Users\Public\Documents\RAD Studio\11.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files\TortoiseSVN\bin;C:\Program Files\TortoiseHg\;C:\BIN
PlatformWin64
PROJECTDIRC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent
PROJECTEXT.dproj
PROJECTFILENAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent.dproj
PROJECTNAMECopy_FastMM_FullDebugMode_Dll_PostBuildEvent
PROJECTPATHC:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent.dproj
SAVE
SystemRootC:\Windows
WINDIRC:\Windows

Observations of the values

Partially lowercase:

  • INCLUDEPATH: c:\program files (x86)\embarcadero\rad studio\11.0\lib\Win64\release;C:\Users\Developer\Documents\RAD Studio\11.0\Imports;c:\program files (x86)\embarcadero\rad studio\11.0\Imports;C:\Users\Public\Documents\RAD Studio\11.0\Dcp\Win64;c:\program files (x86)\embarcadero\rad studio\11.0\include;C:\Program Files (x86)\FastReports\LibD18x64;C:\Program Files (x86)\Raize\CS5\Lib\RS-XE4\Win64

Lowercase:

  • BDS: c:\program files (x86)\embarcadero\rad studio\11.0
  • INPUTEXT: .dproj
  • OUTPUTEXT: .exe
  • PROJECTEXT: .dproj

Empty:

  • DIR:
  • LOCALCOMMAND:
  • SAVE:

Ends with backslash:

  • INPUTDIR: C:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\
  • OUTPUTDIR: C:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent\Win64\Debug\

No backslash:

  • PROJECTDIR: C:\Users\Developer\SVN\BeSharp.codeplex.com\Native\Delphi\Apps\Copy_FastMM_FullDebugMode_Dll_PostBuildEvent

I tried these Intel based platforms in Delphi XE4:

  • Platform: OSX32
  • Platform: Win32
  • Platform: Win64

So that’s where the Copy_FastMM_FullDebugMode_Dll_PostBuildEvent came in (:

Future research

I need to put some more research into where these values are filled, and how you can pass your own to the MSBUILD process.

According to name, with extension INPUTPATH The input file’s full path LOCALCOMMAND Local command entered by user in project manager OUTPUTDIR The output file’s directory OUTPUTEXT – CodeInPro
and What are the MSBuild project level properties for Delphi? – Stack Overflow,
many values are set in
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Borland.Delphi.Targets
but that has since then moved to files named like this:
C:\Program Files (x86)\Embarcadero|CodeGear\RAD Studio\*.0\bin\CodeGear.*.Targets

Nobody seems to know about $(LOCALCOMMAND): Article 10854 Subject D2010 Build Events – Use of $(LOCALCOMMAND)? Where does it come from? on embarcadero.public.delphi.ide.

–jeroen


Filed under: Delphi, Delphi 2005, Delphi 2006, Delphi 2007, Delphi 2009, Delphi 2010, Delphi XE, Delphi XE2, Delphi XE3, Delphi XE4, Delphi XE5, Development, FastMM, Software Development

Viewing all articles
Browse latest Browse all 1725

Trending Articles