Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class GenerateNativeApplicationConfigSources : AndroidTask
public bool EmitLlvmIrComments { get; set; }

public bool AndroidEnableAssemblyStoreDecompressionCache { get; set; }
public bool SkipJniAddNativeMethodRegistrationAttributeScan { get; set; }
public string? RuntimeConfigBinFilePath { get; set; }
public string ProjectRuntimeConfigFilePath { get; set; } = String.Empty;
public string? ProjectRuntimeConfigDevFilePath { get; set; }
Expand Down Expand Up @@ -271,6 +272,9 @@ static bool ShouldSkipAssembly (ITaskItem assembly)
}

bool haveRuntimeConfigBlob = !String.IsNullOrEmpty (RuntimeConfigBinFilePath) && File.Exists (RuntimeConfigBinFilePath);
bool jniAddNativeMethodRegistrationAttributePresent =
SkipJniAddNativeMethodRegistrationAttributeScan ||
NativeCodeGenState.TemplateJniAddNativeMethodRegistrationAttributePresent;
var jniRemappingNativeCodeInfo = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfo> (ProjectSpecificTaskObjectKey (GenerateJniRemappingNativeCode.JniRemappingNativeCodeInfoKey), RegisteredTaskObjectLifetime.Build);
LLVMIR.LlvmIrComposer appConfigAsmGen;

Expand All @@ -280,7 +284,7 @@ static bool ShouldSkipAssembly (ITaskItem assembly)
UsesAssemblyPreload = envBuilder.Parser.UsesAssemblyPreload,
AndroidPackageName = AndroidPackageName,
PackageNamingPolicy = pnp,
JniAddNativeMethodRegistrationAttributePresent = NativeCodeGenState.TemplateJniAddNativeMethodRegistrationAttributePresent,
JniAddNativeMethodRegistrationAttributePresent = jniAddNativeMethodRegistrationAttributePresent,
NumberOfAssembliesInApk = assemblyCount,
BundledAssemblyNameWidth = assemblyNameWidth,
NativeLibraries = uniqueNativeLibraries,
Expand All @@ -307,7 +311,7 @@ static bool ShouldSkipAssembly (ITaskItem assembly)
BrokenExceptionTransitions = envBuilder.Parser.BrokenExceptionTransitions,
PackageNamingPolicy = pnp,
BoundExceptionType = boundExceptionType,
JniAddNativeMethodRegistrationAttributePresent = NativeCodeGenState.TemplateJniAddNativeMethodRegistrationAttributePresent,
JniAddNativeMethodRegistrationAttributePresent = jniAddNativeMethodRegistrationAttributePresent,
HaveRuntimeConfigBlob = haveRuntimeConfigBlob,
NumberOfAssembliesInApk = assemblyCount,
BundledAssemblyNameWidth = assemblyNameWidth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -967,7 +967,9 @@ module Xamarin.Android.Tests
}

[Test]
public void DesignTimeBuildHasAndroidDefines ([Values (AndroidRuntime.CoreCLR, AndroidRuntime.NativeAOT)] AndroidRuntime runtime)
public void DesignTimeBuildHasAndroidDefines (
[Values (AndroidRuntime.CoreCLR, AndroidRuntime.NativeAOT)] AndroidRuntime runtime,
[Values (false, true)] bool disableImplicitFrameworkDefines)
{
bool isRelease = runtime == AndroidRuntime.NativeAOT;
if (IgnoreUnsupportedConfiguration (runtime, release: isRelease)) {
Expand All @@ -977,6 +979,7 @@ public void DesignTimeBuildHasAndroidDefines ([Values (AndroidRuntime.CoreCLR, A
IsRelease = isRelease,
};
proj.SetRuntime (runtime);
proj.SetProperty ("DisableImplicitFrameworkDefines", disableImplicitFrameworkDefines.ToString ());
var androidDefines = new List<string> ();
for (int i = 1; i <= XABuildConfig.AndroidDefaultTargetDotnetApiLevel.Major; ++i) {
androidDefines.Add ($"!__ANDROID_{i}__");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,37 @@ void AssertJniRemappingCounts (XamarinAndroidApplicationProject proj, ProjectBui
Assert.AreEqual (expectedMethodCount, appConfig.jni_remapping_replacement_method_index_entry_count, "jni_remapping_replacement_method_index_entry_count should be preserved.");
}

[Test]
public void JniAddNativeMethodRegistrationAttributePresentIsPreserved ()
{
var proj = new XamarinAndroidApplicationProject ();
proj.SetRuntime (AndroidRuntime.CoreCLR);
proj.SetRuntimeIdentifiers (new [] { "arm64-v8a" });
proj.SetProperty ("_SkipJniAddNativeMethodRegistrationAttributeScan", "true");

using (var builder = CreateApkBuilder ()) {
Assert.IsTrue (builder.Build (proj), "first build should have succeeded.");
AssertJniAddNativeMethodRegistrationAttributePresent (proj, builder);

string stamp = Path.Combine (Root, builder.ProjectDirectory, proj.IntermediateOutputPath, "stamp", "_GeneratePackageManagerJava.stamp");
FileAssert.Exists (stamp);
File.Delete (stamp);

Assert.IsTrue (builder.Build (proj, doNotCleanupOnUpdate: true), "second build should have succeeded.");
builder.Output.AssertTargetIsSkipped ("_GenerateJavaStubs");
builder.Output.AssertTargetIsNotSkipped ("_GeneratePackageManagerJava");
AssertJniAddNativeMethodRegistrationAttributePresent (proj, builder);
}
}

void AssertJniAddNativeMethodRegistrationAttributePresent (XamarinAndroidApplicationProject proj, ProjectBuilder builder)
{
string objDirPath = Path.Combine (Root, builder.ProjectDirectory, proj.IntermediateOutputPath);
var envFiles = EnvironmentHelper.GatherEnvironmentFiles (objDirPath, string.Join (";", proj.GetRuntimeIdentifiersAsAbis ()), required: true, runtime: AndroidRuntime.CoreCLR);
var appConfig = (EnvironmentHelper.ApplicationConfig_CoreCLR) EnvironmentHelper.ReadApplicationConfig (envFiles, AndroidRuntime.CoreCLR);
Assert.IsTrue (appConfig.jni_add_native_method_registration_attribute_present, "JNI native method registration should remain enabled.");
}

Dictionary<string, DateTime> GetJniRemappingSourceTimestamps (XamarinAndroidApplicationProject proj, ProjectBuilder builder)
{
string objDirPath = Path.Combine (Root, builder.ProjectDirectory, proj.IntermediateOutputPath, "android");
Expand Down Expand Up @@ -793,6 +824,43 @@ public void ManifestMergerIncremental ([Values (AndroidRuntime.CoreCLR, AndroidR
}
}

[Test]
public void AndroidDefineConstantsAreOrderIndependent ()
{
var path = Path.Combine ("temp", TestName);
var lib = new XamarinAndroidLibraryProject {
ProjectName = "Library",
};
lib.SetProperty ("DisableImplicitFrameworkDefines", "true");
lib.Imports.Add (new Import ("DefineConstants.targets") {
TextContent = () => """
<Project>
<Target Name="_AddTestDefineConstant">
<PropertyGroup>
<DefineConstants>$(DefineConstants);TEST_DEFINE</DefineConstants>
</PropertyGroup>
</Target>
<Target Name="_WriteTestDefineConstants">
<WriteLinesToFile File="$(IntermediateOutputPath)define-constants.txt" Lines="$(DefineConstants)" Overwrite="true" />
</Target>
</Project>
"""
});

using (var builder = CreateDllBuilder (Path.Combine (path, lib.ProjectName))) {
builder.Target = "_ResolveMonoAndroidSdks,_AddTestDefineConstant,Compile,_WriteTestDefineConstants";
Assert.IsTrue (builder.Build (lib), "first library build should have succeeded.");
var firstDefineConstants = builder.Output.GetIntermediaryAsText ("define-constants.txt");

builder.Target = "_AddTestDefineConstant,_ResolveMonoAndroidSdks,Compile,_WriteTestDefineConstants";
Assert.IsTrue (builder.Build (lib, doNotCleanupOnUpdate: true, saveProject: false), "second library build should have succeeded.");
Assert.AreEqual (firstDefineConstants, builder.Output.GetIntermediaryAsText ("define-constants.txt"),
"DefineConstants should not depend on target execution order.");
Assert.IsFalse (builder.LastBuildOutput.Any (line => line.Contains ("Building target \"CoreCompile\" completely.")),
"CoreCompile should not run when define constants are reordered.");
Comment thread
jonathanpeppers marked this conversation as resolved.
}
}

[Test]
public void ProduceReferenceAssembly ([Values (AndroidRuntime.CoreCLR, AndroidRuntime.NativeAOT)] AndroidRuntime runtime)
{
Expand Down
13 changes: 9 additions & 4 deletions src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
Original file line number Diff line number Diff line change
Expand Up @@ -810,10 +810,6 @@ because xbuild doesn't support framework reference assemblies.
<Output TaskParameter="AndroidDefineConstants" ItemName="AndroidDefineConstants" />
</GetAndroidDefineConstants>

<PropertyGroup>
<DefineConstants>$(DefineConstants);@(AndroidDefineConstants)</DefineConstants>
</PropertyGroup>

<!-- Setup $(AndroidApplicationJavaClass) -->
<PropertyGroup>
<AndroidApplicationJavaClass Condition="'$(AndroidApplicationJavaClass)' == '' And $(AndroidEnableMultiDex)">android.support.multidex.MultiDexApplication</AndroidApplicationJavaClass>
Expand All @@ -822,6 +818,14 @@ because xbuild doesn't support framework reference assemblies.
<Message Text="Application Java class: $(AndroidApplicationJavaClass)" />
</Target>

<Target Name="_AddAndroidDefineConstants"
BeforeTargets="BeforeCompile;CoreCompile"
DependsOnTargets="_ResolveMonoAndroidSdks;AddImplicitDefineConstants">
<PropertyGroup>
<DefineConstants>$(DefineConstants);@(AndroidDefineConstants)</DefineConstants>
</PropertyGroup>
</Target>

<Target Name="AndroidPrepareForBuild" DependsOnTargets="$(_OnResolveMonoAndroidSdks);$(AndroidPrepareForBuildDependsOn)" />

<!-- uploadflags.txt
Expand Down Expand Up @@ -1801,6 +1805,7 @@ because xbuild doesn't support framework reference assemblies.
RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)"
UseAssemblyStore="$(_AndroidUseAssemblyStore)"
AndroidEnableAssemblyStoreDecompressionCache="$(AndroidEnableAssemblyStoreDecompressionCache)"
SkipJniAddNativeMethodRegistrationAttributeScan="$(_SkipJniAddNativeMethodRegistrationAttributeScan)"
EnableMarshalMethods="$(_AndroidUseMarshalMethods)"
CustomBundleConfigFile="$(AndroidBundleConfigurationFile)"
TargetsCLR="$(_AndroidUseCLR)"
Expand Down
Loading