Refactoring the dotnettool (#231)
author최종헌/Common Platform Lab(SR)/Engineer/삼성전자 <j-h.choi@samsung.com>
Mon, 25 May 2020 07:55:10 +0000 (16:55 +0900)
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>
Mon, 25 May 2020 07:55:10 +0000 (16:55 +0900)
Change-Id: Ia41c0548849338b67e9eee143f4b52c74719fadf

NativeLauncher/inc/ni_common.h
NativeLauncher/inc/utils.h
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/util/utils.cc
packaging/dotnet-launcher.spec

index f33ddcc..9fcd321 100644 (file)
@@ -41,6 +41,7 @@ typedef enum {
        NI_ERROR_NO_SUCH_FILE = -3,
        NI_ERROR_INVALID_PACKAGE = -4,
        NI_ERROR_NOT_SUPPORTED = -5,
+       NI_ERROR_CORE_NI_FILE = -6,
        NI_ERROR_UNKNOWN = -9
 } ni_error_e;
 
@@ -69,8 +70,9 @@ void finalizeNICommon();
 /**
  * @brief create native images for platform DLLs (.NETCore + TizenFX)
  * @param[i] flags additional flags for the image generator
+ * @return ni_error_e
  */
-void createNiPlatform(DWORD flags);
+ni_error_e createNiPlatform(DWORD flags);
 
 /**
  * @brief create a native image for a single DLL
@@ -101,8 +103,9 @@ ni_error_e createTACPkgRoot(const std::string& pkgId, DWORD flags);
  * @param[i] rootPaths paths to directories
  * @param[i] count length of rootPaths
  * @param[i] flags additional flags for the image generator
+ * @return ni_error_e
  */
-void createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags);
+ni_error_e createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags);
 
 /**
  * @brief create native images for all DLLs in a package
index b8b065f..90cc23d 100644 (file)
@@ -121,6 +121,13 @@ void splitPath(const std::string& path, std::vector<std::string>& out);
 bool isFileExist(const std::string& path);
 
 /**
+ * @brief check directory is exist
+ * @param[in] source path
+ * @return bool
+ */
+bool isDirectoryExist(const std::string& path);
+
+/**
  * @brief get file size
  * @param[in] source path
  * @return size of file
index 120b179..d657f35 100644 (file)
 #include "ni_common.h"
 #include "tac_common.h"
 
-#include <algorithm>
-#include <cstdio>
-#include <cstring>
 #include <vector>
+#include <stdlib.h>
+#include <sys/time.h>
 
-std::vector<std::string> getCmdArgs(char** begin, char** end)
-{
-       std::vector<std::string> list;
-       for (char** itr = begin+1; itr != end; itr++) {
-               if (strncmp(*itr, "--", 2) != 0) {
-                       list.push_back(*itr);
-               }
-       }
-       return list;
-}
-
-static void help(const char *argv0)
-{
-       const char* helpDesc =
-               "Usage: %s [OPTIONS] COMMAND <paths or pkg name>\n"
+void DisplayUsage() {
+       fprintf(stdout,
+               "\n"
+               "Dotnet Tool Version: 1.0\n"
                "\n"
                "Commands:\n"
-               "       --help                 - Display this screen\n"
-               "       --ni-system            - Create NI under System DLLs\n"
-               "       --ni-dll               - Create NI for DLL\n"
-               "       --ni-pkg               - Create NI for package\n"
-               "       --ni-pkg-dll           - Create NI for DLL in package\n"
-               "       --ni-dir               - Create NI for directory\n"
-               "       --ni-reset-system      - Remove System NI files\n"
-               "       --ni-reset-pkg         - Remove App NI files\n"
-               "       --ni-reset-dir         - Remove NI for directory\n"
-               "       --ni-regen-all-app     - Re-generate All App NI files\n"
-               "       --tac-regen-all        - Re-generate All TAC files\n"
-               "       --tac-restore-db       - Restore TAC Database\n"
-               "       --tac-disable-pkg      - Disable TAC for package\n"
-               "       --tac-enable-pkg       - Enable TAC for package\n"
+               "       -h, --help                - Show this help message\n"
+               "       --ni-system               - Create NI under System DLLs\n"
+               "       --ni-dll                  - Create NI for DLL\n"
+               "       --ni-pkg                  - Create NI for package\n"
+               "       --ni-pkg-dll              - Create NI for DLL in package\n"
+               "       --ni-dir                  - Create NI for directory\n"
+               "       --ni-reset-system         - Remove System NI files\n"
+               "       --ni-reset-pkg            - Remove App NI files\n"
+               "       --ni-reset-dir            - Remove NI for directory\n"
+               "       --ni-regen-all-app        - Re-generate All App NI files\n"
+               "       --tac-regen-all           - Re-generate All TAC files\n"
+               "       --tac-restore-db          - Restore TAC Database\n"
+               "       --tac-disable-pkg         - Disable TAC for package\n"
+               "       --tac-enable-pkg          - Enable TAC for package\n"
+               "       --ibc-dir                 - Specify a directory containing IBC files\n"
                "\n"
                "Options:\n"
-               "       --r2r                  - Generate a Ready-To-Run image (disables /FragileNonVersionable)\n"
-               "       --compatibility        - Compatibility mode for older versions of crossgen\n"
-               "                                (replaces /r with /Trusted_Platform_Assemblies)\n"
-               "       --verbose              - Display verbose information\n"
-               "       --instrument           - Generate an instrumented image for profiling (enables /Tuning)\n"
+               "       --r2r                     - Generate a Ready-To-Run image (disable: /FragileNonVersionable)\n"
+               "       --compatibility           - Compatibility mode for older versions of crossgen\n"
+               "                                   (replaces /r with /Trusted_Platform_Assemblies)\n"
+               "       --verbose                 - Display verbose information\n"
+               "       --instrument              - Generate an instrumented image for profiling (enable: /Tuning)\n"
+               "\n"
+               "Usage: dotnettool [options] [command] [arguments]\n"
                "\n"
                "Example:\n"
                "1. Create native image for dlls and exes under platform directories\n"
-               "   # %s --ni-system\n"
+               "   # dotnettool --ni-system\n"
                "2. Create native image for dll\n"
-               "   # %s --ni-dll /usr/bin/Tizen.Runtime.dll\n"
+               "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
                "3. Create native image under the package's bin and lib directory\n"
-               "   # %s --ni-pkg org.tizen.FormsGallery\n"
+               "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
                "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
-               "   # %s --r2r --ni-regen-all-app\n\n";
-       printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
+               "   # dotnettool --r2r --ni-regen-all-app\n"
+               "5. Create native image for dll based on the IBC data\n"
+               "   # dotnettool --ibc-dir /tmp/ibcdata/ --ni-dll /usr/bin/Tizen.Runtime.dll\n"
+               "\n");
 }
 
 int main(int argc, char* argv[])
 {
-       DWORD flags = 0;
-       bool pkgMode = false;
-       bool dllMode = false;
-       bool dirMode = false;
-       bool rmPkgMode = false;
-       bool rmDirMode = false;
-       bool pkgDllMode = false;
-       bool disableTacMode = false;
-       bool enableTacMode = false;
+       argc--;
+       argv++;
+
+       long starttime;
+       long endtime;
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
+
+       if (argc <= 0) {
+               DisplayUsage();
+               return -1;
+       }
 
        NiCommonOption option = {std::string(), std::string(), std::string()};
        if (initNICommon(&option) != NI_ERROR_NONE) {
                return -1;
        }
 
-       // Parse optional switches first.
-       if (cmdOptionExists(argv, argv+argc, "--r2r")) {
-               flags |= NI_FLAGS_ENABLER2R;
-       }
-       if (cmdOptionExists(argv, argv+argc, "--compatibility")) {
-               flags |= NI_FLAGS_COMPATIBILITY;
-       }
-       if (cmdOptionExists(argv, argv+argc, "--instrument")) {
-               flags |= NI_FLAGS_INSTRUMENT;
-       }
-       if (cmdOptionExists(argv, argv+argc, "--verbose")) {
-               flags |= NI_FLAGS_VERBOSE;
+       //sh-3.2# dotnettool --[r2r|compatibility|instrument|verbose]
+       DWORD flags = 0;
+       std::vector<std::string> args;
+       for (char** it = argv; it != argv+argc; it++) {
+               if (!strncmp(*it, "-?", 2) || !strncmp(*it, "-h", 2) || !strncmp(*it, "--help", 6)) {
+                       DisplayUsage();
+                       return 0;
+               } else if (!strncmp(*it, "--r2r", 5)) {
+                       flags |= NI_FLAGS_ENABLER2R;
+               } else if (!strncmp(*it, "--compatibility", 15)) {
+                       flags |= NI_FLAGS_COMPATIBILITY;
+               } else if (!strncmp(*it, "--instrument", 12)) {
+                       flags |= NI_FLAGS_INSTRUMENT;
+               } else if (!strncmp(*it, "--verbose", 9)) {
+                       flags |= NI_FLAGS_VERBOSE;
+               } else {
+                       args.push_back(*it);
+               }
        }
 
-       // The following commands are mutually exclusive.
-       if (cmdOptionExists(argv, argv+argc, "--help")) {
-               help(argv[0]);
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-system")) {
-               createNiPlatform(flags);
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-dll")) {
-               dllMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg")) {
-               pkgMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-dir")) {
-               dirMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-system")) {
-               removeNiPlatform();
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-pkg")) {
-               rmPkgMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-dir")) {
-               rmDirMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg-dll")) {
-               pkgDllMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--ni-regen-all-app")) {
-               regenerateAppNI(flags);
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--tac-regen-all")) {
-               regenerateTACNI(flags);
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--tac-restore-db")) {
-               restoreTACDB();
-               return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--tac-disable-pkg")) {
-               disableTacMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--tac-enable-pkg")) {
-               enableTacMode = true;
-       } else {
-               help(argv[0]);
-               return 0;
+       //sh-3.2# dotnettool --ibc-dir [ibcDirectory]
+       for (auto it = args.begin(); it != args.end(); ) {
+               if (*it == "--ibc-dir") {
+                       it = args.erase(it);
+
+                       std::string ibcFilePath = std::string(*it);
+                       if (!isDirectoryExist(ibcFilePath)) {
+                               fprintf(stderr, "IBC path is missing or not exist\n");
+                               return -1;
+                       }
+
+                       setenv("COMPlus_IBCFileDir", const_cast<char *>(ibcFilePath.c_str()), 1);
+                       setenv("COMPlus_UseIBCFile", const_cast<char *>("1"), 1);
+               } else {
+                       ++it;
+               }
        }
 
-       std::vector<std::string> args = getCmdArgs(argv, argv+argc);
+       std::vector<std::string>::iterator it = args.begin();
+       std::string cmd = std::string(*it);
+       it = args.erase(it);
 
-       if (args.size() < 1) {
-               if (pkgMode || rmPkgMode || disableTacMode || enableTacMode) {
-                       fprintf(stderr, "Package name is missed\n");
-               } else if (dllMode) {
-                       fprintf(stderr, "DLL path is missing.\n");
-               } else if (rmDirMode) {
-                       fprintf(stderr, "Directory path is missing.\n");
+       //sh-3.2# dotnettool --ni-system
+       if (cmd == "--ni-system") {
+               int ret = createNiPlatform(flags);
+               if (ret != NI_ERROR_NONE) {
+                       fprintf(stderr, "Failed to generate system NI\n");
                }
-               help(argv[0]);
-               return -1;
-       } else if (args.size() < 2) {
-               if (pkgDllMode) {
-                       fprintf(stderr, "Package name or DLL path is missing.\n");
-                       help(argv[0]);
-                       return -1;
+       }
+       //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
+       else if (cmd == "--ni-dll") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "DLL path is missing\n");
+               }
+               while (it != args.end()) {
+                       std::string dll = std::string(*it);
+                       int ret = createNiDll(dll, flags);
+                       if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
+                               break;
+                       }
+                       it = args.erase(it);
                }
        }
-
-       if (pkgMode) {
-               for (const std::string pkg : args) {
+       //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
+       else if (cmd == "--ni-pkg") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Package name is missing\n");
+               }
+               while (it != args.end()) {
+                       std::string pkg = std::string(*it);
                        // if there is AOTed dlls under package root, that is skiped.
                        int ret = createNiUnderPkgRoot(pkg, flags);
                        if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        } else if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        }
                        ret = createTACPkgRoot(pkg, flags);
-                       if (ret == TAC_ERROR_INVALID_PACKAGE) {
+                       if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
-                               return -1;
-                       } else if (ret != TAC_ERROR_NONE) {
+                               break;
+                       } else if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        }
+                       it = args.erase(it);
                }
-       } else if (pkgDllMode) {
-               int ret = createNiDllUnderPkgRoot(args[0], args[1], flags);
-               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;
+       }
+       //sh-3.2# dotnettool --ni-pkg-dll [pkgId] [pkgAssemblyPath] [pkgAssemblyPath] ...
+       else if (cmd == "--ni-pkg-dll") {
+               if (args.size() < 2) {
+                       fprintf(stderr, "Package name or DLL path is missing\n");
+               } else {
+                       std::string pkg = std::string(*it);
+                       it = args.erase(it);
+                       while (it != args.end()) {
+                               std::string dll = std::string(*it);
+                               int ret = createNiDllUnderPkgRoot(pkg, dll, flags);
+                               if (ret == NI_ERROR_INVALID_PACKAGE) {
+                                       fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+                                       break;
+                               } else if (ret != NI_ERROR_NONE) {
+                                       fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
+                                       break;
+                               }
+                               it = args.erase(it);
+                       }
                }
-       } else if (rmPkgMode) {
-               for (const std::string pkg : args) {
+       }
+       //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
+       else if (cmd == "--ni-dir") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Directory path is missing\n");
+               }
+               while (it != args.end()) {
+                       const std::string dir[] = {std::string(*it)};
+                       int ret = createNiUnderDirs(dir, 1, flags);
+                       if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to generate NI directory\n");
+                               break;
+                       }
+                       it = args.erase(it);
+               }
+       }
+       //sh-3.2# dotnettool --ni-reset-system
+       else if (cmd == "--ni-reset-system") {
+               removeNiPlatform();
+       }
+       //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
+       else if (cmd == "--ni-reset-pkg") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Package name is missing\n");
+               }
+               while (it != args.end()) {
+                       std::string pkg = std::string(*it);
                        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;
+                               break;
                        } else if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        }
                        ret = resetTACPackage(pkg);
                        if (ret == TAC_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        } else if (ret != TAC_ERROR_NONE) {
                                fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        }
+                       it = args.erase(it);
                }
-       } else if (rmDirMode) {
-               removeNiUnderDirs(args.data(), args.size());
-       } 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) {
-                       int ret = createNiDll(dll, flags);
-                       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());
-                       }
+       }
+       //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
+       else if (cmd == "--ni-reset-dir") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Directory path is missing\n");
                }
-       } else if (dirMode) {
-               createNiUnderDirs(args.data(), args.size(), flags);
-       } else if (disableTacMode) {
-               for (const std::string pkg : args) {
-                       int ret = disableTACPackage(pkg);
+               while (it != args.end()) {
+                       const std::string dir[] = {std::string(*it)};
+                       removeNiUnderDirs(dir, 1);
+                       it = args.erase(it);
+               }
+       }
+       //sh-3.2# dotnettool --ni-regen-all-app
+       else if (cmd == "--ni-regen-all-app") {
+               int ret = regenerateAppNI(flags);
+               if (ret != NI_ERROR_NONE) {
+                       fprintf(stderr, "Failed to regenerate all app NI\n");
+               }
+       }
+       //sh-3.2# dotnettool --tac-regen-all
+       else if (cmd == "--tac-regen-all") {
+               int ret = regenerateTACNI(flags);
+               if (ret != NI_ERROR_NONE) {
+                       fprintf(stderr, "Failed to regenerate all TAC\n");
+               }
+       }
+       //sh-3.2# dotnettool --tac-restore-db
+       else if (cmd == "--tac-restore-db") {
+               int ret = restoreTACDB();
+               if (ret != TAC_ERROR_NONE) {
+                       fprintf(stderr, "Failed to restore TAC db\n");
+               }
+       }
+       //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
+       else if (cmd == "--tac-enable-pkg") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Package name is missing\n");
+               }
+               while (it != args.end()) {
+                       std::string pkg = std::string(*it);
+                       int ret = enableTACPackage(pkg);
                        if (ret == TAC_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        } else if (ret != TAC_ERROR_NONE) {
-                               fprintf(stderr, "Failed to disable tac [%s]\n", pkg.c_str());
-                               return -1;
+                               fprintf(stderr, "Failed to enable tac [%s]\n", pkg.c_str());
+                               break;
                        }
+                       it = args.erase(it);
                }
-       } else if (enableTacMode) {
-               for (const std::string pkg : args) {
-                       int ret = enableTACPackage(pkg);
+       }
+       //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
+       else if (cmd == "--tac-disable-pkg") {
+               if (args.size() < 1) {
+                       fprintf(stderr, "Package name is missing\n");
+               }
+               while (it != args.end()) {
+                       std::string pkg = std::string(*it);
+                       int ret = disableTACPackage(pkg);
                        if (ret == TAC_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
-                               return -1;
+                               break;
                        } else if (ret != TAC_ERROR_NONE) {
-                               fprintf(stderr, "Failed to enable tac [%s]\n", pkg.c_str());
-                               return -1;
+                               fprintf(stderr, "Failed to disable tac [%s]\n", pkg.c_str());
+                               break;
                        }
+                       it = args.erase(it);
                }
        }
+       else {
+               fprintf(stderr, "Unknown option [%s]\n", cmd.c_str());
+               DisplayUsage();
+       }
+
+       gettimeofday(&tv, NULL);
+       endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
+       fprintf(stdout, "\nSpend time for dotnettool is [%d]ms\n", (int)(endtime - starttime));
+
        return 0;
 }
index 88cc6a1..ed30fdb 100644 (file)
@@ -387,6 +387,23 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
        return 0;
 }
 
+static bool isCoreLibPrepared(DWORD flags)
+{
+       if (flags & NI_FLAGS_ENABLER2R) {
+               return true;
+       }
+
+       std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
+       if (isFileExist(coreLibBackup)) {
+               return true;
+       } else {
+               fprintf(stderr, "The native image of System.Private.CoreLib does not exist\n"
+                                       "Run the command to create the native image\n"
+                                       "# dotnettool --ni-dll /usr/share/dotnet.tizen/netcoreapp/System.Private.CoreLib.dll\n\n");
+               return false;
+       }
+}
+
 static void createCoreLibNI(DWORD flags)
 {
        std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
@@ -394,7 +411,6 @@ static void createCoreLibNI(DWORD flags)
        std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
 
        if (!isFileExist(coreLibBackup)) {
-
                if (!crossgen(coreLib, std::string(), flags)) {
                        if (rename(coreLib.c_str(), coreLibBackup.c_str())) {
                                fprintf(stderr, "Failed to rename System.Private.CoreLib.dll\n");
@@ -448,19 +464,18 @@ void finalizeNICommon()
 }
 
 
-void createNiPlatform(DWORD flags)
+ni_error_e createNiPlatform(DWORD flags)
 {
+       createCoreLibNI(flags);
+
        const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
-       createNiUnderDirs(platformDirs, 2, flags);
+       return createNiUnderDirs(platformDirs, 2, flags);
 }
 
 ni_error_e createNiDll(const std::string& dllPath, DWORD flags)
 {
-       createCoreLibNI(flags);
-       // 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;
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
        }
 
        return crossgen(dllPath, std::string(), flags);
@@ -491,6 +506,10 @@ void createNiUnderTAC(std::vector<std::string> nugets, DWORD flags)
 
 ni_error_e createTACPkgRoot(const std::string& pkgId, DWORD flags)
 {
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
+       }
+
        std::string pkgRoot;
        if (getRootPath(pkgId, pkgRoot) < 0) {
                return NI_ERROR_INVALID_PACKAGE;
@@ -538,9 +557,11 @@ ni_error_e createTACPkgRoot(const std::string& pkgId, DWORD flags)
        return NI_ERROR_NONE;
 }
 
-void createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags)
+ni_error_e createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags)
 {
-       createCoreLibNI(flags);
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
+       }
 
        std::string appPaths;
        for (int i = 0; i < count; i++) {
@@ -574,6 +595,7 @@ void createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags)
        }
 
        tpaAssemblies.clear();
+       return NI_ERROR_NONE;
 }
 
 ni_error_e createNiUnderPkgRoot(const std::string& pkgId, DWORD flags)
@@ -589,13 +611,15 @@ ni_error_e createNiUnderPkgRoot(const std::string& pkgId, DWORD flags)
        std::string paths[] = {binDir, libDir, tacDir};
 
        flags |= NI_FLAGS_APPNI;
-       createNiUnderDirs(paths, 3, flags);
-
-       return NI_ERROR_NONE;
+       return createNiUnderDirs(paths, 3, flags);
 }
 
 ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, DWORD flags)
 {
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
+       }
+
        std::string pkgRoot;
        if (getRootPath(pkgId, pkgRoot) < 0) {
                return NI_ERROR_INVALID_PACKAGE;
@@ -725,6 +749,10 @@ ni_error_e removeNiUnderPkgRoot(const std::string& pkgId)
 
 ni_error_e regenerateAppNI(DWORD flags)
 {
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
+       }
+
        int ret = 0;
        pkgmgrinfo_appinfo_metadata_filter_h handle;
 
@@ -785,6 +813,10 @@ static int regenTacCb(pkgmgrinfo_appinfo_h handle, void *userData)
 
 ni_error_e regenerateTACNI(DWORD flags)
 {
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
+       }
+
        const std::string tacDir[] = {__DOTNET_DIR};
        removeNiUnderDirs(tacDir, 1);
 
index 59a70f3..cab3ab2 100644 (file)
@@ -247,6 +247,18 @@ bool isFileExist(const std::string& path)
        return stat(path.c_str(), &sb) == 0;
 }
 
+bool isDirectoryExist(const std::string& path)
+{
+       struct stat sb;
+       if (stat(path.c_str(), &sb) != 0) {
+               return false;
+       } else if (sb.st_mode & S_IFDIR) {
+               return true;
+       } else {
+               return false;
+       }
+}
+
 uintptr_t getFileSize(const std::string& path)
 {
        struct stat sb;
@@ -609,7 +621,7 @@ void setCmdName(const std::string& name)
 
        memset(processName, '\0', PRC_NAME_LENGTH);
        snprintf(processName, PRC_NAME_LENGTH, "%s", name.c_str());
-       prctl(PR_SET_NAME, processName);                
+       prctl(PR_SET_NAME, processName);
 }
 
 std::string getFileName(const std::string& path)
index 2d3ada9..494abfa 100644 (file)
@@ -148,7 +148,6 @@ mv packaging/10.Dotnet.Launcher.preload %{buildroot}%{_tizen_preload_dir}
 %post
 mkdir -p /opt/etc/skel/.dotnet
 chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
-%{_bindir}/dotnettool --ni-dll %{_runtime_dir}/System.Private.CoreLib.dll
 
 %files
 %manifest dotnet-launcher.manifest