Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaada76d

Browse files
committed
main
1 parent1aa069f commitaada76d

File tree

1 file changed

+227
-38
lines changed

1 file changed

+227
-38
lines changed

‎docs/document/Modern CSharp/docs/Understanding MSBuild.md‎

Lines changed: 227 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@
22

33
##File Types
44

5-
-`.*proj`: project file for each project
6-
-`.targets`: shared config for project within a same solution, can be imported to another.
7-
-`.props`:
8-
-`*.rsp`: msbuild response file,
9-
10-
###Recommended Usage
11-
12-
-`*.targets`
13-
- set dependent properties
14-
- override properties
5+
-`.*proj`: project identifier file for each project
6+
-`.props`: shared config to be imported at the beginning of the project file
7+
-`.targets`: shared config to be imported at the end of the project file
8+
-`*.rsp`:[msbuild response file](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-response-files?view=vs-2022), default options for msbuild cli so you don't have to repeat them on each build
159

1610
##File Structure
1711

@@ -26,6 +20,7 @@
2620
- children with the same tag name are within a same source(they're just declared separately)
2721
- use`@(itemType)` to retrieve a list of items from*existing*`<ItemGroup>`
2822
- has some builtin item types preserved
23+
-`<ItemDefinitionGroup>`: define a new shape of item with default metadata
2924
-`<Target>`: section to**wrap sub-procedures** and to be invoked during build
3025
- name it like a function
3126
- use`Name` attribute to specify a name for it
@@ -37,19 +32,48 @@
3732
##Project Attributes
3833

3934
-`SDK`: sepcify a sdk so that msbuild can prepare dedicated builtin*targets* and*tasks* for corresponding type of project.
40-
>a project with specified`SDK` is sometimes referred as*SDK-style project*
35+
>[!NOTE]
36+
>- a project with specified`SDK` is referred as*SDK-style project*
37+
>- a`<Project>` with`SDK` would auto import standard`*.targets` and`*.props`
38+
>- you could find standard config files from`${DOTNET_ROOT}/sdk/<dotnet_version>/Sdks/<sdk_name>/`
39+
40+
-`InitialTargets`: a list of targets should run first on build
41+
-`DefaultTargets`: a list of targets should run after`InitialTargets`**when no any target specified from msbuild cli**
4142

4243
>[!NOTE]
4344
>[Available SDKs](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#available-sdks)
4445
4546
##Property Section
4647

47-
- reserved properties: pre-defined and cannot be overridden
48+
Two kinds of properties:
49+
50+
- reserved properties: pre-defined and cannot be overridden,
4851
- well-known properties: pre-defined and can be overridden
52+
- properties set by specified sdk, all other sdk inherits from`Microsoft.NET.Sdk`, see:[.NET project SDKs](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview?view=aspnetcore-9.0)
4953

5054
>[!NOTE]
5155
>[Reserved & Well-Known Properties](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2022#reserved-and-well-known-properties)
5256
57+
###Property Functions
58+
59+
>[!NOTE]
60+
>[Property Functions](https://learn.microsoft.com/en-us/visualstudio/msbuild/property-functions?view=vs-2022)
61+
62+
###Merge Properties
63+
64+
```xml
65+
<PropertyGroup>
66+
<Foo>foo;bar</Foo>
67+
<!-- override self with interpolating itself-->
68+
<Foo>$(Foo);baz</Foo>
69+
</PropertyGroup>
70+
71+
<Target>
72+
<!-- foo;bar;baz-->
73+
<MessageText="$(Foo)"Importance="high"/>
74+
</Target>
75+
```
76+
5377
##Item Section
5478

5579
`<ItemGroup>` section is generally for specifying files to be included on build.
@@ -201,7 +225,40 @@ Each item has pre-defined metadata can be accessed.
201225
> [!NOTE]
202226
> If a item does not represent a file, the most of intrinsic metadata would be empty.
203227

228+
### Common Items
229+
230+
- `Reference`: reference to dll files
231+
- `PackageReference`: reference packages to be restored by nuget
232+
- `ProjectReference`: reference project by project file, builds projects cascading
233+
- `Using`: extra global using by specifying namespaces
234+
```xml
235+
<ItemGroup>
236+
<UsingInclude="System.IO.Pipes" />
237+
</ItemGroup>
238+
```
239+
240+
##ItemDefinitionGroup Section
241+
242+
```xml
243+
<ItemDefinitionGroup>
244+
<Foo>
245+
<!-- metadata Bar has default value bar-->
246+
<Bar>bar</Bar>
247+
</Foo>
248+
</ItemDefinitionGroup>
204249

250+
<ItemGroup>
251+
<FooInclude="foo"></Foo>
252+
</ItemGroup>
253+
254+
<TargetName="Hello">
255+
<!-- bar-->
256+
<MessageText="%(Foo.Bar)"Importance="high"/>
257+
</Target>
258+
```
259+
260+
>[!NOTE]
261+
>[ItemDefinitionGroup](https://learn.microsoft.com/en-us/visualstudio/msbuild/item-definitions?view=vs-2022)
205262
206263
##Expression Syntax
207264

@@ -224,10 +281,11 @@ Expression syntax in msbuild has some flavor of Command Prompt and PowerShell.
224281

225282
<TargetName="Hello">
226283
<!-- Collected metadata: Program.cs; ConsoleApp.csproj-->
227-
<MessageText="Collected metadata: @(MyFile->'%(FileName)%(Extension)')" <!-- [!code highlight] -->
228-
Importance="high" /><!-- [!code highlight]-->
229-
<MessageText="Exists: @(MyFile->Count())" <!-- 5 --><!-- [!code highlight]-->
230-
Importance="high" /><!-- [!code highlight]-->
284+
<MessageText="Collected metadata: @(MyFile->'%(FileName)%(Extension)')"
285+
Importance="high" />
286+
<!-- 5-->
287+
<MessageText="Exists: @(MyFile->Count())"
288+
Importance="high" />
231289
</Target>
232290
```
233291

@@ -248,23 +306,21 @@ For [special characters](https://learn.microsoft.com/en-us/visualstudio/msbuild/
248306
So one could include dedicated part of the config for different build scenarios.
249307

250308
```xml
251-
<ItemGroupCondition="'$(DotNetBuildSourceOnly)' == 'true'"><!-- [!code highlight]-->
309+
<ItemGroupCondition="'$(DotNetBuildSourceOnly)' == 'true'">
252310
<PackageVersionInclude="Microsoft.Build"Version="17.3.4" />
253311
<PackageVersionInclude="Microsoft.Build.Framework"Version="17.3.4" />
254312
<PackageVersionInclude="Microsoft.Build.Tasks.Core"Version="17.3.4" />
255313
<PackageVersionInclude="Microsoft.Build.Utilities.Core"Version="17.3.4" />
256314
</ItemGroup>
257315

258-
<ItemGroupCondition="'$(DotNetBuildSourceOnly)' != 'true' and '$(TargetFramework)' != 'net472'"><!-- [!code highlight]-->
316+
<ItemGroupCondition="'$(DotNetBuildSourceOnly)' != 'true' and '$(TargetFramework)' != 'net472'">
259317
<PackageVersionInclude="Microsoft.Build"Version="17.7.2" />
260318
<PackageVersionInclude="Microsoft.Build.Framework"Version="17.7.2" />
261319
<PackageVersionInclude="Microsoft.Build.Tasks.Core"Version="17.7.2" />
262320
<PackageVersionInclude="Microsoft.Build.Utilities.Core"Version="17.7.2" />
263321
</ItemGroup>
264322
```
265323

266-
##Builtin Variables
267-
268324
##Target Section
269325

270326
A task is a pre-defined procedure to be executed in`<Target>` section in their declared order.
@@ -273,6 +329,7 @@ MSBuild ships with some builtin task to be used out of box.
273329

274330
```xml
275331
<Target>
332+
<!-- Csc is a builtin task from sdk-->
276333
<Csc
277334
Sources="@(Compile)"
278335
OutputAssembly="$(AppName).exe"
@@ -283,9 +340,22 @@ MSBuild ships with some builtin task to be used out of box.
283340
>[!NOTE]
284341
>See:[MSBuild Task Reference](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-task-reference?view=vs-2022#in-this-section)
285342
286-
###Task Hooks
343+
###Builtin Targets
287344

288-
-`DependsOnTargets`
345+
MSBuild has some pre-defined targets to perform common actions like`Build`,`Clean`...
346+
Targets starts with`After` and`Before` are preserved to be overridden as a hook on specific target, such as`AfterBuild` and`BeforeBuild` are hooks on`Build`.
347+
348+
>[!NOTE]
349+
>Use`dotnet msbuild -targets|-ts [proj]` to check existing targets(including builtin) from a project file.
350+
>```ps1
351+
># filter out internal targets starts with _
352+
>dotnet msbuild -targets | where { $_ -notmatch '^_' }
353+
>```
354+
355+
### Target Hooks
356+
357+
- `DependsOnTargets`: this target must be executed after the specified target
358+
- `BeforeTarget`
289359
290360
### Custom Task
291361
@@ -308,41 +378,117 @@ Such approach seems to only allow updating on all existing items since `Include`
308378
309379
<Target Name="Hello">
310380
<ItemGroup>
311-
<FooList><!-- no Include here--><!-- [!code highlight]-->
381+
<FooList> <!-- no Include here -->
312382
<!-- update all existing items from FooList -->
313-
<FooMetaData>this is a bar metadata now!</FooMetaData><!-- [!code highlight]-->
383+
<FooMetaData>this is a bar metadata now!</FooMetaData>
314384
</FooList>
315385
</ItemGroup>
316386
317-
<MessageText="%(FooList.Identity): %(FooList.FooMetaData)"Importance="high"/><!-- [!code highlight]-->
387+
<Message Text="%(FooList.Identity): %(FooList.FooMetaData)" Importance="high"/>
318388
<!-- foo: this is a bar metadata now!
319389
bar: this is a bar metadata now!
320390
baz: this is a bar metadata now! -->
321391
</Target>
322392
```
323393
324-
##Importing
394+
###Emit Property and Item from Task
325395

326-
-`*.props` should be imported in early stage
327-
-`*.targets`: should be imported in build stage
396+
- one task could emit multiple items and properties(use multiple`<Output>`)
397+
- the task supports output parameter(specific value for`TaskParameter`)
398+
- search`output parameter` to check available`TaskParameter` on documentation of a task
399+
- use`PropertyName` or`ItemName` attribute to specify the name to emit
328400

329-
##Evaluation Order
401+
```xml
402+
<ItemGroup>
403+
<NewDirInclude="foo;bar" />
404+
</ItemGroup>
330405

331-
MSBuild files are order sensitive, order matters when properties and items may dependent on each other.
406+
<Target>
407+
<MakeDirDirectories="@(NewDir)">
408+
emit DirCreated property with the value of DirectoriesCreated
409+
<OutputTaskParameter="DirectoriesCreated"ItemName="DirCreated"/>
410+
</MakeDir>
411+
<!-- log out new property-->
412+
<MessageText="@(DirCreated)"Importance="high"/>
413+
</Target>
414+
```
332415

416+
##Import & Evaluation Order
417+
418+
The only file msbuild cares for build is the`*.*proj` file, all other files are just imports within it.
419+
The evaluation happens upon the project file, and splits the file into a process with priorities for different section.
420+
421+
###SDK Style
422+
423+
Aforementioned SDK-style project has implicit`<Import>` for standard`props` and`targets`.
424+
425+
- standard`props` were imported
426+
427+
###Evaluation
428+
429+
>[!NOTE]
430+
>[Evaluation Phase](https://learn.microsoft.com/en-us/visualstudio/msbuild/build-process-overview?view=vs-2022#evaluation-phase)
431+
432+
MSBuild files are order sensitive, order matters when properties and items may dependent on each other.
433+
MSBuild merges imported config files and proj file into one object, and then evaluate all values of different parts.
333434

334435
1. environment variables: they're stored as properties
335436
2. imports & properties: evaluated by their declaration order
336-
- so, the order between imports and properties matters if you inter-reference them on expression
437+
- when evaluating a import, the**evaluation process** applies to it**recursively**.
438+
- the order between imports and properties matters if you inter-reference them on expression
439+
- never reference items on properties not within a target
337440
3. definition of items: how should item were filtered out and captured.
338441
4. items: execute the process to fetch items and their metadata
339-
5. inline tasks
442+
5. inline tasks(`<UsingTask>`)
340443
6. targets: as well as items inside targets
341444

445+
>[!IMPORTANT]
446+
>Expressions are lazily evaluated until the identifier been referenced got evaluated.
447+
>So any expression to be evaluated on evaluation time(*not within a target*) would be like a template.
448+
>That is to say, the order doesn't matter when you inter-reference items and properties.
449+
>See:[Subtle effects of the evaluation order](https://learn.microsoft.com/en-us/visualstudio/msbuild/comparing-properties-and-items?view=vs-2022#subtle-effects-of-the-evaluation-order)
450+
>```xml
451+
> <PropertyGroup>
452+
><!-- reference before FooList were evaluated-->
453+
> <Foo>@(FooList)</Foo>
454+
> </PropertyGroup>
455+
>
456+
> <ItemGroup>
457+
> <FooListInclude="foo;bar"/>
458+
> </ItemGroup>
459+
>
460+
> <TargetName="Hello">
461+
><!-- foo;bar-->
462+
> <MessageText="$(Foo)"Importance="high"></Message>
463+
> </Target>
464+
>```
465+
466+
342467
## Folder-Specific Config
343468
344-
`Directory.Build.props` and`Directory.Build.targets` are special config files that could be auto-imported by msbuild.
345-
Such file is a**template** rather than a static store for values, so the containing properties and tasks**could vary for each project**.
469+
Folder-Specific config files includes:
470+
471+
- `Directory.Build.props`: content to be imported before standard config automatically for current or child folders
472+
- `Directory.Build.targets`: content to be imported after content of project file automatically for current or child folders
473+
- `Directory.Build.rsp`: default options for msbuild cli to be passed automatically on each build
474+
```
475+
# inside rsp file
476+
-v:diag -t:Clean
477+
```
478+
- `Directory.Packages.props`: for central package management, fixed version by `<PackageVersion>`
479+
```xml
480+
<PropertyGroup>
481+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
482+
</PropertyGroup>
483+
<ItemGroup>
484+
<PackageVersionInclude="Newtonsoft.Json"Version="13.0.1" />
485+
</ItemGroup>
486+
```
487+
488+
> [!NOTE]
489+
> [Introducing Central Package Management](https://devblogs.microsoft.com/nuget/introducing-central-package-management/)
490+
491+
All these kind of config are special config files that would be auto-imported by msbuild at certain phase.
346492
MSBuild would search upward for each aforementioned config file **until one was found**, it doesn't stop on solution root until it reaches the **drive root**
347493
348494
```xml
@@ -356,16 +502,59 @@ MSBuild would search upward for each aforementioned config file **until one was
356502
</Project>
357503
```
358504
359-
`Directory.Build.props` is imported early in`Microsoft.Common.props` which is the default config for sdk-style projects, so properties in`Directory.Build.props` should not be dependent on other
505+
###Best Practice
506+
507+
-`Directory.Build.props`: imported before standard musbuild config
508+
- to set**independent** properties
509+
- to set conditional items
510+
511+
-`Directory.Build.targets`: imported after standard
512+
- to override properties
513+
- to set**dependent** properties
514+
- to set targets
515+
516+
-`$(MSBuildProjectFullPath).user`: extra config specific to local machine, should not be included in source control
360517

361518
>[!TIP]
362519
>- use`dotnet new buildprops` to create`Directory.Build.props`
363520
>- use`dotnet new buildtargets` to create`Directory.Build.targets`
364-
521+
>- use`dotnet new packagesprops` to create`Directory.Packages.props`
365522
366523
##MSBuild CLI
367524

368-
MSBuild cli was wrapped as`dotnet msbuild [-options]`
525+
>[!NOTE]
526+
>[MSBuild CLI Reference](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2022#switches)
527+
528+
MSBuild cli was wrapped as`dotnet msbuild [-options]` within`dotnet` cli.
369529

370530
-`-p:<prop>=<value>`: override a property value(namely global property)
371-
-`-t:<target>`: trigger a target(and its dependent hooks)
531+
-`-t:<target>[;..]`: trigger a target(and its dependent hooks)
532+
-`-r`:`Restore` before building
533+
534+
>[!NOTE]
535+
>`dotnet` cli essentially wrapped`msbuild` cli and has some shorthand for common usage of`msbuild`.
536+
>All build and restore related command from`dotnet` are wrapper of a`msbuild` command.
537+
>Such targets like`Build` are pre-defined targets.
538+
>```sh
539+
># they're equivalent
540+
>dotnet build
541+
>dotnet msbuild -t:Build
542+
>dotnet msbuild# Build would be the default target if no other targets were specified
543+
>
544+
>dotnet pack
545+
>dotnet msbuild -t:Pack
546+
>
547+
>dotnet restore -p:Foo=foo
548+
>dotnet msbuild -t:Restore -p:Foo=foo#
549+
>```
550+
551+
### Target Execution Order
552+
553+
Targets would be executed by the order they were specified(each target triggers and waits its dependent targets)
554+
555+
```sh
556+
dotnet msbuild -t:Clean,Build# Clean first then Build
557+
```
558+
559+
>[!NOTE]
560+
>[Target Order](https://learn.microsoft.com/en-us/visualstudio/msbuild/target-build-order?view=vs-2022#determine-the-target-build-order)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp