You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
-`.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
15
9
16
10
##File Structure
17
11
@@ -26,6 +20,7 @@
26
20
- children with the same tag name are within a same source(they're just declared separately)
27
21
- use`@(itemType)` to retrieve a list of items from*existing*`<ItemGroup>`
28
22
- has some builtin item types preserved
23
+
-`<ItemDefinitionGroup>`: define a new shape of item with default metadata
29
24
-`<Target>`: section to**wrap sub-procedures** and to be invoked during build
30
25
- name it like a function
31
26
- use`Name` attribute to specify a name for it
@@ -37,19 +32,48 @@
37
32
##Project Attributes
38
33
39
34
-`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**
- reserved properties: pre-defined and cannot be overridden
48
+
Two kinds of properties:
49
+
50
+
- reserved properties: pre-defined and cannot be overridden,
48
51
- 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)
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`
289
359
290
360
### Custom Task
291
361
@@ -308,41 +378,117 @@ Such approach seems to only allow updating on all existing items since `Include`
308
378
309
379
<Target Name="Hello">
310
380
<ItemGroup>
311
-
<FooList><!-- no Include here--><!-- [!code highlight]-->
381
+
<FooList> <!-- no Include here -->
312
382
<!-- 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>
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.
333
434
334
435
1. environment variables: they're stored as properties
335
436
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
337
440
3. definition of items: how should item were filtered out and captured.
338
441
4. items: execute the process to fetch items and their metadata
339
-
5. inline tasks
442
+
5. inline tasks(`<UsingTask>`)
340
443
6. targets: as well as items inside targets
341
444
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)
> [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.
346
492
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**
347
493
348
494
```xml
@@ -356,16 +502,59 @@ MSBuild would search upward for each aforementioned config file **until one was
356
502
</Project>
357
503
```
358
504
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
360
517
361
518
>[!TIP]
362
519
>- use`dotnet new buildprops` to create`Directory.Build.props`
363
520
>- use`dotnet new buildtargets` to create`Directory.Build.targets`
364
-
521
+
>- use`dotnet new packagesprops` to create`Directory.Packages.props`
365
522
366
523
##MSBuild CLI
367
524
368
-
MSBuild cli was wrapped as`dotnet msbuild [-options]`