I have a script that starts msbuild and compiles a bunch of libraries. Here is the test script for one of them:
CALL _whereIsDelphi.cmd Alex
CALL "%DelphiPath%\bin\rsvars.bat"
msbuild "c:\source\TOOLS\Lib1\Lib1.dproj" /t:Build /p:DCC_BuildAllUnits=true /p:Configuration=Release /p:platform=Win32
PS: In the end, I want to pass to the script the whole .ProjGroup file instead of just one .dropj file.
But I have a problem with the output folder. Even though the .dproj file is like this:
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_BplOutput>.\$(ProductVersion)\$(Platform)\$(Config)</DCC_BplOutput>
<DCC_DcpOutput>.\$(ProductVersion)\$(Platform)\$(Config)</DCC_DcpOutput>
<DCC_DcuOutput>.\$(ProductVersion)\$(Platform)\$(Config)</DCC_DcuOutput>
the output (DCUs) goes to:
c:\source\TOOLS\Lib1\Win32\Release
instead of the expected:
c:\source\TOOLS\Lib1\22.0\Win32\Release
Any idea how to get the output (DCUs) to be created into the correct folder?
Note that even though most libraries are using the $(ProductVersion)$(Platform)$(Config) format for output, some of them don't. This is why I cannot use hard-coded output paths. I would really like to use the $(ProductVersion)
because this way I can have the libraries for Delphi 10, 11, 12 running in parallel.
Update:
Experiments:
DPROJ FILES
In Project Options, I set the "unit output directory" to "Test" and the MS Build recognizes that.
Then I set it to $(Config)\$(Config)
and it also works.
I also experimented to see if the MS Build can parse other fields from the DProj file. I experimented with the Map File (0 and 3) and it works.
Conclusion: the problem is only with the $(ProductVersion) variable, which is not recognized.
SCRIPT
In my script, I tried using /p:DCC_DcuOutput="Test"
, and it works, but /p:DCC_DcuOutput="$(ProductVersion)\$(Platform)\$(Config)"
will not work. It will not parse the first $()
variable. It will create the folders exactly as that: "$(ProductVersion)".
This will also not work: /p:DCC_DcuOutput="$(ProductVersion)\ Error it:
Could not create output file '$\DebugForm.dcu'`
Conclusion: the problem is with all the $() variables. None is recognized.
HOWEVER, even if the script had been able to parse the $() vars, this solution will still not work with my ultimate goal: to pass to MS Build a ProjGroup file, because there is no more script involved there. The MS Build goes through the whole ProjGroup without in one go.
And I really don't want to compile via project group file and also via a script, because the two will get desynchronized at one point! Whatever change we do in the group will have to go to the script also.
Solution:
I created a small Delphi project (MyParser.exe) that parses the DProj file and extracts from there the environment variables from the '<DCC_DcuOutput>$(ProductVersion)$(Platform)$(Config)</DCC_DcuOutput>' line.
I replace those variables with real paths.
I do the same for <DCC_ExeOutput>.
Then, my program executes (via ShellExecuteEx) MsBuild.exe and passes all the necessary parameters, including the two paths above, to it.
Finally, I call my program from a script like this:
MyParser.exe "c:\Test.dproj" 22.0 Win32 Release MyParser.exe "c:\Test.dproj" 22.0 Win64 Release
Where:
22 = $(ProductVersion)
Win32 = $(Platform)
Release = $(Config)