في كثير من الأحيان ، صادفت حقيقة أن مطوري دلفي (يمكن للمرء أن يقول تقليديًا) يجمعون تطبيقاتهم باستخدام "أقلام" ، وهي بعيدة عن حل الإنتاج ، ولكن من الخارج تبدو مثل فرك و "تفعل ذلك على الركبة" ، على الرغم من أن المنتجات خطيرة للغاية وقابلة للبيع . ربما يرجع ذلك إلى الوقت الذي كانت فيه الأتمتة بحاجة إلى التوصل إلى ملفات دفعية خاصة بها والتي بدأت مترجم سطر الأوامر dcc32
بالمعلمات الضرورية. حتى أن البعض صنع "الناشر" الخاص بهم - خبير دلفي ، الذي يقوم بعمل خادم التجميع: يجمع المشروع (على الرغم من أنه مفتوح في IDE) ، ويكشفه برقم إصدار متزايد مأخوذ من بعض قواعد البيانات ، ويكتب نوعًا من التغيير وينسخه في مكان ما إلى دليل الشبكة .
لن أخوض في رحلة تاريخية كما كانت من قبل . سأخبرك الآن كيف تأكل / تستطيع الآن ، وكيف تستخدمها لزيادة كفاءة عملي.
ملف مشروع النسخة الحديثة من دلفي هو .dproj
ملف (فيما يلي سوف أركز على دلفي 10 ريو ، ولكن مع اختلافات طفيفة هذا ينطبق على جميع الإصدارات السابقة من دلفي ، ابتداء من عام 2007). يقوم بتخزين جميع إعدادات المشروع ، والتي عادة ما يتم تغييرها في IDE (القائمة Project - Options (Ctrl+Shift+F11)
). في هذه المقالة ، سوف أركز على تلك "الأساسية" التي ستكون مطلوبة لتوضيح المبادئ العامة: هذا Config
هو التكوين ، والنظام Platform
الأساسي ، OutputDirectory
ومسار ملف الإخراج ، و ConditionalDefines
(توجيهات الترجمة الشرطية). بقية الإعدادات ، إذا لزم الأمر تغييرها أثناء التجميع ، أقترح تعريف نفسك. هذا .dproj
الملف نفسه ، إذا نظرت إليه باستخدام محرر نص عادي ، ليس أكثر من برنامج نصي لبناء MSBuild(دعنا ننشئ تطبيق وحدة تحكم بسيط ونطلق عليه DelphiAutomatedBuild ):
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{6880AD8E-6CB3-47B9-B8E3-7304CF6E9735}</ProjectGuid>
<ProjectVersion>18.1</ProjectVersion>
<FrameworkType>None</FrameworkType>
<MainSource>DelphiAutomatedBuild.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Debug</Config>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<AppType>Console</AppType>
</PropertyGroup>
...
كما تستخدم البرامج النصية لبناء MSBuild لوصف المشاريع ، مثل Visual Studio. سوف أتطرق إلى بعض تفاصيل MSBuild ، لكنني أقترح أن يتقن القارئ أساسياته من تلقاء نفسه . ماذا يعطينا هذا؟ هذا يسمح لنا ببناء مشروع دلفي من سطر الأوامر مع سطر واحد ( والذي بدوره يسمح لنا بأتمتة تجميع المشروع )
msbuild /t:build DelphiAutomatedBuild.dproj
MSBuild? Delphi, MSBuild , Delphi . , %WINDIR%\Microsoft.Net\Framework\v3.5
, .Net 4.0/4.5/4.6. Microsoft. MSBuild 4.0, ,
(hint: , () IDE — Show in Explorer, — ), :
...>msbuild /t:build DelphiAutomatedBuild.dproj
"msbuild"
, .
. , MSBuild- PATH
. :
set PATH=%WINDIR%\Microsoft.Net\Framework\v3.5;%PATH%
:
...>msbuild /t:build DelphiAutomatedBuild.dproj
Microsoft (R) Build Engine 12.0.21005.1
[Microsoft .NET Framework 4.0.30319.42000]
(C) (Microsoft Corporation). .
24.11.2018 0:12:14.
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" 1 ( build).
Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj : error MSB4057: "build".
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" ( build) .
.
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" ( build ) (1) ->
Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj : error MSB4057: "build".
: 0
: 1
: 00:00:00.04
, . ? build
?
.dproj
-, :
...
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
...
Delphi
c:\Program Files\Embarcadero\Studio\20.0\Bin\CodeGear.Delphi.Targets
, MSBuild-, Build
:
<Target Name="Build"...
.. BDS
($(VAR)
MSBuild (Property) VAR
, , ), Delphi, (-, Delphi, BDS
). $(BDS)
, .Targets
Delphi Build
.
:
set BDS=c:\Program Files\Embarcadero\Studio\20.0
...>msbuild /t:build DelphiAutomatedBuild.dproj
Microsoft (R) Build Engine 12.0.21005.1
[Microsoft .NET Framework 4.0.30319.42000]
(C) (Microsoft Corporation). .
24.11.2018 0:20:40.
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" 1 ( build).
CreateProjectDirectories:
".\Win32\Debug".
BuildVersionResource:
C:\Program Files\Embarcadero\Studio\20.0\bin\cgrc.exe -c65001 DelphiAutomatedBuild.vrc -foDelphiAutomatedBuild.res
CodeGear Resource Compiler/Binder
Version 1.2.2 Copyright (c) 2008-2012 Embarcadero Technologies Inc.
Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
Copyright (C) Microsoft Corporation. All rights reserved.
"DelphiAutomatedBuild.vrc" .
_PasCoreCompile:
C:\Program Files\Embarcadero\Studio\20.0\bin\dcc32.exe -$O- -$W+ --no-config -B -Q -TX.exe -AGenerics.Collections=System.Generics.Collections;Generics.Defaults=System.Generics.Defaults;WinTypes=Winapi.Windows;WinProcs=Winapi.Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE -DDEBUG -E.\Win32\Debug -I"c:\program files\embarcadero\studio\20.0\lib\Win32\debug";"c:\program files\embarcadero\studio\20.0\lib\Win32\release";C:\Users\USER\Documents\Embarcadero\Studio\20.0\Imports;"C:\Program Files\Embarcadero\Studio\20.0\Imports";"C:\Users\Public\Documents\RAD Studio\5.0\Dcp";"C:\Program Files\Embarcadero\Studio\20.0\include";C:\Users\USER\AppData\Local\Programs\TestInsight\Source -LE"C:\Users\Public\Documents\RAD Studio\5.0\Bpl" -LN"C:\Users\Public\Documents\RAD Studio\5.0\Dcp" -NU.\Win32\Debug -NSWinapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;System;Xml;Data;Datasnap;Web;Soap; -O"c:\program files\embarcadero\studio\20.0\lib\Win32\release";C:\Users\USER\Documents\Embarcadero\Studio\20.0\Imports;"C:\Program Files\Embarcadero\Studio\20.0\Imports";"C:\Users\Public\Documents\RAD Studio\5.0\Dcp";"C:\Program Files\Embarcadero\Studio\20.0\include";C:\Users\USER\AppData\Local\Programs\TestInsight\Source -R"c:\program files\embarcadero\studio\20.0\lib\Win32\release";C:\Users\USER\Documents\Embarcadero\Studio\20.0\Imports;"C:\Program Files\Embarcadero\Studio\20.0\Imports";"C:\Users\Public\Documents\RAD Studio\5.0\Dcp";"C:\Program Files\Embarcadero\Studio\20.0\include";C:\Users\USER\AppData\Local\Programs\TestInsight\Source -U"c:\program files\embarcadero\studio\20.0\lib\Win32\debug";"c:\program files\embarcadero\studio\20.0\lib\Win32\release";C:\Users\USER\Documents\Embarcadero\Studio\20.0\Imports;"C:\Program Files\Embarcadero\Studio\20.0\Imports";"C:\Users\Public\Documents\RAD Studio\5.0\Dcp";"C:\Program Files\Embarcadero\Studio\20.0\include";C:\Users\USER\AppData\Local\Programs\TestInsight\Source -CC -V -VN -NB"C:\Users\Public\Documents\RAD Studio\5.0\Dcp" -NH"C:\Users\Public\Documents\RAD Studio\5.0\hpp\Win32" -NO.\Win32\Debug DelphiAutomatedBuild.dpr
Embarcadero Delphi for Win32 compiler version 30.0
Copyright (c) 1983,2015 Embarcadero Technologies, Inc.
19 lines, 0.27 seconds, 100748 bytes code, 26044 bytes data.
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" ( build).
.
: 0
: 0
: 00:00:01.32
-! . Win32\Debug
DelphiAutomatedBuild.exe
.
( , Debug-), Release- ( ). IDE , , , , . .dproj
-,
...
<Config Condition="'$(Config)'==''">Debug</Config>
...
, , / Config
, , Debug
. , IDE ( IDE Release —
...
<Config Condition="'$(Config)'==''">Release</Config>
...
:
{$IFDEF RELEASE}
WriteLn('This is RELEASE build');
{$ENDIF RELEASE}
{$IFDEF DEBUG}
WriteLn('This is DEBUG build');
{$ENDIF DEBUG}
, conditional defines Release Debug- RELEASE DEBUG,
Config
, :
...>msbuild /t:build DelphiAutomatedBuild.dproj /p:Config=Release
Microsoft (R) Build Engine 12.0.21005.1
[Microsoft .NET Framework 4.0.30319.42000]
(C) (Microsoft Corporation). .
24.11.2018 0:48:30.
"Z:\habr\delphi-automate-build\DelphiAutomatedBuild.dproj" 1 ( build).
CreateProjectDirectories:
".\Win32\Release".
...
...>Win32\Debug\DelphiAutomatedBuild.exe
This is DEBUG build
...>Win32\Release\DelphiAutomatedBuild.exe
This is RELEASE build
!
( ) - , , , — - . , . .dproj
:
...
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
...
? ( ), , ?
...>msbuild /t:build DelphiAutomatedBuild.dproj /p:DCC_ExeOutput=binaries
-! binaries
, — DelphiAutomatedBuild.exe
. ? , MSBuild
, , , MSBuild
-, , . . ...
. , (, ). , Config
— Debug
, — — Release
, , -, (, DCC_ExeOutput
( — )), -, , ( , MSBuild- ).
...>msbuild /t:build DelphiAutomatedBuild.dproj /p:DCC_ExeOutput=binaries
. ? !
Build
. - , IDE ( ; , MMX: DProjNormalizer, DProjSplitter — ProjectMagician — .dproj
-), . DAB.ciproj (CI-project, CI — Continuous Integration):
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<MSBuild Projects="DelphiAutomatedBuild.dproj"
Targets="Build"
Properties="Config=Debug"/>
<MSBuild Projects="DelphiAutomatedBuild.dproj"
Targets="Build"
Properties="Config=Release"/>
</Target>
</Project>
...>msbuild /t:build DAB.ciproj /p:DCC_ExeOutput=binaries
… DelphiAutomatedBuild.exe
binaries
, , :
...>binaries\DelphiAutomatedBuild.exe
This is RELEASE build
DCC_Exeoutput
MSBuild — , . :
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Build">
<MSBuild Projects="DelphiAutomatedBuild.dproj"
Targets="Build"
Properties="Config=Debug;DCC_Exeoutput=$(DCC_ExeOutput)\Debug"/>
<MSBuild Projects="DelphiAutomatedBuild.dproj"
Targets="Build"
Properties="Config=Release;DCC_Exeoutput=$(DCC_ExeOutput)\Release"/>
</Target>
</Project>
...>msbuild /t:build DAB.ciproj /p:DCC_ExeOutput=binaries
binaries\Debug\DelphiAutomatedBuild.exe
binaries\Release\DelphiAutomatedBuild.exe
.
...>binaries\Debug\DelphiAutomatedBuild.exe
This is DEBUG build
...>binaries\Release\DelphiAutomatedBuild.exe
This is RELEASE build
, / conditional define (, -, , TRIAL )
-
{$IFDEF TRIAL}
WriteLn('This is TRIAL version');
{$ENDIF TRIAL}
Debug- conditional define TRIAL , .dproj:
<DCC_Define>DEBUG;TRIAL;$(DCC_Define)</DCC_Define>
, .. /p:DCC_Define=TRIAL,
...>msbuild /t:build DAB.ciproj /p:DCC_ExeOutput=binaries /p:DCC_Define=TRIAL
...>binaries\Debug\DelphiAutomatedBuild.exe
This is TRIAL version
...>binaries\Release\DelphiAutomatedBuild.exe
This is TRIAL version
, - , - DEBUG RELEASE, , .. define-.
, , . .
DCC_Define
:
...>set DCC_Define=TRIAL
...>msbuild /t:build DAB.ciproj /p:DCC_ExeOutput=binaries
...
...>binaries\Debug\DelphiAutomatedBuild.exe
This is DEBUG build
This is TRIAL version
...>binaries\Release\DelphiAutomatedBuild.exe
This is RELEASE build
This is TRIAL version
, , ( Git, SVN ) , , , , .
, . ? , , — - "-", , ( " " — ).
Windows/Delphi- Major.Minor.Release.Build
, , , Release
, , , . , , .dproj-
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
, . FileVersion=0.0.0.0
, , FileVersion=$(Version)
, Version
— , , , IDE — , .. "" . . , , — CSV-, .
, . MSBuild 4.0 C#, ( , PATH ).
Delphi.Version.Targets<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="12.0">
<UsingTask TaskName="__SetFileVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<VerInfoKeys ParameterType="System.String" Required="true" />
<VerInfoProperties ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<Out ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs"><![CDATA[
// split values as CSV (by ";")
String[] verInfoKeysList = VerInfoKeys.Split(';');
Dictionary<String, String> d = new Dictionary<String, String>();
foreach (String verInfoValue in verInfoKeysList) {
// split values as "key=value"
if (! String.IsNullOrEmpty(verInfoValue)) {
String[] kv = verInfoValue.Split('=');
d.Add(kv[0], kv[1]);
}
}
if (VerInfoProperties.Length > 0) {
foreach (ITaskItem item in VerInfoProperties) {
String value = item.GetMetadata("Value");
if (value.Length > 0) {
Log.LogMessage("{0}: {1}", item.ItemSpec, value);
d.Remove(item.ItemSpec);
d.Add(item.ItemSpec, value);
}
}
}
List<String> L = new List<String>();
foreach (KeyValuePair<String, String> kv in d) {
L.Add(kv.Key + "=" + kv.Value);
}
_Out = String.Join(";", L.ToArray());
]]></Code>
</Task>
</UsingTask>
<Target Name='_SetVersionCode_Name'>
<Message Text="$(VerInfo_Keys)" />
<ItemGroup>
<VerInfoProperties Include="FileVersion">
<Value>$(FileVersion)</Value>
</VerInfoProperties>
</ItemGroup>
<__SetFileVersion VerInfoKeys="$(VerInfo_Keys)" VerInfoProperties="@(VerInfoProperties)">
<Output PropertyName="VerInfo_Keys" TaskParameter="Out" />
</__SetFileVersion>
<Message Text="$(VerInfo_Keys)" />
</Target>
<Target Name='_SetFileVersion' BeforeTargets="_BuildRCFile"
Condition="'$(FileVersion)' != ''">
<CallTarget Targets='_SetVersionCode_Name'/>
</Target>
</Project>
.
DelphiAutomatedBuild.dproj
...
<Import Project="Delphi.Version.Targets" Condition="$(MSBuildToolsVersion) >= 4.0" />
...
( "$(MSBuildToolsVersion) >= 4.0" , IDE, , , MSBuild 3.5, UsingTask)
, _SetFileVersion
, _BuildRCFile
( : , — . $(BDS)\bin\Codegear.Common.Targets
), FileVersion
. CSV- VerInfo_Keys
, -, , VerInfo_Keys
.
"Include version information in project" ( ), :
...>msbuild /t:build DAB.ciproj /p:DCC_ExeOutput=binaries /p:FileVersion=4.3.2.1
...>binaries\Debug\DelphiAutomatedBuild.exe
This is RELEASE build
This is TRIAL version
This file version is 4.3.2.1
...>binaries\Release\DelphiAutomatedBuild.exe
This is DEBUG build
This is TRIAL version
This file version is 4.3.2.1
Profit!
Delphi- , , , , , , . , ( ), .
- ( FixInsight, !)
- unit- Delphi (, ))). )
- "" Delphi- GitLab CI
- وكذلك كيفية استخدام مصحح أخطاء WinDbg ، على سبيل المثال ، للعثور على أسباب أعطال / أعطال التطبيق بسبب المكتبات المكتوبة في دلفي (بالطبع ، بالطبع ، كيفية دمج تشكيل ملفات PDB اللازمة لهذا في التجميع التلقائي)
Z.Y. يسعدني الرد على أي أسئلة ، بما في ذلك في برقية ، سواء في PM أو في Delphi_Lazarus و DelphiCommunity دردشات