Open the attached project and try to build:
TestProj.zip
I couldn't find any way to get rid of the 2 warnings and still have my project imported.
No warning when having Sdk="Microsoft.NET.Sdk" in a parent and an imported project
OR
Imported project could in some way inherit the Sdk.
Showing warning:
1>C:DevTestProjTest.targets : warning MSB4011: "C:Program Filesdotnetsdk2.1.301SdksMicrosoft.NET.SdkSdkSdk.props" cannot be imported again. It was already imported at "C:DevTestProjTestProj.csproj". This is most likely a build authoring error. This subsequent import will be ignored.
1>C:DevTestProjTestProj.csproj : warning MSB4011: "C:Program Filesdotnetsdk2.1.301SdksMicrosoft.NET.SdkSdkSdk.targets" cannot be imported again. It was already imported at "C:DevTestProjTest.targets". This is most likely a build authoring error. This subsequent import will be ignored.
If I remove the Sdk="Microsoft.NET.Sdk" in Test.targets, the target won't run (can be seen from the Output, that will not show "Running...").
msbuild /version: 15.7.179.6572
.NET Sdk 2.1.300 or 2.1.301
OS info:
Windows 10 Enterprise
Version 10.0.16299 Build 16299
Visual Studio Enterprise 2017
Version 15.7.4
There is no need to specify an SDK at the project-element level in a .props or .targets file. The Sdk="Microsoft.NET.Sdk" attribute is a shorthand way of specifying an import at the top and bottom of the project file, which used to be explicit <Import elements.
For the example project here, just make this change:
diff --git a/Test.targets b/Test.targets
index 2b3702f..dc39c96 100644
--- a/Test.targets
+++ b/Test.targets
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project>
<Target Name="TargetTest">
<Message Text="Running..." Importance="high" />
</Target>
The warning is correct--the (simplified) import structure was:
TestProj.csproj
+-Microsoft.NET.Sdk .props
+-Test.targets
| +-Microsoft.NET.Sdk .props
| +-Microsoft.NET.Sdk .targets
+-Microsoft.NET.Sdk .targets
And that can cause real problems in your build, by bypassing default calculations and redefining already-defined properties and items.
@rainersigwald
Unfortunately the answer doesn't satisfy the issue reported.
As I mentioned:
"If I remove the Sdk="Microsoft.NET.Sdk" in Test.targets, the target won't run (can be seen from the Output, that will not show "Running...")."
Ah, I see. The problem is that you're hooking TargetTest into the build by overriding a target that is defined in Microsoft.Common.CurrentVersion.targets, which is imported (implicitly by <Project Sdk="Microsoft.NET.Sdk">) _last_, after the full contents of the file.
In this case that means that the default definition of an empty AfterBuild target with no dependencies overrides the one you define in your project (because the last definition of a target wins).
This works with the bad double-SDK-import structure, because the target gets defined in the "inner" import of common.targets and then overridden by the one in the project file.
The import structure becomes:
TestProj.csproj
+-Microsoft.NET.Sdk .props
+-Test.targets
| +-(Microsoft.NET.Sdk .props) # Elided as duplicate, emits MSB4011
| +-Microsoft.NET.Sdk .targets
| +-Microsoft.Common.CurrentVersion.targets
| +-AfterBuild (default)
+-AfterBuild (override)
+-(Microsoft.NET.Sdk .targets) # Elided as duplicate, emits MSB4011
There are several ways to fix this:
diff --git a/Test.targets b/Test.targets
index 2b3702f..8e892a8 100644
--- a/Test.targets
+++ b/Test.targets
@@ -1,5 +1,5 @@
-<Project Sdk="Microsoft.NET.Sdk">
- <Target Name="TargetTest">
+<Project>
+ <Target Name="TargetTest" BeforeTargets="AfterBuild">
<Message Text="Running..." Importance="high" />
</Target>
</Project>
\ No newline at end of file
diff --git a/TestProj.csproj b/TestProj.csproj
index f55c124..c7edd1c 100644
--- a/TestProj.csproj
+++ b/TestProj.csproj
@@ -5,5 +5,4 @@
</PropertyGroup>
<Import Project="Test.targets" />
- <Target Name="AfterBuild" DependsOnTargets="TargetTest" />
</Project>
diff --git a/Test.targets b/Test.targets
index 2b3702f..dc39c96 100644
--- a/Test.targets
+++ b/Test.targets
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project>
<Target Name="TargetTest">
<Message Text="Running..." Importance="high" />
</Target>
diff --git a/TestProj.csproj b/TestProj.csproj
index f55c124..4be9202 100644
--- a/TestProj.csproj
+++ b/TestProj.csproj
@@ -5,5 +5,5 @@
</PropertyGroup>
<Import Project="Test.targets" />
- <Target Name="AfterBuild" DependsOnTargets="TargetTest" />
+ <Target Name="InsertTest" BeforeTargets="AfterBuild" DependsOnTargets="TargetTest" />
</Project>
.targets import, so you can put the override after itdiff --git a/Test.targets b/Test.targets
index 2b3702f..dc39c96 100644
--- a/Test.targets
+++ b/Test.targets
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project>
<Target Name="TargetTest">
<Message Text="Running..." Importance="high" />
</Target>
diff --git a/TestProj.csproj b/TestProj.csproj
index f55c124..538fd84 100644
--- a/TestProj.csproj
+++ b/TestProj.csproj
@@ -1,9 +1,12 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project>
+ <Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" />
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<Import Project="Test.targets" />
+
+ <Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" />
<Target Name="AfterBuild" DependsOnTargets="TargetTest" />
</Project>
Most helpful comment
Ah, I see. The problem is that you're hooking
TargetTestinto the build by overriding a target that is defined inMicrosoft.Common.CurrentVersion.targets, which is imported (implicitly by<Project Sdk="Microsoft.NET.Sdk">) _last_, after the full contents of the file.In this case that means that the default definition of an empty
AfterBuildtarget with no dependencies overrides the one you define in your project (because the last definition of a target wins).This works with the bad double-SDK-import structure, because the target gets defined in the "inner" import of common.targets and then overridden by the one in the project file.
The import structure becomes:
There are several ways to fix this:
.targetsimport, so you can put the override after it