C#: Make GodotSharp API a NuGet package

In the past, the Godot editor distributed the API assemblies and
copied them to project directories for projects to reference them.
This changed with the move to .NET 5/6. Godot no longer copies the
assemblies to project directories. However, the project Sdk still
tried to reference them from the same location.
From now on, the GodotSharp API is distributed as a NuGet package,
which the Sdk can reference.

Added an option to `build_assemblies.py` to copy all Godot NuGet
packages to an existing local NuGet source. This will be needed
during development, while packages are not published to a remote
NuGet repository.
This option also makes sure to remove packages of the same version
installed (~/.nuget/packages). Very useful during development, when
packages change, to make sure the package being used by a project is
the same we just built and not one from a previous build.

A local NuGet source can be created like this:

```
mkdir ~/MyLocalNuGetSource && \
dotnet nuget add source ~/MyLocalNuGetSource/ -n MyLocalNuGetSource
```
This commit is contained in:
Ignacio Roldán Etcheverry 2022-02-27 21:57:53 +01:00
parent 4b90d16250
commit d78e0a8426
10 changed files with 90 additions and 40 deletions

View File

@ -1,3 +1,6 @@
<Project> <Project>
<Import Project="$(MSBuildThisFileDirectory)\SdkPackageVersions.props" /> <PropertyGroup>
<GodotSdkPackageVersionsFilePath>$(MSBuildThisFileDirectory)\SdkPackageVersions.props</GodotSdkPackageVersionsFilePath>
</PropertyGroup>
<Import Project="$(GodotSdkPackageVersionsFilePath)" />
</Project> </Project>

View File

@ -0,0 +1,22 @@
<Project>
<PropertyGroup>
<_HasNuGetPackage Condition=" '$(_HasNuGetPackage)' == '' And '$(PackageId)' != '' And '$(GeneratePackageOnBuild.ToLower())' == 'true' ">true</_HasNuGetPackage>
<_HasNuGetPackage Condition=" '$(_HasNuGetPackage)' == '' ">false</_HasNuGetPackage>
</PropertyGroup>
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack"
Condition=" '$(_HasNuGetPackage)' == 'true' ">
<PropertyGroup>
<GodotSourceRootPath>$(MSBuildThisFileDirectory)\..\..\</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
</PropertyGroup>
<Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
</Target>
<Target Name="PushNuGetPackagesToLocalSource" BeforeTargets="Pack"
Condition=" '$(_HasNuGetPackage)' == 'true' And '$(PushNuGetToLocalSource)' != '' ">
<Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(PushNuGetToLocalSource)\" />
</Target>
<Target Name="ClearNuGetLocalPackageCache" BeforeTargets="Pack"
Condition=" '$(_HasNuGetPackage)' == 'true' And '$(ClearNuGetLocalCache.ToLower())' == 'true' ">
<RemoveDir Directories="$(NugetPackageRoot)/$(PackageId.ToLower())/$(PackageVersion)"/>
</Target>
</Project>

View File

@ -1,7 +1,8 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<PackageFloatingVersion_Godot>4.0.*-*</PackageFloatingVersion_Godot> <PackageFloatingVersion_Godot>4.0.*-*</PackageFloatingVersion_Godot>
<PackageVersion_Godot_NET_Sdk>4.0.0-dev7</PackageVersion_Godot_NET_Sdk> <PackageVersion_GodotSharp>4.0.0-dev</PackageVersion_GodotSharp>
<PackageVersion_Godot_NET_Sdk>4.0.0-dev8</PackageVersion_Godot_NET_Sdk>
<PackageVersion_Godot_SourceGenerators>4.0.0-dev8</PackageVersion_Godot_SourceGenerators> <PackageVersion_Godot_SourceGenerators>4.0.0-dev8</PackageVersion_Godot_SourceGenerators>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -195,7 +195,7 @@ def run_msbuild(tools: ToolsLocation, sln: str, msbuild_args: [str] = None):
return subprocess.call(args, env=msbuild_env) return subprocess.call(args, env=msbuild_env)
def build_godot_api(msbuild_tool, module_dir, output_dir): def build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local):
target_filenames = [ target_filenames = [
"GodotSharp.dll", "GodotSharp.dll",
"GodotSharp.pdb", "GodotSharp.pdb",
@ -213,11 +213,15 @@ def build_godot_api(msbuild_tool, module_dir, output_dir):
targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames] targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames]
args = ["/restore", "/t:Build", "/p:Configuration=" + build_config, "/p:NoWarn=1591"]
if push_nupkgs_local:
args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local]
sln = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln") sln = os.path.join(module_dir, "glue/GodotSharp/GodotSharp.sln")
exit_code = run_msbuild( exit_code = run_msbuild(
msbuild_tool, msbuild_tool,
sln=sln, sln=sln,
msbuild_args=["/restore", "/t:Build", "/p:Configuration=" + build_config, "/p:NoWarn=1591"], msbuild_args=args,
) )
if exit_code != 0: if exit_code != 0:
return exit_code return exit_code
@ -252,9 +256,9 @@ def build_godot_api(msbuild_tool, module_dir, output_dir):
return 0 return 0
def build_all(msbuild_tool, module_dir, output_dir, dev_debug, godot_platform): def build_all(msbuild_tool, module_dir, output_dir, godot_platform, dev_debug, push_nupkgs_local):
# Godot API # Godot API
exit_code = build_godot_api(msbuild_tool, module_dir, output_dir) exit_code = build_godot_api(msbuild_tool, module_dir, output_dir, push_nupkgs_local)
if exit_code != 0: if exit_code != 0:
return exit_code return exit_code
@ -263,13 +267,18 @@ def build_all(msbuild_tool, module_dir, output_dir, dev_debug, godot_platform):
args = ["/restore", "/t:Build", "/p:Configuration=" + ("Debug" if dev_debug else "Release")] + ( args = ["/restore", "/t:Build", "/p:Configuration=" + ("Debug" if dev_debug else "Release")] + (
["/p:GodotPlatform=" + godot_platform] if godot_platform else [] ["/p:GodotPlatform=" + godot_platform] if godot_platform else []
) )
if push_nupkgs_local:
args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local]
exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args) exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args)
if exit_code != 0: if exit_code != 0:
return exit_code return exit_code
# Godot.NET.Sdk # Godot.NET.Sdk
args = ["/restore", "/t:Build", "/p:Configuration=Release"]
if push_nupkgs_local:
args += ["/p:ClearNuGetLocalCache=true", "/p:PushNuGetToLocalSource=" + push_nupkgs_local]
sln = os.path.join(module_dir, "editor/Godot.NET.Sdk/Godot.NET.Sdk.sln") sln = os.path.join(module_dir, "editor/Godot.NET.Sdk/Godot.NET.Sdk.sln")
exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=["/restore", "/t:Build", "/p:Configuration=Release"]) exit_code = run_msbuild(msbuild_tool, sln=sln, msbuild_args=args)
if exit_code != 0: if exit_code != 0:
return exit_code return exit_code
@ -290,6 +299,7 @@ def main():
) )
parser.add_argument("--godot-platform", type=str, default="") parser.add_argument("--godot-platform", type=str, default="")
parser.add_argument("--mono-prefix", type=str, default="") parser.add_argument("--mono-prefix", type=str, default="")
parser.add_argument("--push-nupkgs-local", type=str, default="")
args = parser.parse_args() args = parser.parse_args()
@ -304,7 +314,14 @@ def main():
print("Unable to find MSBuild") print("Unable to find MSBuild")
sys.exit(1) sys.exit(1)
exit_code = build_all(msbuild_tool, module_dir, output_dir, args.godot_platform, args.dev_debug) exit_code = build_all(
msbuild_tool,
module_dir,
output_dir,
args.godot_platform,
args.dev_debug,
args.push_nupkgs_local,
)
sys.exit(exit_code) sys.exit(exit_code)

View File

@ -26,16 +26,8 @@
<None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" /> <None Include="Sdk\Sdk.props" Pack="true" PackagePath="Sdk" />
<None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" /> <None Include="Sdk\Sdk.targets" Pack="true" PackagePath="Sdk" />
<!-- SdkPackageVersions.props --> <!-- SdkPackageVersions.props -->
<None Include="..\..\..\SdkPackageVersions.props" Pack="true" PackagePath="Sdk"> <None Include="$(GodotSdkPackageVersionsFilePath)" Pack="true" PackagePath="Sdk">
<Link>Sdk\SdkPackageVersions.props</Link> <Link>Sdk\SdkPackageVersions.props</Link>
</None> </None>
</ItemGroup> </ItemGroup>
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
<PropertyGroup>
<GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
</PropertyGroup>
<Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
</Target>
</Project> </Project>

View File

@ -95,19 +95,4 @@
<DefineConstants>$(GodotDefineConstants);$(DefineConstants)</DefineConstants> <DefineConstants>$(GodotDefineConstants);$(DefineConstants)</DefineConstants>
</PropertyGroup> </PropertyGroup>
<!-- Godot API references -->
<ItemGroup>
<!--
TODO:
We should consider a nuget package for reference assemblies. This is difficult because the
Godot scripting API is continuaslly breaking backwards compatibility even in patch releases.
-->
<Reference Include="GodotSharp">
<HintPath>$(GodotProjectDir).godot\mono\assemblies\$(GodotApiConfiguration)\GodotSharp.dll</HintPath>
</Reference>
<Reference Include="GodotSharpEditor" Condition=" '$(Configuration)' == 'Debug' ">
<HintPath>$(GodotProjectDir).godot\mono\assemblies\$(GodotApiConfiguration)\GodotSharpEditor.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@ -19,4 +19,10 @@
<ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' "> <ItemGroup Condition=" '$(DisableImplicitGodotGeneratorReferences)' != 'true' ">
<PackageReference Include="Godot.SourceGenerators" Version="$(PackageFloatingVersion_Godot)" /> <PackageReference Include="Godot.SourceGenerators" Version="$(PackageFloatingVersion_Godot)" />
</ItemGroup> </ItemGroup>
<!-- Godot API references -->
<ItemGroup Condition=" '$(DisableImplicitGodotSharpReferences)' != 'true' ">
<PackageReference Include="GodotSharp" Version="$(PackageVersion_GodotSharp)" />
<PackageReference Include="GodotSharpEditor" Version="$(PackageVersion_GodotSharp)" Condition=" '$(Configuration)' == 'Debug' " />
</ItemGroup>
</Project> </Project>

View File

@ -30,12 +30,4 @@
<!-- Package the props file --> <!-- Package the props file -->
<None Include="Godot.SourceGenerators.props" Pack="true" PackagePath="build" Visible="true" /> <None Include="Godot.SourceGenerators.props" Pack="true" PackagePath="build" Visible="true" />
</ItemGroup> </ItemGroup>
<Target Name="CopyNupkgToSConsOutputDir" AfterTargets="Pack">
<PropertyGroup>
<GodotSourceRootPath>$(SolutionDir)\..\..\..\..\</GodotSourceRootPath>
<GodotOutputDataDir>$(GodotSourceRootPath)\bin\GodotSharp\</GodotOutputDataDir>
</PropertyGroup>
<Copy SourceFiles="$(PackageOutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="$(GodotOutputDataDir)Tools\nupkgs\" />
</Target>
</Project> </Project>

View File

@ -15,6 +15,25 @@
<!-- Disabled temporarily as it pollutes the warnings, but we need to document public APIs. --> <!-- Disabled temporarily as it pollutes the warnings, but we need to document public APIs. -->
<NoWarn>CS1591</NoWarn> <NoWarn>CS1591</NoWarn>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<Description>Godot C# Core API.</Description>
<Authors>Godot Engine contributors</Authors>
<PackageId>GodotSharp</PackageId>
<Version>4.0.0</Version>
<PackageVersion>$(PackageVersion_GodotSharp)</PackageVersion>
<RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/glue/GodotSharp/GodotSharp</RepositoryUrl>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<!-- SdkPackageVersions.props for easy access -->
<None Include="$(GodotSdkPackageVersionsFilePath)">
<Link>SdkPackageVersions.props</Link>
</None>
</ItemGroup>
<PropertyGroup> <PropertyGroup>
<DefineConstants>$(DefineConstants);GODOT</DefineConstants> <DefineConstants>$(DefineConstants);GODOT</DefineConstants>
</PropertyGroup> </PropertyGroup>

View File

@ -10,6 +10,19 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<Description>Godot C# Editor API.</Description>
<Authors>Godot Engine contributors</Authors>
<PackageId>GodotSharpEditor</PackageId>
<Version>4.0.0</Version>
<PackageVersion>$(PackageVersion_GodotSharp)</PackageVersion>
<RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/glue/GodotSharp/GodotSharpEditor</RepositoryUrl>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<DefineConstants>$(DefineConstants);GODOT</DefineConstants> <DefineConstants>$(DefineConstants);GODOT</DefineConstants>
</PropertyGroup> </PropertyGroup>