FAKE, the F# Make with Android and Xamarin What's FAKE? Fake is a DSL permitting to write advanced automated builds in FSharp. It can be used by beginners in FSharp because the DSL can hide some FSharp code comlexity. We can define multiple targets like in a Makefile. For example: letbuildDir ="./build/" Target"Clean"(fun_-> trace"cleaning ..." CleanDirbuildDir ) Target"Packages"(fun_-> trace"Restoring nugets" RestorePackages() ) Target"Compile"(fun_-> MSBuildReleaseandroidBuildDir"Build"!!"src/**/*.csproj" |>Log"AppBuild-Output: " // We use MSBuild and XBuild for .net projects but we can extend the DSL to use everything else ) Target"Tests"(fun_-> // we can run the unit tests ... ) Target"Install"(fun_-> // if we use an integration server, we can deploy the project // but we can also install an app like a classic "make install" buildDir |>directoryInfo |>filesInDir |>Seq.map (funf->f.FullName) |>CopyFiles ProgramFilesX86 ) // define the target ordering and dependencies "Clean" ==>"Packages" ==>"Compile" ==>"Tests" ==>"Install" // if no target is specified in args, we run "Install" RunTargetOrDefault"Install" Build an APK with FAKE Build and publish a simple APK Fake contains the XamarinHelper module helping developers to script their APK building. There is also the AndroidPublisher module permitting to upload the APK on the Google Play Store.
trace"cleaning ..." CleanDirbuildDir ) Target"Packages"(fun_-> trace"Restoring nugets" RestorePackages() ) Target"Compile"(fun_-> MSBuildReleaseandroidBuildDir"Build"!!"src/**/*.csproj" |>Log"AppBuild-Output: " // We use MSBuild and XBuild for .net projects but we can extend the DSL to use everything else ) Target"Tests"(fun_-> // we can run the unit tests ... ) Target"Install"(fun_-> // if we use an integration server, we can deploy the project // but we can also install an app like a classic "make install" buildDir |>directoryInfo |>filesInDir |>Seq.map (funf->f.FullName) |>CopyFiles ProgramFilesX86 ) // define the target ordering and dependencies "Clean" ==>"Packages" ==>"Compile" ==>"Tests" ==>"Install" // if no target is specified in args, we run "Install" RunTargetOrDefault"Install" Build an APK with FAKE Build and publish a simple APK Fake contains the XamarinHelper module helping developers to script their APK building. There is also the AndroidPublisher module permitting to upload the APK on the Google Play Store." />
FAKE, the F# Make with Android and Xamarin
What's FAKE?
Fake is a DSL permitting to write advanced automated builds in FSharp.
It can be used by beginners in FSharp because the DSL can hide some FSharp code comlexity.
We can define multiple targets like in a Makefile.
For example:
letbuildDir ="./build/"Target"Clean"(fun_-> trace"cleaning ..." CleanDir buildDir ) Target"Packages"(fun_-> trace"Restoring nugets" RestorePackages() ) Target"Compile"(fun_-> MSBuildRelease androidBuildDir"Build"!!"src/**/*.csproj" |> Log"AppBuild-Output: "// We use MSBuild and XBuild for .net projects but we can extend the DSL to use everything else) Target"Tests"(fun_->// we can run the unit tests ...) Target"Install"(fun_->// if we use an integration server, we can deploy the project// but we can also install an app like a classic "make install" buildDir |> directoryInfo |> filesInDir |> Seq.map (funf->f.FullName) |> CopyFiles ProgramFilesX86 ) // define the target ordering and dependencies"Clean" ==>"Packages" ==>"Compile" ==>"Tests" ==>"Install"// if no target is specified in args, we run "Install"RunTargetOrDefault"Install"
Build an APK with FAKE
Build and publish a simple APK
Fake contains the XamarinHelper module helping developers to script their APK building.
There is also the AndroidPublisher module permitting to upload the APK on the Google Play Store.
In the following sample, we can build Apk with the default target and publish them with the ͞Puďlish͟ target.
Usage Fake.exe"build.fsx "target=publish"
#r"packages/FAKE/tools/FakeLib.dll"letandroidBuildDir ="./build/"letandroidProdDir ="./pack/"androidProdDir |> ensureDirectory //Clean old apkTarget"Clean"(fun_-> CleanDir androidBuildDir CleanDir androidProdDir ) Target"Android-Package"(fun()-> AndroidPackage(fundefaults-> { defaultswith ProjectPath ="Path to my project Droid.csproj" Configuration ="Release" OutputPath = androidBuildDir Properties = ["MSBuild property","MSBuild property value"] }) |> AndroidSignAndAlign (fundefaults-> { defaultswith KeystorePath =@"path to my file.keystore" KeystorePassword ="my password" KeystoreAlias ="my key alias" }) |>funfile->file.CopyTo(Path.Combine(androidProdDir, file.Name)) |> ignore ) Target"Publish"(fun_->// I like verbose script trace"publishing Android App"letapk=androidProdDir |> directoryInfo |> filesInDir |>Seq.filter(funf->f.Name.EndsWith(".apk")) |>Seq.exactlyOne letapkPath = apk.FullName tracefn"Apk found: %s"apkPath letmail ="my service account mail@developer.gserviceaccount.com"-// Path to the certificate file probably named 'Google Play Android Developer xxxxxxxxxxxx.p12'
I modified XamarinHelper to give the possibility to specify ABI target when using AndroidPackage.
As described inhttp://developer.xamarin.com/guides/android/advanced_topics/build-abi-specific-apks/, multiple APK support is good for reduce the size of the APK and support different CPU architectures.
I͛ŵ Ŷot faŶ of edžĐessivelLJ Đoŵpledž versioŶ Đode geŶeratioŶ.I published some applications using a simpliest method. I just increment of 1 each ABI version code.
Google imposes only one constraint:
We must respect the order x86 < x86_64 < ArmEabi < ArmEabiV7a < Arm64V8a.
For example, if your debug version code is 5, your APKS͚s versioŶ Đodesshould be:
-----
5 for MyApp-X86.apk 6 for MyApp-X86_64.apk 7 for MyApp-armeabi.apk 8 for MyApp- armeabi-v7.apk 9 for MyApp- armeabiv64-v8a.apk
The next built script example is use forhttps://bitbucket.org/rflechner/sokoban/overview