Merge branch 'tizen' into use_app_ni_path
author조웅석/Common Platform Lab(SR)/Principal Engineer/삼성전자 <ws77.cho@samsung.com>
Tue, 11 Jun 2019 07:52:38 +0000 (16:52 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 11 Jun 2019 07:52:38 +0000 (16:52 +0900)
Init/Init.cs [new file with mode: 0644]
Init/Tizen.Init.csproj [new file with mode: 0644]
NativeLauncher/dotnet.debugger
NativeLauncher/installer-plugin/ni_common.cc
NativeLauncher/installer-plugin/ni_common.h
NativeLauncher/installer-plugin/nitool.cc
NativeLauncher/launcher/dotnet/dotnet_launcher.cc
NativeLauncher/launcher/dotnet/dotnet_launcher.h
NativeLauncher/launcher/injection.cc
README.md
packaging/dotnet-launcher.spec

diff --git a/Init/Init.cs b/Init/Init.cs
new file mode 100644 (file)
index 0000000..5658226
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Reflection;
+using System.Runtime.Loader;
+using System.IO;
+
+namespace Tizen.Init {
+
+    class TypeLoader
+    {
+        static string[,] assem_type = new string[,] 
+        {
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Box"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Button"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Check"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Color"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Conformant"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.DateTimeSelector"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.DisplayRotation"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeObject"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeObject+SignalData"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EdjeTextPartObject"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Elementary"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Entry"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasKeyEventArgs"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasMap"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.EvasObject"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.FocusDirection"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.GenList"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.GestureLayer+GestureType"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.IInvalidatable"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Image"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.ItemObject+SignalData"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Label"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Layout"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Naviframe"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.NaviItem"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Point3D"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.ProgressBar"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Radio"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Rect"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Rectangle"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Scroller"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Size"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Slider"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Spinner"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Widget"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.Window"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "ElmSharp.WrapType"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleDateTimeSelector"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleGenList"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleScroller"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.CircleSpinner"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.ICircleWidget"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "ElmSharp.Wearable.IRotaryActionWidget"},
+            {"/usr/share/dotnet.tizen/framework/ElmSharp.Wearable.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", "<PrivateImplementationDetails>"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.IO.FileSystem.dll", "System.IO.File"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Algorithms.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Algorithms.dll", "System.Security.Cryptography.MD5"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", "<PrivateImplementationDetails>"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", "System.Collections.Generic.HashSet`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Collections.dll", "System.Collections.Generic.Queue`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Uri.dll", "<PrivateImplementationDetails>"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Uri.dll", "System.Uri"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "<PrivateImplementationDetails>"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "System.Xml.IXmlLineInfo"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Private.Xml.dll", "System.Xml.IXmlNamespaceResolver"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Runtime.dll", "System.Collections.Generic.ISet`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Runtime.dll", "System.Reflection.RuntimeReflectionExtensions"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.ObjectModel.ObservableCollection`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.INotifyCollectionChanged"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedAction"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedEventArgs"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Collections.Specialized.NotifyCollectionChangedEventHandler"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.INotifyPropertyChanged"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.PropertyChangedEventArgs"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.ComponentModel.PropertyChangedEventHandler"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ObjectModel.dll", "System.Windows.Input.ICommand"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.ComponentModel.dll", "System.IServiceProvider"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.Enumerable"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.EnumerableSorter`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IIListProvider`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IOrderedEnumerable`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.IPartition`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.dll", "System.Linq.OrderedEnumerable`1"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Linq.Expressions.dll", "System.Linq.Expressions.ExpressionVisitor"},
+            {"/usr/share/dotnet.tizen/netcoreapp/System.Security.Cryptography.Primitives.dll", "System.Security.Cryptography.HashAlgorithm"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.Application"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.CoreApplication"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.CoreBackend.EventType"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.Common.dll", "Tizen.Applications.TizenSynchronizationContext"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.UI.dll", "Tizen.Applications.CoreUIApplication"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Applications.UI.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Log.dll", "Interop"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.Log.dll", "Tizen.Log"},
+            {"/usr/share/dotnet.tizen/framework/Tizen.System.Information.dll", "Tizen.System.Information"}
+        };
+
+       static void PreloadEnd()
+       {
+               GC.Collect();
+               GC.WaitForPendingFinalizers();
+       }
+
+       static int PreloadTypes()
+       {
+               string loaded_assem_name = new string("");
+               Assembly loaded_assem = null;
+               for (int i = 0; i < assem_type.GetLength(0); i++)
+               {
+                       if (assem_type[i,0] != loaded_assem_name)
+                       {
+                               loaded_assem_name = assem_type[i,0];
+                               loaded_assem = LoadAssembly(loaded_assem_name);
+                       }
+                       if (loaded_assem != null)
+                       {
+                               LoadType(loaded_assem, assem_type[i,1]);
+                       }
+               }
+               PreloadEnd();
+
+               return 0;
+       }
+       static Assembly LoadAssembly(string path)
+       {
+               var context = AssemblyLoadContext.Default;
+               Assembly ret = null;
+
+               try
+               {
+                       if (File.Exists(path.Replace(".dll", ".ni.dll")))
+                       {
+                               ret = context.LoadFromNativeImagePath(path.Replace(".dll", ".ni.dll"), path);
+                       } else
+                       {//by concept LoadFromNativeImagePath has to do fallbacks to
+                        //properly passed IL asms, but it does not
+                               ret = context.LoadFromAssemblyPath(path);
+                       }
+               }
+               catch (Exception e) 
+               {
+                       Console.WriteLine(e.ToString());
+
+                       return null;
+               }
+
+               return ret;
+       }
+       static int LoadType(Assembly assem, string typeName)
+       {
+               try
+               {
+                       var tp = assem.GetType(typeName);
+               }
+               catch
+               {
+                       Console.WriteLine("Tizen.Init.TypeLoader.PreloadTypes can't load type " + typeName + " from assembly " + assem.ToString());
+                       return 1;
+               }
+
+               return 0;
+       }
+    }
+}
diff --git a/Init/Tizen.Init.csproj b/Init/Tizen.Init.csproj
new file mode 100644 (file)
index 0000000..6becf02
--- /dev/null
@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+           <TargetFramework>netcoreapp2.1</TargetFramework>
+           <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
+           <NoWin32Manifest>True</NoWin32Manifest>
+           <Configuration>Release</Configuration>
+    </PropertyGroup>
+
+    <ItemGroup>
+       <Reference Include="System.Runtime">
+       </Reference>
+       <Reference Include="System.Runtime.Loader">
+       </Reference>
+       <Reference Include="System.Console">
+       </Reference>
+       <Reference Include="System.IO.FileSystem">
+       </Reference>
+    </ItemGroup>
+
+</Project>
index fea3b4a..22338b2 100644 (file)
@@ -32,7 +32,6 @@ DEFAULT_OPT /home/owner/share/tmp/sdk_tools/heaptrack/heaptrack_interpret
 DEFAULT_OPT -o
 DEFAULT_OPT /home/owner/share/tmp/sdk_tools/profctl/profctl_heaptrack.log
 DEFAULT_OPT -E
-DEFAULT_OPT    DOTNET_LAUNCHER_INJECT=/home/owner/share/tmp/sdk_tools/heaptrack/libheaptrack_inject.so
 DEFAULT_OPT    DUMP_HEAPTRACK_OUTPUT=/home/owner/share/tmp/sdk_tools/heaptrack/heaptrack_fifo
 DEFAULT_OPT    CORECLR_PROFILER={C7BAD323-25F0-4C0B-B354-566390B215CA}
 DEFAULT_OPT    CORECLR_PROFILER_PATH=/home/owner/share/tmp/sdk_tools/heaptrack/libprofiler.so
index 4a1e284..29f0b82 100644 (file)
@@ -152,28 +152,28 @@ static bool niExist(const std::string& path)
        return false;
 }
 
-static int crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R, bool isAppNI = false)
+static ni_error_e crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R, bool isAppNI = false)
 {
        if (!isFileExist(dllPath)) {
                fprintf(stderr, "dll file is not exist : %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_NO_SUCH_FILE;
        }
 
        if (!isManagedAssembly(dllPath)) {
                fprintf(stderr, "Input file is not a dll file : %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PARAMETER;
        }
 
        if (niExist(dllPath)) {
                fprintf(stderr, "Already ni file is exist for %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_ALREADY_EXIST;
        }
 
        std::string absDllPath = absolutePath(dllPath);
        std::string absNiPath = getNiFilePath(dllPath);
        if (absNiPath.empty()) {
                fprintf(stderr, "Fail to get ni file name\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        if (isAppNI) {
@@ -182,7 +182,7 @@ static int crossgen(const std::string& dllPath, const std::string& appPath, bool
 
        pid_t pid = fork();
        if (pid == -1)
-               return -1;
+               return NI_ERROR_UNKNOWN;
 
        if (pid > 0) {
                int status;
@@ -192,10 +192,10 @@ static int crossgen(const std::string& dllPath, const std::string& appPath, bool
                        // niEixst() return false for System.Private.Corelib.dll
                        if (isFileExist(absNiPath)) {
                                updateNiFileInfo(absDllPath, absNiPath);
-                               return 0;
+                               return NI_ERROR_NONE;
                        } else {
                                fprintf(stderr, "Fail to create native image for %s\n", dllPath.c_str());
-                               return -1;
+                               return NI_ERROR_NO_SUCH_FILE;
                        }
                }
        } else {
@@ -232,10 +232,10 @@ static int crossgen(const std::string& dllPath, const std::string& appPath, bool
                exit(0);
        }
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-static int getRootPath(std::string pkgId, std::string& rootPath)
+static ni_error_e getRootPath(std::string pkgId, std::string& rootPath)
 {
        int ret = 0;
        char *path = 0;
@@ -244,32 +244,32 @@ static int getRootPath(std::string pkgId, std::string& rootPath)
 
        if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
                _ERR("Failed to get UID");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        pkgmgrinfo_pkginfo_h handle;
        if (uid == 0) {
                ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
                if (ret != PMINFO_R_OK)
-                       return -1;
+                       return NI_ERROR_UNKNOWN;
        } else {
                ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
                if (ret != PMINFO_R_OK)
-                       return -1;
+                       return NI_ERROR_UNKNOWN;
        }
 
        ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
        if (ret != PMINFO_R_OK) {
                pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
        rootPath = path;
        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-
+// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
 static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
@@ -318,7 +318,7 @@ static void createCoreLibNI(bool enableR2R)
        }
 }
 
-int initNICommon(NiCommonOption* option)
+ni_error_e initNICommon(NiCommonOption* option)
 {
 #if defined(__arm__)
        // get interval value
@@ -331,19 +331,19 @@ int initNICommon(NiCommonOption* option)
 
        if (initializePluginManager("normal")) {
                fprintf(stderr, "Fail to initialize plugin manager\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
        if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) {
                fprintf(stderr, "Fail to initialize path manager\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        __tpa = getTPA();
 
-       return 0;
+       return NI_ERROR_NONE;
 #else
        fprintf(stderr, "crossgen supports arm architecture only. skip ni file generation\n");
-       return -1;
+       return NI_ERROR_NOT_SUPPORTED;
 #endif
 }
 
@@ -364,9 +364,15 @@ void createNiPlatform(bool enableR2R)
        createNiUnderDirs(platformDirs, 2, enableR2R);
 }
 
-int createNiDll(const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDll(const std::string& dllPath, bool enableR2R)
 {
        createCoreLibNI(enableR2R);
+       // System.Private.CoreLib.dll is generated in the createCoreLibNI function.
+       // Skip if input dll is System.Private.CoreLib.dll
+       if (dllPath.find("System.Private.CoreLib.dll") != std::string::npos) {
+               return NI_ERROR_NONE;
+       }
+
        return crossgen(dllPath, std::string(), enableR2R);
 }
 
@@ -394,12 +400,12 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R,
        }
 }
 
-int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
+ni_error_e createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
 {
        std::string pkgRoot;
-       if (getRootPath(pkgName, pkgRoot) < 0) {
+       if (getRootPath(pkgName, pkgRoot) != NI_ERROR_NONE) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -408,15 +414,15 @@ int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
 
        createNiUnderDirs(paths, 2, enableR2R, true);
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-int createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
 {
        std::string pkgRoot;
        if (getRootPath(pkgName, pkgRoot) < 0) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -463,12 +469,12 @@ void removeNiUnderDirs(const std::string rootPaths[], int count)
                scanFilesInDir(rootPaths[i], convert, -1);
 }
 
-int removeNiUnderPkgRoot(const std::string& pkgName)
+ni_error_e removeNiUnderPkgRoot(const std::string& pkgName)
 {
        std::string pkgRoot;
        if (getRootPath(pkgName, pkgRoot) < 0) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -491,34 +497,34 @@ int removeNiUnderPkgRoot(const std::string& pkgName)
                }
        }
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-int regenerateAppNI(bool enableR2R)
+ni_error_e regenerateAppNI(bool enableR2R)
 {
        int ret = 0;
        pkgmgrinfo_appinfo_metadata_filter_h handle;
 
        ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
        if (ret != PMINFO_R_OK)
-               return -1;
+               return NI_ERROR_UNKNOWN;
 
        ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, AOT_METADATA_KEY, AOT_METADATA_VALUE);
        if (ret != PMINFO_R_OK) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, &enableR2R);
        if (ret != PMINFO_R_OK) {
                fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
 
        pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-       return 0;
+       return NI_ERROR_NONE;
 }
 
index a98bf5a..3f3de82 100644 (file)
 
 typedef std::function<void (std::string)> afterCreate;
 
+typedef enum {
+       NI_ERROR_NONE = 0,
+       NI_ERROR_INVALID_PARAMETER = -1,
+       NI_ERROR_ALREADY_EXIST = -2,
+       NI_ERROR_NO_SUCH_FILE = -3,
+       NI_ERROR_INVALID_PACKAGE = -4,
+       NI_ERROR_NOT_SUPPORTED = -5,
+       NI_ERROR_UNKNOWN = -9
+} ni_error_e;
+
 /**
  * @brief : structure which contains directory info
  */
@@ -33,9 +43,9 @@ typedef struct NiCommonOption {
 /**
  * @brief initialize NICommon
  * @param[in] options to initialize path
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e 0 on success, otherwise a negative error value
  */
-int initNICommon(NiCommonOption* option);
+ni_error_e initNICommon(NiCommonOption* option);
 
 /**
  * @brief finalize NICommon
@@ -52,9 +62,9 @@ void createNiPlatform(bool enableR2R);
  * @brief create native image for specific dll with file path.
  * @param[i] dllPath file path to generate native image
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiDll(const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDll(const std::string& dllPath, bool enableR2R);
 
 /**
  * @brief create native images with files under specific directory.
@@ -69,18 +79,18 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R,
  * @brief create native images for specific package. (All DLLs)
  * @param[i] pkgId package ID
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
+ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
 
 /**
  * @brief create native image for specific dll in the package.
  * @Details All dlls in the package are added for reference when create native image.
  * @param[i] pkgId package ID
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
 
 /**
  * @brief remove native images (NI file) for Platform DLLs (.NETCore + TizenFX)
@@ -97,13 +107,14 @@ void removeNiUnderDirs(const std::string rootPaths[], int count);
 /**
  * @brief remove native images for specific package.
  * @param[i] pkgId package ID
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int removeNiUnderPkgRoot(const std::string& pkgId);
+ni_error_e removeNiUnderPkgRoot(const std::string& pkgId);
 
 /**
  * @brief regenerate native image for all installed application
+ * @return ni_error_e
  */
-int regenerateAppNI(bool enableR2R = true);
+ni_error_e regenerateAppNI(bool enableR2R = true);
 
 #endif /* __NI_COMMON_H__ */
index aac3d0e..4ff2679 100644 (file)
@@ -74,7 +74,7 @@ int main(int argc, char* argv[])
        bool pkgDllMode = false;
 
        NiCommonOption option = {std::string(), std::string(), std::string()};
-       if (initNICommon(&option) < 0) {
+       if (initNICommon(&option) != NI_ERROR_NONE) {
                fprintf(stderr, "Fail to initialize NI Common\n");
                return -1;
        }
@@ -123,26 +123,47 @@ int main(int argc, char* argv[])
 
        if (pkgMode) {
                for (const std::string pkg : args) {
-                       if (createNiUnderPkgRoot(pkg, enableR2R) != 0) {
+                       // if there is AOTed dlls under package root, that is skiped.
+                       int ret = createNiUnderPkgRoot(pkg, enableR2R);
+                       if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
                                return -1;
+                       } else if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+                               return -1;
                        }
                }
        } else if (pkgDllMode) {
-               if (createNiDllUnderPkgRoot(args[0], args[1], enableR2R) != 0) {
+               int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
+               if (ret == NI_ERROR_INVALID_PACKAGE) {
                        fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
                        return -1;
+               } else if (ret == NI_ERROR_ALREADY_EXIST) {
+                       // skip for already exist case
+                       return -1;
+               } else if (ret != NI_ERROR_NONE) {
+                       fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+                       return -1;
                }
        } else if (rmPkgMode) {
                for (const std::string pkg : args) {
-                       if (removeNiUnderPkgRoot(pkg) != 0) {
+                       int ret = removeNiUnderPkgRoot(pkg);
+                       if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
                                return -1;
+                       } else if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
+                               return -1;
                        }
                }
        } else if (dllMode) {
+               // donot return error code for generation failure.
+               // we have to run crossgen for all input dlls.
                for (const std::string dll : args) {
-                       if (createNiDll(dll, enableR2R) != 0) {
+                       int ret = createNiDll(dll, enableR2R);
+                       if (ret == NI_ERROR_ALREADY_EXIST) {
+                               // skip for already exist case
+                       } else if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
                        }
                }
index 247c671..feae81d 100644 (file)
@@ -227,6 +227,30 @@ static std::u16string utf8ToUtf16(char* str)
        return convert.from_bytes(str);
 }
 
+void CoreRuntime::preloadTypes()
+{
+       const static std::string initDllPath = "/usr/share/dotnet.tizen/framework/Tizen.Init.dll";
+       if (!isFileExist(initDllPath)) {
+               _ERR("Failed to locate Tizen.Init.dll");
+               return;
+       }
+
+       typedef void (*InitDelegate)();
+       InitDelegate initDelegate;
+
+       int ret = createDelegate(__hostHandle,
+               __domainId,
+               "Tizen.Init",
+               "Tizen.Init.TypeLoader",
+               "PreloadTypes",
+               (void**)&initDelegate);
+
+       if (ret < 0) {
+               _ERR("Failed to create delegate for PreloadTypes (0x%08x)", ret);
+       } else {
+               initDelegate();
+       }
+}
 
 CoreRuntime::CoreRuntime(const char* mode) :
        initializeClr(nullptr),
@@ -264,8 +288,7 @@ CoreRuntime::~CoreRuntime()
 
 int CoreRuntime::initialize(bool standalone)
 {
-       // checkInjection checks dotnet-launcher run mode,
-       // if it contains DOTNET_LAUNCHER_INJECT variable, it injects library.
+       // checkInjection checks dotnet-launcher run mode
        // At the moment, this mechanism is used only when the Memory Profiler is started.
        int res = checkInjection();
        if (res != 0) {
@@ -379,6 +402,11 @@ int CoreRuntime::initialize(bool standalone)
 
        __initialized = true;
 
+       if (!standalone)
+       {
+               preloadTypes();         // Preload common managed code
+       }
+
        _INFO("CoreRuntime initialize success");
 
        return 0;
index b05009d..e9e6c5d 100644 (file)
@@ -35,7 +35,9 @@ class CoreRuntime
                int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]);
 
        private:
+
                bool initializeCoreClr(const char* appId, const char* assemblyProbePaths, const char* NIProbePaths, const char* pinvokeProbePaths, const char* tpaList);
+               void preloadTypes();
                coreclr_initialize_ptr initializeClr;
                coreclr_execute_assembly_ptr executeAssembly;
                coreclr_shutdown_ptr shutdown;
@@ -54,4 +56,4 @@ class CoreRuntime
 }  // namespace runtime
 }  // namespace tizen
 
-#endif /* __DOTNET_LAUNCHER_H__ */
\ No newline at end of file
+#endif /* __DOTNET_LAUNCHER_H__ */
index 3efd3a9..819af59 100644 (file)
 
 #include <dlfcn.h>
 
+#define HT_PATH "/home/owner/share/tmp/sdk_tools/heaptrack/"
+#define HT_LIB_PATH HT_PATH "libprofiler.so"
+#define HT_INJECTION_LIB_PATH HT_PATH "libheaptrack_inject.so"
+
 static int injectLibrary(const char path[])
 {
        typedef int inject_func();
@@ -51,42 +55,25 @@ static int injectLibrary(const char path[])
 
 int checkInjection()
 {
-       int res = -1;
        char *env = nullptr;
-       char* injectableLibs = nullptr;
-       const char *delim = ", ";
-       char *lib = nullptr;
-       char *saveptr = nullptr;
 
-       env = getenv("DOTNET_LAUNCHER_INJECT");
+       env = getenv("CORECLR_PROFILER_PATH");
        if (env == nullptr) {
-               res = 0;
-               return res;
+               return 0;
        }
 
-       _INFO("##### Perform injection #########");
-
-       injectableLibs = strdup(env);
-       if (injectableLibs == nullptr) {
-               _ERR("Fail to allocate memory for injectable library paths\n");
-               return res;
+       // At the moment, this mechanism is used only when the Memory Profiler is started.
+       if (strcmp(env, HT_LIB_PATH) != 0) {
+               return 0;
        }
 
-       res = 0;
-       lib = strtok_r(injectableLibs, delim, &saveptr);
-       for(; lib != nullptr; lib = strtok_r(nullptr, delim, &saveptr)) {
-               if (injectLibrary(lib) != 0) {
-                       res = -1;
-                       break;
-               }
-       }
+       _INFO("##### Perform injection #########");
 
-       if (res == 0) {
-               _INFO("##### Injection finished #########");
-       } else {
+       if (injectLibrary(HT_INJECTION_LIB_PATH) != 0) {
                _INFO("##### Injection failed #########");
+               return -1;
        }
 
-       free(injectableLibs);
-       return res;
+       _INFO("##### Injection finished #########");
+       return 0;
 }
index 1ac01f9..e85863e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -14,14 +14,6 @@ dotnet-launcher [options...] [args...]
 * --standalone [assembly path]  
    Run assembly with the current user environment.
 
-#### environment
-
-* DOTNET_LAUNCHER_INJECT  
-   A list of additional libraries to be loaded with `dlopen()` and call to
-   `int dotnet_launcher_inject()` initialization hook. If hook returns non-zero
-   status initialization will be failed. The items of the list can be separated
-   by spaces or colons, and there is no support for escaping either separator.
-
 ----
 
 ### Anatomy
index 74b03ba..e551023 100644 (file)
@@ -45,6 +45,7 @@ Requires(preun): /usr/bin/systemctl
 %define _loaderdir %{_prefix}/share/aul
 %define _device_api_dir %{dotnet_assembly_path}
 %define _runtime_dir /usr/share/dotnet.tizen/netcoreapp
+%define _framework_dir /usr/share/dotnet.tizen/framework
 %define _install_mdplugin_dir /etc/package-manager/parserlib/metadata
 %define _native_lib_dir /usr/share/dotnet.tizen/lib
 
@@ -77,6 +78,10 @@ export CXXFLAGS=$(echo $CXXFLAGS | sed -e 's/--target=i686/--target=i586/')
 %endif
 %endif
 
+dotnet msbuild Init/Tizen.Init.csproj /t:clean
+dotnet msbuild Init/Tizen.Init.csproj /t:restore /p:RestoreSources=/nuget
+dotnet msbuild Init/Tizen.Init.csproj
+
 cmake \
        -DCMAKE_INSTALL_PREFIX=%{_prefix} \
 %if 0%{?asan_enabled}
@@ -102,6 +107,9 @@ make %{?jobs:-j%jobs} VERBOSE=1
 %install
 rm -rf %{buildroot}
 %make_install
+mkdir -p %{buildroot}%{_framework_dir} 
+mv Init/bin/Release/Tizen.Init.dll %{buildroot}%{_framework_dir}
+
 
 mkdir -p %{buildroot}%{_native_lib_dir}
 ln -sf %{_libdir}/libsqlite3.so.0 %{buildroot}%{_native_lib_dir}/libsqlite3.so
@@ -112,6 +120,7 @@ install -m 0644 %{name}.conf %{buildroot}/etc/tmpfiles.d/%{name}.conf
 %post
 mkdir -p /opt/etc/skel/.dotnet
 chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
+%{_bindir}/nitool --dll %{_runtime_dir}/System.Private.CoreLib.dll
 
 %files
 %manifest dotnet-launcher.manifest
@@ -126,6 +135,7 @@ chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
 %{_libdir}/libdotnet_launcher_util.so
 %{_libdir}/libni_common.so
 /etc/tmpfiles.d/%{name}.conf
+%{_framework_dir}/Tizen.Init.dll
 
 %files devel
 %manifest dotnet-launcher.manifest