[mono] Use "dotnet publish" for Android sample with ILLink (#36593)
authorEgor Bogatov <egorbo@gmail.com>
Sat, 16 May 2020 13:15:56 +0000 (16:15 +0300)
committerGitHub <noreply@github.com>
Sat, 16 May 2020 13:15:56 +0000 (16:15 +0300)
docs/workflow/testing/libraries/testing-android.md
src/mono/mono.proj
src/mono/netcore/sample/Android/Makefile
src/mono/netcore/sample/Android/Program.csproj
tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.cs
tools-local/tasks/mobile.tasks/AndroidAppBuilder/ApkBuilder.cs
tools-local/tasks/mobile.tasks/AppleAppBuilder/Templates/CMakeLists.txt.template

index 4c32cd4..7ac22f8 100644 (file)
@@ -36,13 +36,13 @@ fi
 # download Android NDK
 export ANDROID_NDK_ROOT=~/android-ndk-${NDK_VER}
 curl https://dl.google.com/android/repository/android-ndk-${NDK_VER}-${HOST_OS}-x86_64.zip -L --output ~/andk.zip
-unzip ~/andk.zip -o -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip
+unzip ~/andk.zip -d $(dirname ${ANDROID_NDK_ROOT}) && rm -rf ~/andk.zip
 
 # download Android SDK, accept licenses and download additional packages such as
 # platform-tools, platforms and build-tools
 export ANDROID_SDK_ROOT=~/android-sdk
 curl https://dl.google.com/android/repository/commandlinetools-${HOST_OS_SHORT}-${SDK_VER}.zip -L --output ~/asdk.zip
-unzip ~/asdk.zip -o -d ${ANDROID_SDK_ROOT} && rm -rf ~/asdk.zip
+unzip ~/asdk.zip -d ${ANDROID_SDK_ROOT} && rm -rf ~/asdk.zip
 yes | ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --licenses
 ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platform-tools" "platforms;android-${SDK_API_LEVEL}" "build-tools;${SDK_BUILD_TOOLS}"
 
@@ -50,10 +50,10 @@ ${ANDROID_SDK_ROOT}/tools/bin/./sdkmanager --sdk_root=${ANDROID_SDK_ROOT} "platf
 # and will be removed once we figure out how to integrate OpenSSL properly as a dependency
 export ANDROID_OPENSSL_AAR=~/openssl-android
 curl https://maven.google.com/com/android/ndk/thirdparty/openssl/${OPENSSL_VER}/openssl-${OPENSSL_VER}.aar -L --output ~/openssl.zip
-unzip ~/openssl.zip -o -d ${ANDROID_OPENSSL_AAR} && rm -rf ~/openssl.zip
+unzip ~/openssl.zip -d ${ANDROID_OPENSSL_AAR} && rm -rf ~/openssl.zip
 printf "\n\nexport ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT}\nexport ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}\nexport ANDROID_OPENSSL_AAR=${ANDROID_OPENSSL_AAR}\n" >> ${BASHRC}
 ```
-Make sure `ANDROID_NDK_ROOT`, `ANDROID_SDK_ROOT` and `ANDROID_OPENSSL_AAR` environment variables are accessible and point to correct locations.
+Save it to a file (e.g. `deps.sh`) and execute using `source` (e.g. `chmod +x deps.sh && source ./deps.sh`) in order to propogate the `ANDROID_NDK_ROOT`, `ANDROID_SDK_ROOT` and `ANDROID_OPENSSL_AAR` environment variables to the current process.
 
 ## Building Libs and Tests for Android
 
index 83ddd98..3951191 100644 (file)
 
     <!-- Release specific options -->
     <ItemGroup Condition="'$(Configuration)' == 'Release'">
-      <_MonoCFLAGS Include="-O2" />
+      <_MonoCFLAGS Include="-O2" Condition="'$(TargetsMobile)' != 'true'" />
+      <_MonoCFLAGS Include="-Os" Condition="'$(TargetsMobile)' == 'true'" />
       <_MonoCFLAGS Include="-g" />
+      <_MonoCFLAGS Include="-Wl,-s" Condition="'$(TargetsAndroid)' == 'true'" />
 
-      <_MonoCXXFLAGS Include="-O2" />
+      <_MonoCXXFLAGS Include="-O2" Condition="'$(TargetsMobile)' != 'true'" />
+      <_MonoCXXFLAGS Include="-Os" Condition="'$(TargetsMobile)' == 'true'" />
       <_MonoCXXFLAGS Include="-g" />
     </ItemGroup>
 
index 898c8cf..32d038d 100644 (file)
@@ -1,18 +1,18 @@
-MONO_CONFIG=Debug
+MONO_CONFIG=Release
 MONO_ARCH=arm64
 DOTNET := ../../../../.././dotnet.sh
 
-#export ANDROID_NDK_ROOT=/path/to/android/ndk
-#export ANDROID_SDK_ROOT=/path/to/android/sdk
+all: runtimepack apk
 
-all: bundle
+appbuilder:
+       $(DOTNET) build -c Release ../../../../../tools-local/tasks/mobile.tasks/AndroidAppBuilder/AndroidAppBuilder.csproj
 
-bundle: clean
-       $(DOTNET) build -c $(MONO_CONFIG) Program.csproj
-       $(DOTNET) msbuild /t:BuildAppBundle /p:Configuration=$(MONO_CONFIG) /p:TargetArchitecture=$(MONO_ARCH)
+runtimepack:
+       ../../../../.././build.sh Mono+Libs -os Android -arch $(MONO_ARCH) -c $(MONO_CONFIG)
 
-deploy-launch: bundle
-       $(DOTNET) msbuild /t:ReinstallAndLaunch
+apk: clean appbuilder
+       $(DOTNET) publish -c Release -r android-$(MONO_ARCH) \
+       /p:Platform=$(MONO_ARCH) /p:DeployAndRun=true
 
 clean:
        rm -rf bin
index 600ac6d..d7516dc 100644 (file)
@@ -4,71 +4,63 @@
     <OutputPath>bin</OutputPath>
     <DebugType>Portable</DebugType>
     <TargetFramework>$(NetCoreAppCurrent)</TargetFramework>
-    <TargetArchitecture Condition="'$(TargetArchitecture)'==''">x64</TargetArchitecture>
     <RuntimePackDir>$(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(TargetArchitecture)\runtimes\android-$(TargetArchitecture)</RuntimePackDir>
-    <BundleDir>$(MSBuildThisFileDirectory)\bin\bundle</BundleDir>
     <AndroidAppBuilderDir>$([MSBuild]::NormalizeDirectory('$(ArtifactsBinDir)', 'AndroidAppBuilder', 'Debug', '$(NetCoreAppCurrent)'))</AndroidAppBuilderDir>
-
+    <EnableTargetingPackDownload>false</EnableTargetingPackDownload>
+    <PublishTrimmed>true</PublishTrimmed>
+    <_TrimmerDefaultAction>link</_TrimmerDefaultAction>
   </PropertyGroup>
 
-  <Target Name="RebuildAndroidAppBuilder">
-    <MSBuild Projects="$(AndroidAppBuilderProjDirectory)\AndroidAppBuilder.csproj"
-             Properties="Configuration=$(Configuration);Platform=$(HostArch)" Targets="Restore;Build" />
+  <!-- Redirect 'dotnet publish' to in-tree runtime pack -->
+  <Target Name="TrickRuntimePackLocation" AfterTargets="ProcessFrameworkReferences">
+    <ItemGroup>
+      <RuntimePack>
+        <PackageDirectory>$(ArtifactsDir)bin\lib-runtime-packs\$(NetCoreAppCurrent)-Android-$(Configuration)-$(Platform)</PackageDirectory>
+      </RuntimePack>
+    </ItemGroup>
+    <Message Text="Packaged ID: %(RuntimePack.PackageDirectory)" Importance="high" />
   </Target>
 
   <UsingTask TaskName="AndroidAppBuilderTask"
              AssemblyFile="$(AndroidAppBuilderDir)\AndroidAppBuilder.dll" />
 
-  <Target Name="BuildAppBundle" DependsOnTargets="RebuildAndroidAppBuilder">
+  <!-- Build APK during 'dotnet publish' -->
+  <Target Name="BuildAppBundle" AfterTargets="CopyFilesToPublishDirectory">
     <PropertyGroup>
-      <AndroidAbi Condition="'$(TargetArchitecture)'=='arm64'">arm64-v8a</AndroidAbi>
-      <AndroidAbi Condition="'$(TargetArchitecture)'=='arm'">armeabi-v7a</AndroidAbi>
-      <AndroidAbi Condition="'$(TargetArchitecture)'=='x64'">x86_64</AndroidAbi>
-      <AndroidAbi Condition="'$(AndroidAbi)'==''">$(TargetArchitecture)</AndroidAbi>
+      <AndroidAbi Condition="'$(Platform)'=='arm64'">arm64-v8a</AndroidAbi>
+      <AndroidAbi Condition="'$(Platform)'=='arm'">armeabi-v7a</AndroidAbi>
+      <AndroidAbi Condition="'$(Platform)'=='x64'">x86_64</AndroidAbi>
+      <AndroidAbi Condition="'$(AndroidAbi)'==''">$(Platform)</AndroidAbi>
+      <ApkDir>$(MSBuildThisFileDirectory)$(PublishDir)\apk</ApkDir>
+      <StripDebugSymbols>False</StripDebugSymbols>
+      <StripDebugSymbols Condition="'$(Configuration)' == 'Release'">True</StripDebugSymbols>
+      <AdbTool>$(ANDROID_SDK_ROOT)\platform-tools\adb</AdbTool>
     </PropertyGroup>
-    <ItemGroup>
-      <AppBinaries Include="bin\*.*"/>
-      <BclBinaries Include="$(RuntimePackDir)\lib\$(NetCoreAppCurrent)\*.*" 
-                   Exclude="$(RuntimePackDir)\lib\$(NetCoreAppCurrent)\System.Runtime.WindowsRuntime.dll" />
-      <BclBinaries Include="$(RuntimePackDir)\native\*.*" />
-    </ItemGroup>
-    <Error Condition="'$(AndroidAbi)'==''" Text="Unknown $(TargetArchitecture)" />
-    <Error Condition="!Exists('$(RuntimePackDir)')" Text="RuntimePackDir=$(RuntimePackDir) doesn't exist" />
-    <RemoveDir Directories="$(BundleDir)" />
-    <Copy SourceFiles="@(AppBinaries)" DestinationFolder="$(BundleDir)" SkipUnchangedFiles="true"/>
-    <Copy SourceFiles="@(BclBinaries)" DestinationFolder="$(BundleDir)\%(RecursiveDir)" SkipUnchangedFiles="true"/>
 
-    <!-- TEMP: consume OpenSSL binaries from external sources via env. variables -->
-    <Copy Condition="'$(ANDROID_OPENSSL_AAR)' != ''"
-          SourceFiles="$(ANDROID_OPENSSL_AAR)\prefab\modules\crypto\libs\android.$(AndroidAbi)\libcrypto.so"
-          DestinationFolder="$(BundleDir)" SkipUnchangedFiles="true"/>
-    <Copy Condition="'$(ANDROID_OPENSSL_AAR)' != ''"
-          SourceFiles="$(ANDROID_OPENSSL_AAR)\prefab\modules\ssl\libs\android.$(AndroidAbi)\libssl.so"
-          DestinationFolder="$(BundleDir)" SkipUnchangedFiles="true"/>
+    <RemoveDir Directories="$(ApkDir)" />
 
-    <AndroidAppBuilderTask 
+    <!-- These native libs are not needed for HelloWorld
+         and can be deleted to save 0.4 Mb for APK size -->
+    <Delete Files="$(PublishDir)\libSystem.IO.Compression.Native.so" />
+    <Delete Files="$(PublishDir)\libSystem.Security.Cryptography.Native.OpenSsl.so" />
+
+    <AndroidAppBuilderTask
         Abi="$(AndroidAbi)"
         ProjectName="HelloAndroid"
-        MonoRuntimeHeaders="$(RuntimePackDir)\native\include\mono-2.0"
+        MonoRuntimeHeaders="%(ResolvedRuntimePack.PackageDirectory)\runtimes\android-$(Platform)\native\include\mono-2.0"
         MainLibraryFileName="Program.dll"
-        SourceDir="$(BundleDir)"
-        OutputDir="$(BundleDir)\apk">
+        StripDebugSymbols="$(StripDebugSymbols)"
+        SourceDir="$(MSBuildThisFileDirectory)$(PublishDir)"
+        OutputDir="$(ApkDir)">
         <Output TaskParameter="ApkBundlePath" PropertyName="ApkBundlePath" />
         <Output TaskParameter="ApkPackageId" PropertyName="ApkPackageId" />
     </AndroidAppBuilderTask>
     <Message Importance="High" Text="Apk:       $(ApkBundlePath)"/>
     <Message Importance="High" Text="PackageId: $(ApkPackageId)"/>
-  </Target>
 
-  <!-- Deploy and launch on an active emulator or device -->
-  <Target Name="ReinstallAndLaunch">
-    <PropertyGroup>
-      <AdbTool>$(ANDROID_SDK_ROOT)\platform-tools\adb</AdbTool>
-    </PropertyGroup>
-    <Message Importance="High" Text="Uninstalling app if it exists (throws an error if it doesn't but it can be ignored):"/>
-    <Exec Command="$(AdbTool) uninstall net.dot.HelloAndroid" ContinueOnError="WarnAndContinue" />
-    <Exec Command="$(AdbTool) install bin/bundle/apk/bin/HelloAndroid.apk" />
-    <Exec Command="$(AdbTool) shell am instrument -w net.dot.HelloAndroid/net.dot.MonoRunner" />
-    <!--Exec Command="$(AdbTool) logcat" /-->
+    <Message Condition="'$(DeployAndRun)' == 'true'" Importance="High" Text="Uninstalling app if it exists (throws an error if it doesn't but it can be ignored):"/>
+    <Exec Condition="'$(DeployAndRun)' == 'true'" Command="$(AdbTool) uninstall net.dot.HelloAndroid" ContinueOnError="WarnAndContinue" />
+    <Exec Condition="'$(DeployAndRun)' == 'true'" Command="$(AdbTool) install $(ApkDir)/bin/HelloAndroid.apk" />
+    <Exec Condition="'$(DeployAndRun)' == 'true'" Command="$(AdbTool) shell am instrument -w net.dot.HelloAndroid/net.dot.MonoRunner" />
   </Target>
 </Project>
index cc915ae..baaa1c7 100644 (file)
@@ -22,7 +22,7 @@ public class AndroidAppBuilderTask : Task
     public string MainLibraryFileName { get; set; } = ""!;
 
     /// <summary>
-    /// Target arch, can be 'x86', 'x86_64', 'armeabi', 'armeabi-v7a' or 'arm64-v8a'
+    /// Target arch, can be 'x86', 'x86_64', 'armeabi-v7a' or 'arm64-v8a'
     /// </summary>
     [Required]
     public string Abi { get; set; } = ""!;
index 4330c74..b252a46 100644 (file)
@@ -23,7 +23,7 @@ public class ApkBuilder
             throw new ArgumentException($"sourceDir='{sourceDir}' is empty or doesn't exist");
 
         if (string.IsNullOrEmpty(abi))
-            throw new ArgumentException("abi shoudln't be empty (e.g. x86, x86_64, armeabi, armeabi-v7a or arm64-v8a");
+            throw new ArgumentException("abi shoudln't be empty (e.g. x86, x86_64, armeabi-v7a or arm64-v8a");
 
         if (string.IsNullOrEmpty(entryPointLib))
             throw new ArgumentException("entryPointLib shouldn't be empty");