Skip to content
This repository has been archived by the owner on Oct 25, 2021. It is now read-only.

Commit

Permalink
[android] moved Xamarin.Android path logic to XamarinAndroid.cs
Browse files Browse the repository at this point in the history
- `FindDirectory` goes to `Helpers`
- Paths for Xamarin.Android go to `XamarinAndroid`
- Added a couple of smoke tests for `XamarinAndroid`
- Removed `RefreshAndroidSdk` in favor of static ctor on
`XamarinAndroid`
  • Loading branch information
jonathanpeppers committed Jul 6, 2017
1 parent f6641f2 commit 735629b
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 102 deletions.
93 changes: 9 additions & 84 deletions binder/Compilation.cs
Expand Up @@ -380,28 +380,8 @@ string GetJavaSdkPath()
return home;
}

bool initAndroidSdk = false;

void RefreshAndroidSdk()
{
if (Options.Compilation.Platform == TargetPlatform.Android)
{
if (!initAndroidSdk)
{
AndroidLogger.Info += AndroidLogger_Info;
AndroidLogger.Warning += AndroidLogger_Warning;
AndroidLogger.Error += AndroidLogger_Error;
initAndroidSdk = true;
}

AndroidSdk.Refresh();
}
}

bool CompileJava(IEnumerable<string> files)
{
RefreshAndroidSdk();

var executableSuffix = Platform.IsWindows ? ".exe" : string.Empty;
var javaSdk = GetJavaSdkPath();
var javac = Path.Combine(javaSdk, "bin", "javac" + executableSuffix);
Expand All @@ -417,7 +397,7 @@ bool CompileJava(IEnumerable<string> files)

var javaFiles = files.Select(file => Path.GetFullPath(file)).ToList();

var supportFiles = Directory.GetFiles(FindDirectory("support"), "*.java", SearchOption.AllDirectories)
var supportFiles = Directory.GetFiles(Helpers.FindDirectory("support"), "*.java", SearchOption.AllDirectories)
.Where(f => Options.Compilation.Platform == TargetPlatform.Android || Path.GetFileName(Path.GetDirectoryName(f)) != "android");
javaFiles.AddRange(supportFiles);

Expand Down Expand Up @@ -445,13 +425,13 @@ bool CompileJava(IEnumerable<string> files)
//Jar files needed: JNA, android.jar, mono.android.jar
args.Add("-cp");

var jnaJar = Path.Combine(FindDirectory("external"), "jna", "jna-4.4.0.jar");
var jnaJar = Path.Combine(Helpers.FindDirectory("external"), "jna", "jna-4.4.0.jar");
if (Options.Compilation.Platform == TargetPlatform.Android)
{
var maxVersion = AndroidSdk.GetInstalledPlatformVersions().Select(m => m.ApiLevel).Max();
var androidDir = AndroidSdk.GetPlatformDirectory(maxVersion);
var androidJar = Path.Combine(androidDir, "android.jar");
var monoAndroidJar = Path.Combine(GetMonoDroidPath(), "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroidBuild.TargetFrameworkVersion, "mono.android.jar");
var monoAndroidJar = Path.Combine(XamarinAndroid.Path, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion, "mono.android.jar");
var delimiter = Platform.IsWindows ? ";" : ":";
args.Add("\"" + string.Join(delimiter, jnaJar, androidJar, monoAndroidJar) + "\"");
}
Expand Down Expand Up @@ -528,7 +508,7 @@ bool CreateJar()
}

//Embed JNA into our jar file
using (var stream = File.OpenRead(Path.Combine(FindDirectory("external"), "jna", "jna-4.4.0.jar")))
using (var stream = File.OpenRead(Path.Combine(Helpers.FindDirectory("external"), "jna", "jna-4.4.0.jar")))
using (var zip = new ZipArchive(stream))
{
foreach (var entry in zip.Entries)
Expand Down Expand Up @@ -564,7 +544,7 @@ bool CreateJar()
//Embed mono.android.jar into our jar file
if (Options.Compilation.Platform == TargetPlatform.Android)
{
using (var stream = File.OpenRead(Path.Combine(GetMonoDroidPath(), "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroidBuild.TargetFrameworkVersion, "mono.android.jar")))
using (var stream = File.OpenRead(Path.Combine(XamarinAndroid.Path, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion, "mono.android.jar")))
using (var zip = new ZipArchive(stream))
{
foreach (var entry in zip.Entries)
Expand Down Expand Up @@ -604,8 +584,8 @@ bool CreateAar()
var classesDir = Path.Combine(Options.OutputDir, "classes");
var androidDir = Path.Combine(Options.OutputDir, "android");
var name = Path.GetFileNameWithoutExtension(Project.Assemblies[0]).Replace('-', '_');
var monoDroidPath = GetMonoDroidPath();
var monoDroidLibPath = GetMonoDroidLibPath();
var monoDroidPath = XamarinAndroid.Path;
var monoDroidLibPath = XamarinAndroid.LibraryPath;

var args = new List<string> {
"cvf",
Expand Down Expand Up @@ -637,7 +617,7 @@ bool CreateAar()
}

//Copy JNA native libs
foreach (var file in Directory.GetFiles(Path.Combine(FindDirectory("external"), "jna"), "android-*"))
foreach (var file in Directory.GetFiles(Path.Combine(Helpers.FindDirectory("external"), "jna"), "android-*"))
{
using (var stream = File.OpenRead(file))
using (var zip = new ZipArchive(stream))
Expand Down Expand Up @@ -725,34 +705,6 @@ bool MSBuild(string project)
return output.ExitCode == 0;
}

string FindDirectory(string dir)
{
for (int i = 0; i <= 3; i++)
{
if (Directory.Exists(dir))
return Path.GetFullPath(dir);

dir = Path.Combine("..", dir);
}

throw new Exception($"Cannot find {Path.GetFileName(dir)}!");
}

private void AndroidLogger_Info(string task, string message)
{
Diagnostics.Debug(message);
}

private void AndroidLogger_Warning(string task, string message)
{
Diagnostics.Warning(message);
}

private void AndroidLogger_Error(string task, string message)
{
Diagnostics.Error(message);
}

const string DLLExportDefine = "MONO_EMBEDDINATOR_DLL_EXPORT";

bool CompileMSVC(IEnumerable<string> files)
Expand Down Expand Up @@ -875,35 +827,8 @@ bool CompileClang(IEnumerable<string> files)
return output.ExitCode == 0;
}

string GetMonoDroidPath()
{
string external = Path.Combine(FindDirectory("external"), "Xamarin.Android");
if (Directory.Exists(external))
return external;

string binPath = MonoDroidSdk.BinPath;

//On Windows, it is generally correct, but probe for "lib"
if (File.Exists(Path.Combine(binPath, "lib")))
return Path.GetFullPath(MonoDroidSdk.BinPath);

//On Mac, it is up one directory from BinPath
return Path.GetFullPath(Path.Combine(MonoDroidSdk.BinPath, ".."));
}

string GetMonoDroidLibPath()
{
var basePath = GetMonoDroidPath();
var libPath = Path.Combine(basePath, "lib", "xbuild", "Xamarin", "Android", "lib");
if (!Directory.Exists(libPath))
libPath = Path.Combine(basePath, "lib");
return libPath;
}

bool CompileNDK(IEnumerable<string> files)
{
RefreshAndroidSdk();

var monoPath = Path.Combine(ManagedToolchain.FindMonoPath(), "include", "mono-2.0");
var name = Path.GetFileNameWithoutExtension(Project.Assemblies[0]);
var libName = $"lib{name}.so";
Expand Down Expand Up @@ -939,7 +864,7 @@ bool CompileNDK(IEnumerable<string> files)

var clangBin = NdkUtil.GetNdkClangBin(Path.Combine(ndkPath, "toolchains"), targetArch);
var systemInclude = NdkUtil.GetNdkPlatformIncludePath(ndkPath, targetArch, 24); //NOTE: 24 should be an option?
var monoDroidPath = Path.Combine(GetMonoDroidLibPath(), abi);
var monoDroidPath = Path.Combine(XamarinAndroid.LibraryPath, abi);
var abiDir = Path.Combine(Options.OutputDir, "android", "jni", abi);
var outputPath = Path.Combine(abiDir, libName);

Expand Down
8 changes: 3 additions & 5 deletions binder/Driver.cs
Expand Up @@ -51,9 +51,9 @@ bool Parse()
var parser = new Parser();
if (Options.Compilation.Platform == TargetPlatform.Android)
{
var monoDroidPath = GetMonoDroidPath();
var monoDroidPath = XamarinAndroid.Path;
parser.AddAssemblyResolveDirectory(Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0"));
parser.AddAssemblyResolveDirectory(Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v2.3"));
parser.AddAssemblyResolveDirectory(Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion));
}

parser.OnAssemblyParsed += HandleAssemblyParsed;
Expand Down Expand Up @@ -198,10 +198,8 @@ bool WriteFiles()
ca => ca.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute" &&
ca.ConstructorArguments.FirstOrDefault().Value.ToString().StartsWith("MonoAndroid,", StringComparison.Ordinal))))
{
RefreshAndroidSdk();

Diagnostics.Message("Generating Java stubs...");
var project = XamarinAndroidBuild.GenerateJavaStubsProject(Assemblies, GetMonoDroidPath(), Options.OutputDir);
var project = XamarinAndroidBuild.GenerateJavaStubsProject(Assemblies, XamarinAndroid.Path, Options.OutputDir);
if (!MSBuild(project))
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion binder/Utils/ResourceDesignerGenerator.cs
Expand Up @@ -163,7 +163,7 @@ public bool WriteAssembly()
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0", "System.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0", "Facades", "System.Runtime.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0", "Java.Interop.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroidBuild.TargetFrameworkVersion, "Mono.Android.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion, "Mono.Android.dll"));
parameters.ReferencedAssemblies.Add(MainAssembly);

var results = csc.CompileAssemblyFromDom(parameters, unit);
Expand Down
13 changes: 13 additions & 0 deletions binder/Utils/Utils.cs
Expand Up @@ -71,5 +71,18 @@ public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
CopyAll(sourceSubDir, nextTargetSubDir);
}
}

public static string FindDirectory(string dir)
{
for (int i = 0; i <= 3; i++)
{
if (Directory.Exists(dir))
return Path.GetFullPath(dir);

dir = Path.Combine("..", dir);
}

throw new Exception($"Cannot find {Path.GetFileName(dir)}!");
}
}
}
80 changes: 80 additions & 0 deletions binder/Utils/XamarinAndroid.cs
@@ -0,0 +1,80 @@
using System;
using System.IO;
using CppSharp;
using Xamarin.Android.Tools;
using static System.IO.Path;

namespace MonoEmbeddinator4000
{
/// <summary>
/// Contains various path logic for Xamarin.Android
/// </summary>
static class XamarinAndroid
{
public const string TargetFrameworkVersion = "v2.3";
public const string MinSdkVersion = "9";
public const string TargetSdkVersion = "25";

static XamarinAndroid()
{
AndroidLogger.Info += AndroidLogger_Info;
AndroidLogger.Warning += AndroidLogger_Warning;
AndroidLogger.Error += AndroidLogger_Error;

AndroidSdk.Refresh();
}

static void AndroidLogger_Info(string task, string message)
{
Diagnostics.Debug(message);
}

static void AndroidLogger_Warning(string task, string message)
{
Diagnostics.Warning(message);
}

static void AndroidLogger_Error(string task, string message)
{
Diagnostics.Error(message);
}

static string GetMonoDroidPath()
{
string external = Combine(Helpers.FindDirectory("external"), "Xamarin.Android");
if (Directory.Exists(external))
return external;

string binPath = MonoDroidSdk.BinPath;

//On Windows, it is generally correct, but probe for "lib"
if (File.Exists(Combine(binPath, "lib")))
return GetFullPath(MonoDroidSdk.BinPath);

//On Mac, it is up one directory from BinPath
return GetFullPath(Combine(MonoDroidSdk.BinPath, ".."));
}

static string GetMonoDroidLibPath()
{
var libPath = Combine(Path, "lib", "xbuild", "Xamarin", "Android", "lib");
if (!Directory.Exists(libPath))
libPath = Combine(Path, "lib");
return libPath;
}

static Lazy<string> path = new Lazy<string>(GetMonoDroidPath);

public static string Path
{
get { return path.Value; }
}

static Lazy<string> libraryPath = new Lazy<string>(GetMonoDroidLibPath);

public static string LibraryPath
{
get { return libraryPath.Value; }
}
}
}
21 changes: 10 additions & 11 deletions binder/Utils/XamarinAndroidBuild.cs
Expand Up @@ -7,12 +7,12 @@
using Xamarin.Android.Tools;

namespace MonoEmbeddinator4000
{
{
/// <summary>
/// Contains everything MSBuild-related for Xamarin.Android
/// </summary>
static class XamarinAndroidBuild
{
public const string TargetFrameworkVersion = "v2.3";
public const string MinSdkVersion = "9";
public const string TargetSdkVersion = "25";
{
const string LinkMode = "SdkOnly";

static ProjectRootElement CreateProject(string monoDroidPath)
Expand All @@ -25,7 +25,7 @@ static ProjectRootElement CreateProject(string monoDroidPath)
project.AddProperty("TargetFrameworkDirectory", string.Join(";",
Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0"),
Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0", "Facades"),
Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", TargetFrameworkVersion)));
Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion)));
project.AddImport(ProjectCollection.Escape(Path.Combine(msBuildPath, "Xamarin.Android.CSharp.targets")));

return project;
Expand All @@ -34,7 +34,7 @@ static ProjectRootElement CreateProject(string monoDroidPath)
static void ResolveAssemblies(ProjectTargetElement target, string monoDroidPath, string mainAssembly)
{
//NOTE: [Export] requires Mono.Android.Export.dll
string monoAndroidExport = Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", TargetFrameworkVersion, "Mono.Android.Export.dll");
string monoAndroidExport = Path.Combine(monoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion, "Mono.Android.Export.dll");

var resolveAssemblies = target.AddTask("ResolveAssemblies");
resolveAssemblies.SetParameter("Assemblies", mainAssembly + ";" + monoAndroidExport);
Expand All @@ -45,7 +45,6 @@ static void ResolveAssemblies(ProjectTargetElement target, string monoDroidPath,
resolveAssemblies.AddOutputItem("ResolvedFrameworkAssemblies", "ResolvedFrameworkAssemblies");
}



/// <summary>
/// Generates a Package.proj file for MSBuild to invoke
Expand Down Expand Up @@ -137,7 +136,7 @@ public static string GeneratePackageProject(List<IKVM.Reflection.Assembly> assem
aapt.SetParameter("ResourceDirectory", resourceDir);
aapt.SetParameter("ToolPath", AndroidSdk.GetBuildToolsPaths().First());
aapt.SetParameter("ToolExe", "aapt");
aapt.SetParameter("ApiLevel", TargetSdkVersion);
aapt.SetParameter("ApiLevel", XamarinAndroid.TargetSdkVersion);
aapt.SetParameter("ExtraArgs", "--output-text-symbols " + androidDir);

//There is an extra /manifest/AndroidManifest.xml file created
Expand Down Expand Up @@ -165,7 +164,7 @@ public static void GenerateAndroidManifest(List<IKVM.Reflection.Assembly> assemb
File.WriteAllText(path,
$@"<?xml version=""1.0"" encoding=""utf-8""?>
<manifest xmlns:android=""http://schemas.android.com/apk/res/android"" package=""com.{name}_dll"">
<uses-sdk android:minSdkVersion=""{MinSdkVersion}"" android:targetSdkVersion=""{TargetSdkVersion}"" />
<uses-sdk android:minSdkVersion=""{XamarinAndroid.MinSdkVersion}"" android:targetSdkVersion=""{XamarinAndroid.TargetSdkVersion}"" />
<application>
<meta-data android:name=""mono.embeddinator.mainassembly"" android:value=""{name}"" />
{provider}
Expand Down Expand Up @@ -206,7 +205,7 @@ public static string GenerateJavaStubsProject(List<IKVM.Reflection.Assembly> ass
generateJavaStubs.SetParameter("ResolvedUserAssemblies", "@(ResolvedUserAssemblies)");
generateJavaStubs.SetParameter("ManifestTemplate", manifestPath);
generateJavaStubs.SetParameter("MergedAndroidManifestOutput", manifestPath);
generateJavaStubs.SetParameter("AndroidSdkPlatform", TargetSdkVersion); //TODO: should be an option
generateJavaStubs.SetParameter("AndroidSdkPlatform", XamarinAndroid.TargetSdkVersion); //TODO: should be an option
generateJavaStubs.SetParameter("AndroidSdkDir", AndroidSdk.AndroidSdkPath);
generateJavaStubs.SetParameter("OutputDirectory", outputDirectory);
generateJavaStubs.SetParameter("ResourceDirectory", "$(MonoAndroidResDirIntermediate)");
Expand Down
3 changes: 3 additions & 0 deletions build/projects/MonoEmbeddinator4000.csproj
Expand Up @@ -156,6 +156,9 @@
<Compile Include="../../binder/Utils/Utils.cs">
<Link>binder/Utils/Utils.cs</Link>
</Compile>
<Compile Include="../../binder/Utils/XamarinAndroid.cs">
<Link>binder/Utils/XamarinAndroid.cs</Link>
</Compile>
<Compile Include="../../binder/Utils/XamarinAndroidBuild.cs">
<Link>binder/Utils/XamarinAndroidBuild.cs</Link>
</Compile>
Expand Down
2 changes: 1 addition & 1 deletion tests/MonoEmbeddinator4000Tests/Helpers/Samples.cs
Expand Up @@ -37,7 +37,7 @@ public static Assembly LoadFile(string resourceFile)
OutputAssembly = temp,
};
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", "v1.0", "System.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroidBuild.TargetFrameworkVersion, "Mono.Android.dll"));
parameters.ReferencedAssemblies.Add(Path.Combine(MonoDroidPath, "lib", "xbuild-frameworks", "MonoAndroid", XamarinAndroid.TargetFrameworkVersion, "Mono.Android.dll"));

var results = csc.CompileAssemblyFromSource(parameters, source);

Expand Down

0 comments on commit 735629b

Please sign in to comment.