Report codes are chosen to conform to suggested guidelines. Those guidelines are currently in revew: #10088
Diagnostic Code | Default Severity | Reason |
---|---|---|
BC0101 | Warning | Shared output path. |
BC0102 | Warning | Double writes. |
BC0103 | Suggestion | Used environment variable. |
BC0201 | Warning | Usage of undefined property. |
BC0202 | Warning | Property first declared after it was used. |
BC0203 | Suggestion | Property declared but never used. |
To enable verbose logging in order to troubleshoot issue(s), enable binary logging
Cmd:
dotnet build -bl -check
"Two projects should not share their OutputPath nor IntermediateOutputPath locations"
It is not recommended to share output path nor intermediate output path between multiple projects. Such practice can lead to silent overwrites of the outputs. Such overwrites will depend on the order of the build, that might not be guaranteed (if not explicitly configured) and hence it can cause nondeterministic behavior of the build.
If you want to produce outputs in a consolidated output folder - consider using the Artifacts output layout and/or Microsoft.Build.Artifacts SDK.
"Two tasks should not write the same file"
This is a similar problem as 'BC0101 - Shared output path' - however with higher granularity. It is not recomended that multiple tasks attempt to write to a single file - as such behavior might lead to nondeterminism of a build (as result can be dependent on the order of the tasks execution if those belong to independent projects) or/and to a lost updates.
If you want multiple tasks to update file in a one-by-one pipeline fashion, it is recommended to give each intermediate output a distinct name - preventing silent mixups if any of the tasks in the chain are skipped or removed.
"Environment variables should not be used as a value source for the properties"
Using environment variables as a data source in MSBuild is problematic and can lead to nondeterministic builds. Relying on environment variables introduces variability and unpredictability, as their values can change between builds or environments.
This practice can result in inconsistent build outcomes and makes debugging difficult, since environment variables are external to project files and build scripts. To ensure consistent and reproducible builds, avoid using environment variables. Instead, explicitly pass properties using the /p option, which offers better control and traceability.
"A property that is accessed should be declared first."
This check indicates that a property was accessed without being declared (the declaration might have happen later - see BC0202 for such checking). Only accessing in the configured scope (by default it's the project file only) are checked.
There are couple cases which are allowed by the check:
-
Selfreferencing declaration is allowed - e.g.:
<ChainProp>$(ChainProp)</ChainProp>
-
Checking the property for emptyness - e.g.:
<PropertyGroup Condition="'$(PropertyThatMightNotBeDefined)' == ''">
-
Any usage of property in condition. This can be opted out via the configuration
AllowUninitializedPropertiesInConditions
- e.g.:[*.csproj] build_check.BC0201.severity=error build_check.BC0201.AllowUninitializedPropertiesInConditions=false build_check.BC0202.AllowUninitializedPropertiesInConditions=false
BC0201 and BC0202 must have same value for the optional switch - as both operate on top of same data and same filtering.
"A property should be declared before it is first used."
This check indicates that a property was accessed before it was declared. The default scope of this rule is the project file only. The scope captures the read and write operations as well. So this rule reports:
- Uninitialized reads that happened anywhere during the build, while the uninitialized property was later defined within the scope of this check (e.g. project file).
- Uninitialized reads that happened within the scope of check (e.g. project file), while later defined anywhere in the build
If BC0202
and BC0201 are both enabled - then BC0201
reports only the undefined reads that are not reported by this rule (so those that do not have late definitions).
"A property that is not used should not be declared."
This check indicates that a property was defined in the observed scope (by default it's the project file only) and it was then not used anywhere in the build.
This is a runtime check, not a static analysis check - so it can have false positives - for this reasons it's currently only suggestion.
Common cases of false positives:
- Property not used in a particular build might be needed in a build with different conditions or a build of a different target (e.g.
dotnet pack /check
ordotnet build /t:pack /check
accesses some additional properties as compared to ordinarydotnet build /check
). - Property accessing is tracked for each project build request. There might be multiple distinct build requests for a project in a single build. Specific case of this is a call to the MSBuild task or CallTarget task that can request a result from a project build, while passing additional or different global properties and/or calling specific target. This happens often as part of common targets - e.g. for multi-targeted project build parallelization
- Incremental build might skip execution of some targets, that might have been accessing properties of interest.