Byron
Byron
CC#
Created by Byron on 8/22/2024 in #help
Mixed Project References
Hey Folks, I often run into the case where I have one project that needs the output from another. For example i have ProjectA which is net8.0 and it needs the binaries from ProjectB which is compiled using net48. I can't add a project reference because they are different runtimes. I have tried to do
<ItemGroup>
<ProjectReference Include="ProjectB">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="ProjectB">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
However you get the error This project may not be fully compatible with your project. which is weird because it's not a reference. So I add
<ItemGroup>
<ProjectReference Include="ProjectB">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties> <!--- Add this -->
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="ProjectB">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties> <!--- Add this -->
</ProjectReference>
</ItemGroup>
However the explodes with doesn't have a target for 'net8.0' which is true because it's a net48 project. Is there a clean way to set this up without having to do a bunch of MSBuild targets?
8 replies
CC#
Created by Byron on 2/19/2024 in #help
Nuget Package: Project Reference Mutli Runtime Targeting
Hey Folks, I have a nuget package that wraps an exe, which I need to run on both linux and windows. I was trying to set it up so when I build my nuget package it compiles the other project reference and generates two executables. Altought what I have works it seems a bit hacky. I was wondering if there was a cleaner way of going about this
ini
App.Tool: Dotnet cli tool
App.MSBuild: References App.Tool and should build it twice and be contained within the nuget package.
ini
App.Tool: Dotnet cli tool
App.MSBuild: References App.Tool and should build it twice and be contained within the nuget package.
<!--==== App.MSBuild =====-->

<!-- Include in generated Nuget Package -->
<Target Name="AddNugetContent">
<ItemGroup>
<TfmSpecificPackageFile Include="$(PublishDir)$(LinuxRuntime)\*.*">
<PackagePath>tool/bin/$(LinuxRuntime)/%(RecursiveDir)</PackagePath>
</TfmSpecificPackageFile>
<TfmSpecificPackageFile Include="$(PublishDir)$(WindowsRuntime)\*.*">
<PackagePath>tool/bin/$(WindowsRuntime)/%(RecursiveDir)</PackagePath>
</TfmSpecificPackageFile>
</ItemGroup>
</Target>
<!-- Double Publish -->
<Target Name="MultiRuntimeBuild" BeforeTargets="Build">
<Message Importance="high" Text="BaseOutputPath: $(BaseOutputPath)"/>
<MSBuild Projects="$(ToolProjectDirectory)App.Tool.csproj" Targets="Publish" Properties="RuntimeIdentifier=$(LinuxRuntime);SelfContained=true;TargetFramework=net6.0;PublishDir=$(PublishDir)$(LinuxRuntime)" />
<MSBuild Projects="$(ToolProjectDirectory)App.Tool.csproj" Targets="Publish" Properties="RuntimeIdentifier=$(WindowsRuntime);SelfContained=true;TargetFramework=net6.0;PublishDir=$(PublishDir)$(WindowsRuntime)" />
</Target>
<!--==== App.MSBuild =====-->

<!-- Include in generated Nuget Package -->
<Target Name="AddNugetContent">
<ItemGroup>
<TfmSpecificPackageFile Include="$(PublishDir)$(LinuxRuntime)\*.*">
<PackagePath>tool/bin/$(LinuxRuntime)/%(RecursiveDir)</PackagePath>
</TfmSpecificPackageFile>
<TfmSpecificPackageFile Include="$(PublishDir)$(WindowsRuntime)\*.*">
<PackagePath>tool/bin/$(WindowsRuntime)/%(RecursiveDir)</PackagePath>
</TfmSpecificPackageFile>
</ItemGroup>
</Target>
<!-- Double Publish -->
<Target Name="MultiRuntimeBuild" BeforeTargets="Build">
<Message Importance="high" Text="BaseOutputPath: $(BaseOutputPath)"/>
<MSBuild Projects="$(ToolProjectDirectory)App.Tool.csproj" Targets="Publish" Properties="RuntimeIdentifier=$(LinuxRuntime);SelfContained=true;TargetFramework=net6.0;PublishDir=$(PublishDir)$(LinuxRuntime)" />
<MSBuild Projects="$(ToolProjectDirectory)App.Tool.csproj" Targets="Publish" Properties="RuntimeIdentifier=$(WindowsRuntime);SelfContained=true;TargetFramework=net6.0;PublishDir=$(PublishDir)$(WindowsRuntime)" />
</Target>
12 replies
CC#
Created by Byron on 2/6/2024 in #help
Source Generator AdditionalFiles Batching missing metadata
Hey folks, I am working with a source generator that wraps NSwag to generate clients and servers based on OpenApi spesefications. I have each project that wants to have generated client add the following Item.
<ItemGroup>
<GeneratedApiServerContracts Include="$(OpenApiBasePath)openapi.yml" /> <-- clients
<GeneratedApiClientContracts Include="$(OpenApiBasePath)openapi.yml" /> <-- servers
</ItemGroup>
<ItemGroup>
<GeneratedApiServerContracts Include="$(OpenApiBasePath)openapi.yml" /> <-- clients
<GeneratedApiClientContracts Include="$(OpenApiBasePath)openapi.yml" /> <-- servers
</ItemGroup>
I have both of these custom items defined with the following
<ItemDefinitionGroup>
<GeneratedApiClientContracts>
<Namespace>$(RootNamespace)</Namespace>
<NSwagGenerateClient>true</NSwagGenerateClient>
</GeneratedApiClientContracts>
<GeneratedApiServerContracts>
<Namespace>$(RootNamespace)</Namespace>
<NSwagGenerateServer>true</NSwagGenerateServer>
</GeneratedApiServerContracts>
</ItemDefinitionGroup>
<ItemDefinitionGroup>
<GeneratedApiClientContracts>
<Namespace>$(RootNamespace)</Namespace>
<NSwagGenerateClient>true</NSwagGenerateClient>
</GeneratedApiClientContracts>
<GeneratedApiServerContracts>
<Namespace>$(RootNamespace)</Namespace>
<NSwagGenerateServer>true</NSwagGenerateServer>
</GeneratedApiServerContracts>
</ItemDefinitionGroup>
I then merge these two items into an AdditionalFiles item so that it could be read by the source generator.
<AdditionalFiles Include="@(GeneratedApiClientContracts)"/>
<AdditionalFiles Include="@(GeneratedApiServerContracts)"/>
<AdditionalFiles Include="@(GeneratedApiClientContracts)"/>
<AdditionalFiles Include="@(GeneratedApiServerContracts)"/>
If I were evaluate this the following would be returned, as expected dotnet msbuild -getItem:AdditionalFiles
// trimed extra metadata for brevity.
{
"Items": {
"AdditionalFiles": [
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\nswag\\openapi.nswag",
"NSwagConfig": "true"
},
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\api\\api-gateway\\openapi.yml",
"Namespace": "ApiGateway",
"NSwagGenerateClient": "true"
},
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\api\\api-gateway\\openapi.yml",
"Namespace": "ApiGateway",
"NSwagGenerateServer": "true"
}
]
}
}
// trimed extra metadata for brevity.
{
"Items": {
"AdditionalFiles": [
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\nswag\\openapi.nswag",
"NSwagConfig": "true"
},
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\api\\api-gateway\\openapi.yml",
"Namespace": "ApiGateway",
"NSwagGenerateClient": "true"
},
{
"Identity": "D:\\dev\\gdw\\cadet\\cadet.service\\api\\api-gateway\\openapi.yml",
"Namespace": "ApiGateway",
"NSwagGenerateServer": "true"
}
]
}
}
When trying to access this from the source generator only the first two elements are returned from AdditionalTextsProvider.
6 replies
CC#
Created by Byron on 7/31/2023 in #help
✅ dotnet Restore and Targets in NuGet packages not found until second build
Hey folks, I have a NoTargets project file which contains logic for running our Ci/Cd. This file has a series of functions in there for build automation and running locally. It has logic for using the NuGet package GitVersion which is pulled in as a project reference.
<Project Sdk="Microsoft.Build.NoTargets/3.7.0">
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.10.3"/>
</ItemGroup>
<Project Sdk="Microsoft.Build.NoTargets/3.7.0">
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.10.3"/>
</ItemGroup>
Then my custom target has a dependency on a target defined within that package called GetVersion https://github.com/GitTools/GitVersion/blob/main/src/GitVersion.MsBuild/msbuild/tools/GitVersion.MsBuild.targets#L24. The target looks like this
<Target Name="__GenerateSharedGitAssemblyInfo" DependsOnTargets="WriteGitShaHash;GetVersion">
<!-- other stuff -->
</Target>
<Target Name="__GenerateSharedGitAssemblyInfo" DependsOnTargets="WriteGitShaHash;GetVersion">
<!-- other stuff -->
</Target>
The solution I am working with has 50+ projects which all need to be versioned so instead of running gitversion per assembly, I run it once and cache it with incremental building by sharing a single generated C# class. Each project calls into the build script using the MSBuild method to make sure the shared class in generated. It looks like this
<MSBuild Projects="$(MSBuildThisFileDirectory)Build.targets" Targets="Restore;GenerateSharedGitAssemblyInfo"/>
<MSBuild Projects="$(MSBuildThisFileDirectory)Build.targets" Targets="Restore;GenerateSharedGitAssemblyInfo"/>
The problem is that Restore will restore the packages for Build.targets however the targets defined in NuGet packages are not loaded into the current context, so they fail to resolve. The user has to build twice. Is there a simple way to force them to be resolved?
9 replies
CC#
Created by Byron on 6/14/2023 in #help
✅ Restore a PackageReference and use contained MSBBuild scripts inside of .targets file
Hey folks, I have a CICD script that executes a custom target Foo.targets using dotnet msbuild Foot.targets /t:DoSomething The script pretty much looks like this
<Project>
<ItemGroup>
<PackageRefernce Include="CustomBuildTargets" Version="1.0.0"/>
</ItemGroup>

<Target Name="DoSomthing">
<Message Importance="high" Text="The value is $(CustomBuildTargets_Variable)"/>
</Target>
</Project>
<Project>
<ItemGroup>
<PackageRefernce Include="CustomBuildTargets" Version="1.0.0"/>
</ItemGroup>

<Target Name="DoSomthing">
<Message Importance="high" Text="The value is $(CustomBuildTargets_Variable)"/>
</Target>
</Project>
The target is trying to use other targets and variables that are defined within the CustomBuildTargets nuget package. However since the this is a .target file and not a csproj I can't use restore. Is there a way to go about doing this? Things I have attempted> 1. -t:Restore=true 2. GeneratePathProperty and trying to get the path to the build folder in the nuget pakcage
9 replies