Sunday, April 27, 2014

Building Delphi VCL Packages From the Command-line Using PowerShell and MSBuild - Part 3

This is a continuation of part 2.

MSBuild Parameters

Now that MSBuild is successfully compiled my project, the following questions came up in my mind:
  • Does Delphi call DCC or MSBuild?
  • What parameters can I pass in?
To answer the first question, I loaded Delphi and compiled the VCL package. I paid careful attention to the output. The screen appeared as follows:

Based on the highlighted output in the previous screenshot, I came to three conclusions:
  1. Delphi built the .dproj file, so the IDE must launch MSBuild to compile the project.
  2. Delphi built the project in Debug mode, so there must be an MSBuild parameter to specify the build configuration.
  3. Delphi built the project for the Win32 platform, so there must be an MSBuild parameter to specify the platform.
My next step was to open the .dproj file and look at what MSBuild parameters were available in there. I thought the following seemed important:

<PropertyGroup Condition="('$(Platform)'=='Win64'...
...
<PropertyGroup Condition="'$(Config)'=='Release'...
...
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
This looked promising!  Based on these three XML snippets, I came to three more conclusions:
  1. The MSBuild parameter for specifying the build configuration is called Config.
  2. The MSBuild parameter for specifying the build platform is called Platform.
  3. Embarcadero ships a default target file, located under $(BDS)\Bin\CodeGear.Delphi.Targets.
To test out my conclusions, I decided to manually try to reproduce what the IDE had done from the command line. I entered the following:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe ZLibEx_XE2.dproj /p:Config=Debug /p:Platform=Win32
It compiled successfully. Then, I replaced Win32 with Win64.  Sure enough, it failed due to the ZLibEx obj files being 32-bit. I had only one question left:
  • How could I override where to put the DCU files?
I could not find anything in the .dproj file. The only other option I could think of was to open the CodeGear.Delphi.Targets file. Sure enough, there it was:

<DCC_ObjOutput Condition = " '$(DCC_ObjOutput)' == ''">$(DCC_DcuOutput)</DCC_ObjOutput>
That was the answer I needed. The parameter I was looking for was DCC_DcuOutput. So, for my final test, I ran:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe ZLibEx_XE2.dproj /p:Config=Debug /p:Platform=Win32 /p:DCC_DcuOutput=C:\Temp\DCU
Sure enough, my DCU files ended up under C:\Temp\DCU. Perfect! By that point, I was ready to start my PowerShell module.

1 comment:

  1. Thanks for this post however I am now receive error F1027 which is due to Sytem.pas not being located. I am trying to create a build environment without installing the full ide.

    ReplyDelete