diff --git a/samples/NativeAOT/NativeAOT.csproj b/samples/NativeAOT/NativeAOT.csproj
index d16ef4b8056..b971a851f9e 100644
--- a/samples/NativeAOT/NativeAOT.csproj
+++ b/samples/NativeAOT/NativeAOT.csproj
@@ -12,4 +12,8 @@
true
-
\ No newline at end of file
+
+
+
+
+
diff --git a/samples/NativeAOT/environment.txt b/samples/NativeAOT/environment.txt
new file mode 100644
index 00000000000..1fbd68e71b6
--- /dev/null
+++ b/samples/NativeAOT/environment.txt
@@ -0,0 +1 @@
+naot.system.property=testing 1 2 3
diff --git a/samples/NativeAOT/run.sh b/samples/NativeAOT/run.sh
index bf6e8379d15..1f815130abd 100755
--- a/samples/NativeAOT/run.sh
+++ b/samples/NativeAOT/run.sh
@@ -19,7 +19,7 @@ fi
adb uninstall "${PACKAGE}" || true
adb install -r -d --no-streaming --no-fastdeploy "${APK}"
-#adb shell setprop debug.mono.log default,assembly,timing=bare
+adb shell setprop debug.mono.log default,assembly,timing=bare
adb logcat -G 128M
adb logcat -c
adb shell am start -S --user "0" -a "android.intent.action.MAIN" -c "android.intent.category.LAUNCHER" -n "${PACKAGE}/${ACTIVITY}" -W
diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
index 0120ff02aba..43372363cfd 100644
--- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
+++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets
@@ -72,6 +72,9 @@ This file contains the NativeAOT-specific MSBuild logic for .NET for Android.
clang++
llvm-objcopy
+
+ false
+
true
-
-
+
-
+
+
+
+
+
+
+
+
diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
index 89f08f48fca..6e8c70e7d1d 100644
--- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
+++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BuildTest2.cs
@@ -159,11 +159,11 @@ public void BasicApplicationPublishReadyToRun (bool isComposite, string rid)
var helper = new ArchiveAssemblyHelper (apk, true);
var abi = MonoAndroidHelper.RidToAbi (rid);
Assert.IsTrue (helper.Exists ($"assemblies/{abi}/{assemblyName}.dll"), $"{assemblyName}.dll should exist in apk!");
-
+
using var stream = helper.ReadEntry ($"assemblies/{assemblyName}.dll");
stream.Position = 0;
using var peReader = new System.Reflection.PortableExecutable.PEReader (stream);
- Assert.IsTrue (peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory.Size > 0,
+ Assert.IsTrue (peReader.PEHeaders.CorHeader.ManagedNativeHeaderDirectory.Size > 0,
$"ReadyToRun image not found in {assemblyName}.dll! ManagedNativeHeaderDirectory should not be empty!");
}
@@ -193,9 +193,7 @@ public void NativeAOT ()
];
string [] nativeaot_files = [
$"lib/arm64-v8a/lib{proj.ProjectName}.so",
- "lib/arm64-v8a/libc++_shared.so",
$"lib/x86_64/lib{proj.ProjectName}.so",
- "lib/x86_64/libc++_shared.so",
];
var intermediate = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath);
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs
index 7392418c5d8..3438f098bdb 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs
@@ -332,10 +332,21 @@ protected override void Construct (LlvmIrModule module)
module.Add (envVars);
module.AddGlobalVariable ("app_environment_variable_contents", envVarsBlob, LlvmIrVariableOptions.GlobalConstant);
- var sysProps = new LlvmIrGlobalVariable (systemProperties ?? new SortedDictionary(), "app_system_properties") {
+ // We reuse the same structure as for environment variables, there's no point in adding a new, identical, one
+ var sysPropsBlob = new LlvmIrStringBlob ();
+ List> appSysProps = LlvmIrHelpers.MakeEnvironmentVariableList (
+ Log,
+ systemProperties,
+ sysPropsBlob,
+ appEnvironmentVariableStructureInfo
+ );
+
+ var sysProps = new LlvmIrGlobalVariable (appSysProps, "app_system_properties") {
Comment = " System properties defined by the application",
+ Options = LlvmIrVariableOptions.GlobalConstant,
};
- module.Add (sysProps, stringGroupName: "sysprop", stringGroupComment: " System properties name:value pairs");
+ module.Add (sysProps);
+ module.AddGlobalVariable ("app_system_property_contents", sysPropsBlob, LlvmIrVariableOptions.GlobalConstant);
DsoCacheState dsoState = InitDSOCache ();
var app_cfg = new ApplicationConfigCLR {
@@ -347,7 +358,7 @@ protected override void Construct (LlvmIrModule module)
number_of_runtime_properties = (uint)(runtimeProperties == null ? 0 : runtimeProperties.Count),
package_naming_policy = (uint)PackageNamingPolicy,
environment_variable_count = (uint)(environmentVariables == null ? 0 : environmentVariables.Count),
- system_property_count = (uint)(systemProperties == null ? 0 : systemProperties.Count * 2),
+ system_property_count = (uint)(appSysProps.Count),
number_of_assemblies_in_apk = (uint)NumberOfAssembliesInApk,
number_of_shared_libraries = (uint)NativeLibraries.Count,
bundled_assembly_name_width = (uint)BundledAssemblyNameWidth,
diff --git a/src/Xamarin.Android.Build.Tasks/Utilities/NativeAotEnvironmentNativeAssemblyGenerator.cs b/src/Xamarin.Android.Build.Tasks/Utilities/NativeAotEnvironmentNativeAssemblyGenerator.cs
index ad80bb9c03d..210512de964 100644
--- a/src/Xamarin.Android.Build.Tasks/Utilities/NativeAotEnvironmentNativeAssemblyGenerator.cs
+++ b/src/Xamarin.Android.Build.Tasks/Utilities/NativeAotEnvironmentNativeAssemblyGenerator.cs
@@ -28,6 +28,8 @@ protected override void Construct (LlvmIrModule module)
SortedDictionary? systemProperties = null;
if (envBuilder.SystemProperties.Count > 0) {
systemProperties = new (envBuilder.SystemProperties, StringComparer.Ordinal);
+ } else {
+ systemProperties = new (StringComparer.Ordinal);
}
var envVarsBlob = new LlvmIrStringBlob ();
@@ -47,6 +49,25 @@ protected override void Construct (LlvmIrModule module)
};
module.Add (envVars);
module.AddGlobalVariable ("__naot_android_app_environment_variable_contents", envVarsBlob, LlvmIrVariableOptions.GlobalConstant);
+
+ // We reuse the same structure as for environment variables, there's no point in adding a new, identical, one
+ var sysPropsBlob = new LlvmIrStringBlob ();
+ List> appSysProps = LlvmIrHelpers.MakeEnvironmentVariableList (
+ Log,
+ systemProperties,
+ sysPropsBlob,
+ appEnvironmentVariableStructureInfo
+ );
+
+ var sysPropsCount = new LlvmIrGlobalVariable ((uint)appSysProps.Count, "__naot_android_app_system_property_count");
+ module.Add (sysPropsCount);
+
+ var sysProps = new LlvmIrGlobalVariable (appSysProps, "__naot_android_app_system_properties") {
+ Comment = " System properties defined by the application",
+ Options = LlvmIrVariableOptions.GlobalConstant,
+ };
+ module.Add (sysProps);
+ module.AddGlobalVariable ("__naot_android_app_system_property_contents", sysPropsBlob, LlvmIrVariableOptions.GlobalConstant);
}
void MapStructures (LlvmIrModule module)
diff --git a/src/native/clr/include/host/host-environment-clr.hh b/src/native/clr/include/host/host-environment-clr.hh
new file mode 100644
index 00000000000..c06ec3f8c71
--- /dev/null
+++ b/src/native/clr/include/host/host-environment-clr.hh
@@ -0,0 +1,4 @@
+#pragma once
+
+#include
+#include
diff --git a/src/native/clr/include/host/host-environment.hh b/src/native/clr/include/host/host-environment.hh
new file mode 100644
index 00000000000..fd3a5f16e1b
--- /dev/null
+++ b/src/native/clr/include/host/host-environment.hh
@@ -0,0 +1,76 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#include
+
+struct AppEnvironmentVariable;
+
+namespace xamarin::android {
+ class HostEnvironment
+ {
+ public:
+ static void init () noexcept;
+
+ [[gnu::flatten, gnu::always_inline]]
+ static void set_variable (const char *name, const char *value) noexcept
+ {
+ log_debug (LOG_DEFAULT, " Variable {} = '{}'", optional_string (name), optional_string (value));
+ if (::setenv (name, value, 1) < 0) {
+ log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
+ }
+ }
+
+ [[gnu::flatten, gnu::always_inline]]
+ static void set_variable (std::string_view const& name, std::string_view const& value) noexcept
+ {
+ set_variable (name.data (), value.data ());
+ }
+
+ [[gnu::flatten, gnu::always_inline]]
+ static void set_system_property (const char *name, const char *value) noexcept
+ {
+ // TODO: should we **actually** try to set the system property here? Would that even work? Needs testing
+ log_debug (LOG_DEFAULT, " System property {} = '{}'", optional_string (name), optional_string (value));
+ }
+
+ [[gnu::flatten, gnu::always_inline]]
+ static auto lookup_system_property (std::string_view const& name, size_t &value_len,
+ uint32_t const count, AppEnvironmentVariable const (&entries)[],
+ const char (&contents)[]) noexcept -> const char*
+ {
+ if (count == 0) {
+ return nullptr;
+ }
+
+ for (size_t i = 0; i < count; i++) {
+ AppEnvironmentVariable const& sys_prop = entries[i];
+ const char *prop_name = &contents[sys_prop.name_index];
+ if (name.compare (prop_name) != 0) {
+ continue;
+ }
+
+ const char *prop_value = &contents[sys_prop.value_index];
+ value_len = strlen (prop_value);
+ return prop_value;
+ }
+
+ return nullptr;
+ }
+
+ template [[gnu::flatten, gnu::always_inline]]
+ static void set_values (uint32_t const& count, AppEnvironmentVariable const (&entries)[], const char (&contents)[]) noexcept
+ {
+ for (size_t i = 0; i < count; i++) {
+ AppEnvironmentVariable const& env_var = entries[i];
+ const char *var_name = &contents[env_var.name_index];
+ const char *var_value = &contents[env_var.value_index];
+
+ setter (var_name, var_value);
+ }
+ }
+ };
+}
diff --git a/src/native/clr/include/xamarin-app.hh b/src/native/clr/include/xamarin-app.hh
index 7c774584a2e..c2140e2c882 100644
--- a/src/native/clr/include/xamarin-app.hh
+++ b/src/native/clr/include/xamarin-app.hh
@@ -339,7 +339,8 @@ extern "C" {
[[gnu::visibility("default")]] extern const ApplicationConfig application_config;
[[gnu::visibility("default")]] extern const AppEnvironmentVariable app_environment_variables[];
[[gnu::visibility("default")]] extern const char app_environment_variable_contents[];
- [[gnu::visibility("default")]] extern const char* const app_system_properties[];
+ [[gnu::visibility("default")]] extern const AppEnvironmentVariable app_system_properties[];
+ [[gnu::visibility("default")]] extern const char app_system_property_contents[];
[[gnu::visibility("default")]] extern const char* const mono_aot_mode_name;
diff --git a/src/native/clr/runtime-base/android-system.cc b/src/native/clr/runtime-base/android-system.cc
index 4ce0fab92c7..d63f21392e5 100644
--- a/src/native/clr/runtime-base/android-system.cc
+++ b/src/native/clr/runtime-base/android-system.cc
@@ -6,6 +6,7 @@
#include
#include
+#include
#include
#include
#include
@@ -224,32 +225,34 @@ AndroidSystem::setup_app_library_directories (jstring_array_wrapper& runtimeApks
void
AndroidSystem::setup_environment () noexcept
{
- const char *var_name;
- const char *var_value;
- for (size_t i = 0uz; i < application_config.environment_variable_count; i++) {
- AppEnvironmentVariable const& env_var = app_environment_variables [i];
- var_name = &app_environment_variable_contents[env_var.name_index];
- var_value = &app_environment_variable_contents[env_var.value_index];
-
- if constexpr (Constants::is_debug_build) {
- log_info (LOG_DEFAULT, "Setting environment variable '{}' to '{}'", var_name, var_value);
- }
+ if (application_config.environment_variable_count > 0) {
+ log_debug (LOG_DEFAULT, "Setting environment variables ({})", application_config.environment_variable_count);
+ HostEnvironment::set_values (
+ application_config.environment_variable_count,
+ app_environment_variables,
+ app_environment_variable_contents
+ );
+ }
- if (setenv (var_name, var_value, 1) < 0) {
- log_warn (LOG_DEFAULT, "Failed to set environment variable: {}", strerror (errno));
- }
+ if (application_config.system_property_count > 0) {
+ log_debug (LOG_DEFAULT, "Setting system properties ({})", application_config.system_property_count);
+ HostEnvironment::set_values (
+ application_config.system_property_count,
+ app_system_properties,
+ app_system_property_contents
+ );
}
#if defined(DEBUG)
- log_debug (LOG_DEFAULT, "Loading environment from the override directory."sv);
-
- dynamic_local_string env_override_file;
- Util::path_combine (env_override_file, std::string_view {primary_override_dir}, Constants::OVERRIDE_ENVIRONMENT_FILE_NAME);
- log_debug (LOG_DEFAULT, "{}", env_override_file.get ());
- if (Util::file_exists (env_override_file)) {
- log_debug (LOG_DEFAULT, "Loading {}"sv, env_override_file.get ());
- setup_environment_from_override_file (env_override_file);
- }
+ log_debug (LOG_DEFAULT, "Loading environment from the override directory."sv);
+
+ dynamic_local_string env_override_file;
+ Util::path_combine (env_override_file, std::string_view {primary_override_dir}, Constants::OVERRIDE_ENVIRONMENT_FILE_NAME);
+ log_debug (LOG_DEFAULT, "{}", env_override_file.get ());
+ if (Util::file_exists (env_override_file)) {
+ log_debug (LOG_DEFAULT, "Loading {}"sv, env_override_file.get ());
+ setup_environment_from_override_file (env_override_file);
+ }
#endif // def DEBUG
}
@@ -289,27 +292,13 @@ AndroidSystem::lookup_system_property (std::string_view const& name, size_t &val
return nullptr;
}
- const char *prop_name;
- const char *prop_value;
- for (size_t i = 0uz; i < application_config.system_property_count; i += 2uz) {
- prop_name = app_system_properties[i];
- if (prop_name == nullptr || *prop_name == '\0') {
- continue;
- }
-
- if (strcmp (prop_name, name.data ()) == 0) {
- prop_value = app_system_properties [i + 1uz];
- if (prop_value == nullptr || *prop_value == '\0') {
- value_len = 0uz;
- return "";
- }
-
- value_len = strlen (prop_value);
- return prop_value;
- }
- }
-
- return nullptr;
+ return HostEnvironment::lookup_system_property (
+ name,
+ value_len,
+ application_config.system_property_count,
+ app_system_properties,
+ app_system_property_contents
+ );
}
auto AndroidSystem::get_full_dso_path (std::string const& base_dir, std::string_view const& dso_path, dynamic_local_string& path) noexcept -> bool
diff --git a/src/native/clr/xamarin-app-stub/application_dso_stub.cc b/src/native/clr/xamarin-app-stub/application_dso_stub.cc
index cbc59d8a99f..14f33be4c29 100644
--- a/src/native/clr/xamarin-app-stub/application_dso_stub.cc
+++ b/src/native/clr/xamarin-app-stub/application_dso_stub.cc
@@ -76,7 +76,8 @@ const ApplicationConfig application_config = {
// TODO: migrate to std::string_view for these two
const AppEnvironmentVariable app_environment_variables[] = {};
const char app_environment_variable_contents[] = {};
-const char* const app_system_properties[] = {};
+const AppEnvironmentVariable app_system_properties[] = {};
+const char app_system_property_contents[] = {};
@@ -138,6 +139,7 @@ DSOCacheEntry aot_dso_cache[] = {
.hash = xamarin::android::xxhash::hash (fake_dso_name, sizeof(fake_dso_name) - 1),
.real_name_hash = xamarin::android::xxhash::hash (fake_dso_name, sizeof(fake_dso_name) - 1),
.ignore = true,
+ .is_jni_library = true,
.name_index = 3,
.handle = nullptr,
},
@@ -146,6 +148,7 @@ DSOCacheEntry aot_dso_cache[] = {
.hash = xamarin::android::xxhash::hash (fake_dso_name2, sizeof(fake_dso_name2) - 1),
.real_name_hash = xamarin::android::xxhash::hash (fake_dso_name2, sizeof(fake_dso_name2) - 1),
.ignore = true,
+ .is_jni_library = false,
.name_index = 4,
.handle = nullptr,
},
diff --git a/src/native/nativeaot/host/host-environment.cc b/src/native/nativeaot/host/host-environment.cc
index 8f647511e66..d1a093f6521 100644
--- a/src/native/nativeaot/host/host-environment.cc
+++ b/src/native/nativeaot/host/host-environment.cc
@@ -1,15 +1,10 @@
#include
-#include
+#include
#include
using namespace xamarin::android;
-struct AppEnvironmentVariable {
- uint32_t name_index;
- uint32_t value_index;
-};
-
extern "C" {
extern const uint32_t __naot_android_app_environment_variable_count;
extern const AppEnvironmentVariable __naot_android_app_environment_variables[];
@@ -18,16 +13,23 @@ extern "C" {
void HostEnvironment::init () noexcept
{
- if (__naot_android_app_environment_variable_count == 0) {
- return;
+ if (__naot_android_app_environment_variable_count > 0) {
+ log_debug (LOG_DEFAULT, "Setting environment variables ({})", __naot_android_app_environment_variable_count);
+ set_values (
+ __naot_android_app_environment_variable_count,
+ __naot_android_app_environment_variables,
+ __naot_android_app_environment_variable_contents
+ );
}
- log_debug (LOG_DEFAULT, "Setting {} environment variables", __naot_android_app_environment_variable_count);
- for (size_t i = 0; i < __naot_android_app_environment_variable_count; i++) {
- AppEnvironmentVariable const& env_var = __naot_android_app_environment_variables[i];
- const char *var_name = &__naot_android_app_environment_variable_contents[env_var.name_index];
- const char *var_value = &__naot_android_app_environment_variable_contents[env_var.value_index];
-
- set_variable (var_name, var_value);
+ if (__naot_android_app_system_property_count == 0) {
+ return;
}
+
+ log_debug (LOG_DEFAULT, "Setting system properties ({})", __naot_android_app_system_property_count);
+ set_values (
+ __naot_android_app_system_property_count,
+ __naot_android_app_system_properties,
+ __naot_android_app_system_property_contents
+ );
}
diff --git a/src/native/nativeaot/host/host.cc b/src/native/nativeaot/host/host.cc
index ae93cb4ad79..0562d4de408 100644
--- a/src/native/nativeaot/host/host.cc
+++ b/src/native/nativeaot/host/host.cc
@@ -1,6 +1,6 @@
#include
#include
-#include
+#include
#include
#include
#include
diff --git a/src/native/nativeaot/include/host/host-environment-naot.hh b/src/native/nativeaot/include/host/host-environment-naot.hh
new file mode 100644
index 00000000000..9ca099ed101
--- /dev/null
+++ b/src/native/nativeaot/include/host/host-environment-naot.hh
@@ -0,0 +1,17 @@
+#pragma once
+
+#include
+
+// Must be declared before including host-environment.hh
+struct AppEnvironmentVariable {
+ uint32_t name_index;
+ uint32_t value_index;
+};
+
+#include
+
+extern "C" {
+ extern const uint32_t __naot_android_app_system_property_count;
+ extern const AppEnvironmentVariable __naot_android_app_system_properties[];
+ extern const char __naot_android_app_system_property_contents[];
+}
diff --git a/src/native/nativeaot/include/host/host-environment-variables.hh b/src/native/nativeaot/include/host/host-environment-variables.hh
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/native/nativeaot/include/host/host-environment.hh b/src/native/nativeaot/include/host/host-environment.hh
deleted file mode 100644
index ceb7ee52f5f..00000000000
--- a/src/native/nativeaot/include/host/host-environment.hh
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-
-#include
-
-namespace xamarin::android {
- class HostEnvironment
- {
- public:
- static void init () noexcept;
-
- static void set_variable (const char *name, const char *value) noexcept
- {
- log_debug (LOG_DEFAULT, " Variable {} = '{}'", name, value);
- if (::setenv (name, value, 1) < 0) {
- log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
- }
- }
-
- static void set_variable (std::string_view const& name, std::string_view const& value) noexcept
- {
- set_variable (name.data (), value.data ());
- }
- };
-}
diff --git a/src/native/nativeaot/runtime-base/android-system.cc b/src/native/nativeaot/runtime-base/android-system.cc
index 66ce40f344b..52e19c153bc 100644
--- a/src/native/nativeaot/runtime-base/android-system.cc
+++ b/src/native/nativeaot/runtime-base/android-system.cc
@@ -1,11 +1,18 @@
+#include
#include
+#include
#include
using namespace xamarin::android;
-auto
-AndroidSystem::lookup_system_property ([[maybe_unused]] std::string_view const& name, [[maybe_unused]] size_t &value_len) noexcept -> const char*
+auto AndroidSystem::lookup_system_property (std::string_view const& name, size_t &value_len) noexcept -> const char*
{
- return nullptr; // No-op in NativeAOT
+ return HostEnvironment::lookup_system_property (
+ name,
+ value_len,
+ __naot_android_app_system_property_count,
+ __naot_android_app_system_properties,
+ __naot_android_app_system_property_contents
+ );
}