Skip to content

Commit

Permalink
Use bin as default output dir for native projects (#27)
Browse files Browse the repository at this point in the history
`$(GradleProjectBuildDirectory)` and `$(XcodeProjectBuildDirectory)`
props have been added to control the name of the output directory of
native builds. The default value is now `bin`, to better match .NET
project outputs.

The android and macios targets now hook into the Clean target to ensure
native project outputs are removed when Clean is ran.
  • Loading branch information
pjcollins authored Jun 19, 2024
1 parent 5fcae27 commit bdf9b24
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 39 deletions.
48 changes: 37 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,35 @@ Install prerequisites:
## Building

The goal is to have bindings and samples building 100% through normal MSBuild invocations.
The binding build process is extended to obtain and build native SDK dependencies by adding the `CommunityToolkit.Maui.BindingExtensions` NuGet package to your binding project:

Each .NET Binding project contains some additional MSBuild logic to help obtain and build the native SDK dependencies along with the native slim binding project. In some cases, the target may also download native SDKs if they are not already present. In this way, the expected native artifacts are available in the expected working directories.
```xml
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui.BindingExtensions" Version="0.0.1-pre1" />
</ItemGroup>
```

Android binding projects will also add a `@(GradleProjectReference)` item that points to the root folder that contains their gradle project:

```xml
<ItemGroup>
<GradleProjectReference Include="../native" >
<ModuleName>mauifacebook</ModuleName>
</GradleProjectReference>
</ItemGroup>
```

In the [```src/```](/src/) folder you will find a solution with custom build tasks/targets to help with this. These build extensions are available in a CommunityToolkit.Maui.BindingExtensions NuGet package that the binding projects reference.
iOS binding projects will also add a `@(XcodeProjectReference)` item that points to their Xcode project:

```xml
<XcodeProjectReference Include="../native/MauiFacebook.xcodeproj">
<SchemeName>MauiFacebook</SchemeName>
<SharpieNamespace>Facebook</SharpieNamespace>
<SharpieBind>true</SharpieBind>
</XcodeProjectReference>
```

In the [```src/```](/src/) folder you will find the sources for the NuGet and these custom build tasks/targets.

Android binding projects generate the API definition automatically taking into account any optional manual modifications like those implemented via the [```Metadata.xml```](https://learn.microsoft.com/xamarin/android/platform/binding-java-library/customizing-bindings/java-bindings-metadata#metadataxml-transform-file) transform file.

Expand Down Expand Up @@ -191,7 +215,7 @@ public static func unregister(completion: @escaping (NSError?) -> Void) {
The other half will be to update the `ApiDefinitions.cs` file in the binding project to expose this new method. There are two ways you can go about this:

1. You can manually add the required code
2. When the binding project builds, objective sharpie is run and an `ApiDefinitions.cs` file is generated inside of the `native/macios/.build/Binding` folder (this path will vary based on the project you are working on of course). You can try to find the relevant changes from this file and copy them over manually, or try copying over the whole file and looking at the diff to find the part you need.
2. When the binding project builds, objective sharpie is run and an `ApiDefinitions.cs` file is generated inside of the `native/macios/bin/sharpie` folder (this path will vary based on the project you are working on of course). You can try to find the relevant changes from this file and copy them over manually, or try copying over the whole file and looking at the diff to find the part you need.

In this case, the changes to `ApiDefinitions.cs` would be:

Expand Down Expand Up @@ -278,19 +302,21 @@ There are several ways you can use these samples in your own project.

When packaging a native Android library (.aar) file, gradle/maven dependencies are _not_ automatically bundled into your library. This is important to note, as the application project will often need to explicitly reference these dependencies in order to run successfully. While this approach can work on an individual application basis, it is *not* recommended for library projects. Including specific versions of dependencies in a library can lead to version conflicts when the library is consumed by an application that also uses the same dependencies.

The `facebook/android/native/mauifacebook/build.gradle.kts` file is configured to copy facebook dependencies into a `build/outputs/deps` folder. Some of this content is then referenced by the .NET MAUI sample project:
The `facebook/android/native/mauifacebook/build.gradle.kts` file is configured to copy facebook dependencies into a `bin/outputs/deps` folder. Some of this content is then referenced by the .NET MAUI sample project:

```xml
<ItemGroup>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-common*.aar">
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-android-sdk-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-common-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-core*.aar">
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-core-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
</ItemGroup>
</AndroidLibrary>
```

In some cases first party NuGet packages will exist for missing dependencies. In other cases, you may need to manually include the dependencies in the project as demonstrated in the sample. We hope to improve this type of dependency inclusion guess work in the future by introducing support for `@(AndroidMavenPackage)` references in Android projects.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
<PackageReference Include="CommunityToolkit.Maui.BindingExtensions" Version="$(BindingExtPackageVersion)" />
</ItemGroup>

<!-- Metadata applicable to @(AndroidLibrary) will be used if set -->
<ItemGroup>
<GradleProjectReference Include="../native" >
<ModuleName>mauifacebook</ModuleName>
<!-- Metadata applicable to @(AndroidLibrary) will be used if set, otherwise the following defaults will be used:
<Bind>true</Bind>
<Pack>true</Pack>
-->
</GradleProjectReference>
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion facebook/android/native/mauifacebook/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ dependencies {
project.afterEvaluate {
tasks.register<Copy>("copyDeps") {
from(configurations["copyDependencies"])
into("${projectDir}/build/outputs/deps")
into("${buildDir}/outputs/deps")
}
tasks.named("preBuild") { finalizedBy("copyDeps") }
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
<SchemeName>MauiFacebook</SchemeName>
<SharpieNamespace>Facebook</SharpieNamespace>
<SharpieBind>true</SharpieBind>
<!-- Metadata applicable to @(NativeReference) will be used if set -->
<!-- Metadata applicable to @(NativeReference) will be used if set, otherwise the following defaults will be used:
<Kind>Framework</Kind>
<SmartLink>true</SmartLink>
-->
</XcodeProjectReference>
</ItemGroup>

Expand Down
6 changes: 3 additions & 3 deletions facebook/sample/Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<ProjectReference Include="..\android\Facebook.Android.Binding\Facebook.Android.Binding.csproj" />
<!-- Include core facebook dependencies. Starting in .NET 9 these can potentially be replaced with @(AndroidMavenPackage) -->
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-android-sdk*.aar">
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-android-sdk-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-common*.aar">
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-common-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
<AndroidLibrary Include="..\android\native\mauifacebook\build\outputs\deps\facebook-core*.aar">
<AndroidLibrary Include="..\android\native\mauifacebook\bin\outputs\deps\facebook-core-17.0.0.aar">
<Bind>false</Bind>
<Visible>false</Visible>
</AndroidLibrary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
<SchemeName>MauiFirebase</SchemeName>
<SharpieNamespace>Firebase</SharpieNamespace>
<SharpieBind>true</SharpieBind>
<!-- Metadata applicable to @(NativeReference) will be used if set -->
<!-- Metadata applicable to @(NativeReference) will be used if set, otherwise the following defaults will be used:
<Kind>Framework</Kind>
<SmartLink>true</SmartLink>
-->
</XcodeProjectReference>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
<SchemeName>MauiGoogleCast</SchemeName>
<SharpieNamespace>GoogleCast</SharpieNamespace>
<SharpieBind>false</SharpieBind>
<!-- Metadata applicable to @(NativeReference) will be used if set -->
<!-- Metadata applicable to @(NativeReference) will be used if set, otherwise the following defaults will be used:
<Kind>Framework</Kind>
<SmartLink>true</SmartLink>
-->
</XcodeProjectReference>
</ItemGroup>

Expand All @@ -36,11 +37,11 @@
<GoogleCastiOSSdkUrl>https://github.com/react-native-google-cast/google-cast-sdk-dynamic-xcframework-no-bluetooth/archive/refs/tags/4.7.1.zip</GoogleCastiOSSdkUrl>
</PropertyGroup>

<DownloadFile SourceUrl="$(GoogleCastiOSSdkUrl)" DestinationFolder="$([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/build/deps))">
<DownloadFile SourceUrl="$(GoogleCastiOSSdkUrl)" DestinationFolder="$([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/bin/deps))">
<Output TaskParameter="DownloadedFile" ItemName="GoogleCastiOSSdkArchives" />
</DownloadFile>

<Exec Command="unzip -q -o -d $([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/build/deps)) @(GoogleCastiOSSdkArchives)" />
<Exec Command="unzip -q -o -d $([System.IO.Path]::GetFullPath($(MSBuildProjectDirectory)/../native/bin/deps)) @(GoogleCastiOSSdkArchives)" />
</Target>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
64B993472B97A71D00BAFB55 /* MauiGoogleCast.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MauiGoogleCast.framework; sourceTree = BUILT_PRODUCTS_DIR; };
64B9934A2B97A71D00BAFB55 /* MauiGoogleCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MauiGoogleCast.h; sourceTree = "<group>"; };
64B993562B97A7B300BAFB55 /* MauiGoogleCast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MauiGoogleCast.swift; sourceTree = "<group>"; };
D0A597A42C211EE600C52635 /* GoogleCast.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleCast.xcframework; path = "build/deps/google-cast-sdk-dynamic-xcframework-no-bluetooth-4.7.1/GoogleCast.xcframework"; sourceTree = "<group>"; };
D0A597A42C211EE600C52635 /* GoogleCast.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleCast.xcframework; path = "bin/deps/google-cast-sdk-dynamic-xcframework-no-bluetooth-4.7.1/GoogleCast.xcframework"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down
2 changes: 1 addition & 1 deletion nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<configuration>
<packageSources>
<add key="maui-binding-extensions" value="https://pkgs.dev.azure.com/xamarin/public/_packaging/maui-binding-extensions/nuget/v3/index.json" />
<!--add key="local" value="src/CommunityToolkit.Maui.BindingExtensions/bin/Release/" /-->
<add key="local" value="src/CommunityToolkit.Maui.BindingExtensions/bin/Release/" />
</packageSources>
</configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

<PropertyGroup>
<GradleProjectConfiguration Condition=" '$(GradleProjectConfiguration)' == '' ">Release</GradleProjectConfiguration>
<GradleProjectBuildDirectory Condition=" '$(GradleProjectBuildDirectory)' == '' ">bin</GradleProjectBuildDirectory>
</PropertyGroup>

<ItemDefinitionGroup>
Expand Down Expand Up @@ -32,8 +33,8 @@
<_GradleInputs Include="%(GradleProjectReference.FullPath)/**/*.gradle" />
<_GradleInputs Include="%(GradleProjectReference.FullPath)/**/*.xml" />
<_GradleInputs Include="%(GradleProjectReference.FullPath)/**/*.properties"/>
<_GradleInputs Remove="%(GradleProjectReference.FullPath)/%(GradleProjectReference.ModuleName)/build/**/*" />
<_GradleOutputs Include="@(GradleProjectReference->'%(FullPath)/%(ModuleName)/build/outputs/aar/%(ModuleName)-$(GradleProjectConfiguration).aar')" />
<_GradleInputs Remove="%(GradleProjectReference.FullPath)/%(GradleProjectReference.ModuleName)/$(GradleProjectBuildDirectory)/**/*" />
<_GradleOutputs Include="@(GradleProjectReference->'%(FullPath)/%(ModuleName)/$(GradleProjectBuildDirectory)/outputs/aar/%(ModuleName)-$(GradleProjectConfiguration).aar')" />
</ItemGroup>
</Target>

Expand All @@ -44,12 +45,12 @@
Inputs="@(_GradleInputs)"
Outputs="@(_GradleOutputs)" >

<RemoveDir Directories="@(GradleProjectReference->'%(FullPath)/%(ModuleName)/build/outputs')" />
<RemoveDir Directories="@(GradleProjectReference->'%(FullPath)/%(ModuleName)/$(GradleProjectBuildDirectory)/outputs')" />

<Gradle ToolPath="%(GradleProjectReference.FullPath)"
AndroidSdkDirectory="$(AndroidSdkDirectory)"
JavaSdkDirectory="$(JavaSdkDirectory)"
Arguments="%(GradleProjectReference.ModuleName):assemble$(GradleProjectConfiguration)"
Arguments="%(GradleProjectReference.ModuleName):assemble$(GradleProjectConfiguration) -Dorg.gradle.project.buildDir=$(GradleProjectBuildDirectory)"
WorkingDirectory="%(GradleProjectReference.FullPath)" >
</Gradle>

Expand All @@ -65,4 +66,21 @@
<Message Text="Adding reference to gradle project output: @(AndroidLibrary)" />
</Target>


<!-- Consider also moving native build outputs to $(IntermediateOutputDirectory) and using @(FileWrites) to clean -->
<PropertyGroup>
<CleanDependsOn>
$(CleanDependsOn);
_CleanGradleProjects;
</CleanDependsOn>
</PropertyGroup>

<Target Name="_CleanGradleProjects"
Condition=" '@(GradleProjectReference->Count())' != '0' " >
<Gradle ToolPath="%(GradleProjectReference.FullPath)"
Arguments="clean -Dorg.gradle.project.buildDir=$(GradleProjectBuildDirectory)"
WorkingDirectory="%(GradleProjectReference.FullPath)" >
</Gradle>
</Target>

</Project>
Loading

0 comments on commit bdf9b24

Please sign in to comment.