Add options to support crossgen2 (#351)
author조웅석/Common Platform Lab(SR)/Principal Engineer/삼성전자 <ws77.cho@samsung.com>
Wed, 5 Jan 2022 04:30:06 +0000 (13:30 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 5 Jan 2022 04:30:06 +0000 (13:30 +0900)
* remove code and options for crossgen1

* clean-up code related to pre-generating native image of System.Private.CoreLib.dll

* use NIOption structure to pass option instead of flags

* support --mibc option

* add --print-cmd option

* add --ref to set reference path

* update TC for crossgen2

* check directory existance

* check dll existance for platform assembly path

* add null check for NIOption

* Create SPC native image preferentially

* Fixed option parsing of dotnettool

Resolve option parshing error by using strncmp() function.

NativeLauncher/inc/ni_common.h
NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/tool/nitool.cc
tests/TCs/1_AOT/AOT.py
tests/TCs/6_TOOL/TOOL.py
tests/TCs/Utils.py

index 989e199..8ce0346 100644 (file)
@@ -18,6 +18,8 @@
 #define __NI_COMMON_H__
 
 #include <functional>
+#include <vector>
+#include <string>
 
 #ifndef DWORD
 #define DWORD uint32_t
 /**
  * Common flags passed to crossgen()
 */
-#define NI_FLAGS_ENABLER2R              0x0001
-#define NI_FLAGS_APPNI                  0x0002
-#define NI_FLAGS_COMPATIBILITY          0x0004
-#define NI_FLAGS_VERBOSE                0x0008
-#define NI_FLAGS_APP_UNDER_RO_AREA      0x0010
-#define NI_FLAGS_USE_CROSSGEN2          0x0100
-#define NI_FLAGS_INPUT_BUBBLE           0x0200
-#define NI_FLAGS_INPUT_BUBBLE_REF       0x0400
-#define NI_FLAGS_NO_PIPELINE            0x0800
-#define NI_FLAGS_INSTRUMENT             0x1000
+#define NI_FLAGS_APPNI                  0x0001
+#define NI_FLAGS_VERBOSE                0x0002
+#define NI_FLAGS_APP_UNDER_RO_AREA      0x0004
+#define NI_FLAGS_REF                    0x0008
+#define NI_FLAGS_INPUT_BUBBLE           0x0010
+#define NI_FLAGS_INPUT_BUBBLE_REF       0x0020
+#define NI_FLAGS_NO_PIPELINE            0x0040
+#define NI_FLAGS_MIBC                   0x0080
+#define NI_FLAGS_PRINT_CMD              0x0100
 
 typedef std::function<void (std::string)> afterCreate;
 
@@ -50,6 +51,19 @@ typedef enum {
        NI_ERROR_UNKNOWN = -9
 } ni_error_e;
 
+typedef struct NIOption{
+       DWORD flags;
+       std::vector<std::string> refPath;
+       std::vector<std::string> inputBubbleRefPath;
+       std::vector<std::string> mibcPath;
+} NIOption;
+
+/**
+ * @brief get NIOption structure for setting
+ * @return NIOption*
+ */
+NIOption* getNIOption();
+
 /**
  * @brief initialize NICommon
  * @return ni_error_e 0 on success, otherwise a negative error value
@@ -67,7 +81,7 @@ void finalizeNICommon();
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNIPlatform(DWORD flags);
+ni_error_e createNIPlatform(NIOption* opt);
 
 /**
  * @brief create a native image for a single DLL
@@ -75,7 +89,7 @@ ni_error_e createNIPlatform(DWORD flags);
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNIDll(const std::string& dllPath, DWORD flags);
+ni_error_e createNIDll(const std::string& dllPath, NIOption* opt);
 
 
 /**
@@ -84,7 +98,7 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags);
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags);
+ni_error_e createNIUnderDirs(const std::string& rootPaths, NIOption* opt);
 
 /**
  * @brief create native images for all DLLs in a package
@@ -92,7 +106,7 @@ ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags);
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags);
+ni_error_e createNIUnderPkgRoot(const std::string& pkgId, NIOption* opt);
 
 /**
  * @brief remove platform native images (.NETCore + TizenFX)
@@ -117,14 +131,14 @@ ni_error_e removeNIUnderPkgRoot(const std::string& pkgId);
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e regenerateAppNI(DWORD flags);
+ni_error_e regenerateAppNI(NIOption* opt);
 
 /**
  * @brief regenerate native image of TAC for all shared assembly.
  * @param[in] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e regenerateTACNI(DWORD flags);
+ni_error_e regenerateTACNI(NIOption* opt);
 
 /**
  * @brief remove app profile data of a package
index 57b2182..2ebd35f 100644 (file)
@@ -63,8 +63,13 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                        return -1;
                }
 
-               DWORD flags = 0;
-               if (createNIUnderPkgRoot(pkgId, flags) != NI_ERROR_NONE) {
+               NIOption* opt = getNIOption();
+               if (opt == nullptr) {
+                       _ERR("Fail to create option structure.");
+                       return -1;
+               }
+
+               if (createNIUnderPkgRoot(pkgId, opt) != NI_ERROR_NONE) {
                        _ERR("Failed to generate application to native image [%s]", pkgId);
                        return -1;
                }
index b6f51c8..6697960 100644 (file)
@@ -47,7 +47,6 @@ void DisplayUsage() {
                "       --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"
                "       --resolve-all-app         - Remove unused multi-targeting files of all apps\n"
                "                                   (this option is used for FOTA script or test)\n"
                "       --rm-app-profile          - Remove application profile of given packages for all users\n"
@@ -56,15 +55,15 @@ void DisplayUsage() {
                "                                   (this option should be run as root)\n"
                "\n"
                "Options:\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"
+               "       --ibc-dir                 - Specify a directory containing IBC files\n"
                "       --verbose                 - Display verbose information\n"
-               "       --instrument              - Generate an instrumented image for profiling (enable: /Tuning)\n"
-               "       --crossgen2               - Use crossgen2\n"
                "       --inputbubble             - Use inputbubble (run with --crossgen2 option)\n"
+               "       --inputbubbleref          - Path of references for inputbubble\n"
+               "                                   (If not set, all references are included to inputbubble.)\n"
+               "       --ref                     - Path of references\n"
+               "                                   (If not set, default system paths are used.)\n"
                "       --no-pipeline             - Compile the dlls individually (run with --crossgen2 option)\n"
-
+               "       --print-cmd               - Print command and options\n"
                "\n"
                "Usage: dotnettool [options] [command] [arguments]\n"
                "\n"
@@ -75,8 +74,8 @@ void DisplayUsage() {
                "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
                "3. Create native image under the package's bin and lib directory\n"
                "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
-               "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
-               "   # dotnettool --r2r --ni-regen-all-app\n"
+               "4. Regenerate native images for all installed .net packages\n"
+               "   # dotnettool --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"
                "6. Remove profile for package\n"
@@ -100,48 +99,86 @@ int main(int argc, char* argv[])
                return -1;
        }
 
-       //sh-3.2# dotnettool --[r2r|compatibility|instrument|verbose]
-       DWORD flags = 0;
+       NIOption* opt = getNIOption();
+       if (opt == nullptr) {
+               _SERR("Fail to create option structure.");
+               return -1;
+       }
+
        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)) {
+       for (int i = 0; i < argc; ++i) {
+               std::string arg = argv[i];
+
+               if ((arg == "-?") || (arg == "-h") || (arg == "--h")) {
                        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 if (!strncmp(*it, "--crossgen2", 11)) {
-                       flags |= NI_FLAGS_USE_CROSSGEN2;
-               } else if (!strncmp(*it, "--inputbubble", 13)) {
-                       flags |= NI_FLAGS_INPUT_BUBBLE;
-               } else if (!strncmp(*it, "--no-pipeline", 13)) {
-                       flags |= NI_FLAGS_NO_PIPELINE;
-               } else {
-                       args.push_back(*it);
-               }
-       }
+               } else if (arg == "--verbose") {
+                       opt->flags |= NI_FLAGS_VERBOSE;
+               } else if (arg == "--inputbubble") {
+                       opt->flags |= NI_FLAGS_INPUT_BUBBLE;
+               } else if (arg == "--no-pipeline") {
+                       opt->flags |= NI_FLAGS_NO_PIPELINE;
+               } else if (arg == "--print-cmd") {
+                       opt->flags |= NI_FLAGS_PRINT_CMD;
+               } else if (arg == "--ibc-dir") {
+                       ++i;
+                       if (i >= argc) {
+                               _SOUT("Directory path containing IBC files should be followed for --ibc-dir option");
+                               DisplayUsage();
+                               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);
+                       opt->flags |= NI_FLAGS_MIBC;
 
-                       std::string ibcFilePath = std::string(*it);
-                       if (!isDirectory(ibcFilePath)) {
-                               _SERR("IBC path is missing or not exist");
-                               return -1;
+                       std::vector<std::string> paths;
+                       splitPath(std::string(argv[i]), paths);
+                       for (const auto &path : paths) {
+                               if (!isDirectory(path)) {
+                                       _SERR("mibc path is missing or not exist");
+                                       return -1;
+                               }
+                               opt->mibcPath.push_back(path);
+                       }
+               } else if (arg == "--inputbubbleref") {
+                       ++i;
+                       if (i >= argc) {
+                               _SOUT("Path for references should be followed for --inputbubbleref option");
+                               DisplayUsage();
+                               return 0;
                        }
 
-                       setenv("COMPlus_IBCFileDir", const_cast<char *>(ibcFilePath.c_str()), 1);
-                       setenv("COMPlus_UseIBCFile", const_cast<char *>("1"), 1);
-                       it = args.erase(it);
+                       opt->flags |= NI_FLAGS_INPUT_BUBBLE_REF;
+
+                       std::vector<std::string> paths;
+                       splitPath(std::string(argv[i]), paths);
+                       for (const auto &path : paths) {
+                               if (!isDirectory(path)) {
+                                       _SERR("intpubbubbleref path is missing or not exist");
+                                       return -1;
+                               }
+                               opt->inputBubbleRefPath.push_back(path);
+                       }
+               } else if (arg == "--ref") {
+                       ++i;
+                       if (i >= argc) {
+                               _SOUT("Path for references should be followed for --ref option");
+                               DisplayUsage();
+                               return 0;
+                       }
+
+                       opt->flags |= NI_FLAGS_REF;
+
+                       std::vector<std::string> paths;
+                       splitPath(std::string(argv[i]), paths);
+                       for (const auto &path : paths) {
+                               if (!isDirectory(path)) {
+                                       _SERR("ref path is missing or not exist");
+                                       return -1;
+                               }
+                               opt->refPath.push_back(path);
+                       }
                } else {
-                       ++it;
+                       args.push_back(arg);
                }
        }
 
@@ -155,7 +192,7 @@ int main(int argc, char* argv[])
 
        //sh-3.2# dotnettool --ni-system
        if (cmd == "--ni-system") {
-               int ret = createNIPlatform(flags);
+               int ret = createNIPlatform(opt);
                if (ret != NI_ERROR_NONE) {
                        _SERR("Failed to generate system NI");
                }
@@ -167,7 +204,7 @@ int main(int argc, char* argv[])
                }
                while (it != args.end()) {
                        std::string dll = std::string(*it);
-                       int ret = createNIDll(dll, flags);
+                       int ret = createNIDll(dll, opt);
                        if (ret != NI_ERROR_NONE) {
                                _SERR("Failed to generate NI file [%s]", dll.c_str());
                                break;
@@ -182,7 +219,7 @@ int main(int argc, char* argv[])
                }
                while (it != args.end()) {
                        std::string pkg = std::string(*it);
-                       int ret = createNIUnderPkgRoot(pkg, flags);
+                       int ret = createNIUnderPkgRoot(pkg, opt);
                        if (ret != NI_ERROR_NONE) {
                                _SERR("Failed to generate app NI [%s]", pkg.c_str());
                                break;
@@ -197,7 +234,7 @@ int main(int argc, char* argv[])
                }
                while (it != args.end()) {
                        const std::string dir = std::string(*it);
-                       int ret = createNIUnderDirs(dir, flags);
+                       int ret = createNIUnderDirs(dir, opt);
                        if (ret != NI_ERROR_NONE) {
                                _SERR("Failed to generate NI directory");
                                break;
@@ -237,14 +274,14 @@ int main(int argc, char* argv[])
        }
        //sh-3.2# dotnettool --ni-regen-all-app
        else if (cmd == "--ni-regen-all-app") {
-               int ret = regenerateAppNI(flags);
+               int ret = regenerateAppNI(opt);
                if (ret != NI_ERROR_NONE) {
                        _SERR("Failed to regenerate all app NI");
                }
        }
        //sh-3.2# dotnettool --tac-regen-all
        else if (cmd == "--tac-regen-all") {
-               int ret = regenerateTACNI(flags);
+               int ret = regenerateTACNI(opt);
                if (ret != NI_ERROR_NONE) {
                        _SERR("Failed to regenerate all TAC");
                }
index 5f1487e..ed24af3 100644 (file)
 #endif
 #define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
 
-#ifndef CROSSGEN_PATH
-#error "CROSSGEN_PATH is missed"
-#endif
-
 #define __XSTR(x) #x
 #define __STR(x) __XSTR(x)
 #if defined(__arm__) || defined(__aarch64__)
 static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR);
 #endif
-static const char* __CROSSGEN_PATH = __STR(CROSSGEN_PATH);
 static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
 static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR);
 
@@ -86,18 +81,29 @@ static const char* CROSSGEN_OPT_OPTIMIZE = "-O";
 static const char* CROSSGEN_OPT_INPUTBUBBLE = "--inputbubble";
 static const char* CROSSGEN_OPT_COMPILE_BUBBLE_GENERICS = "--compilebubblegenerics";
 static const char* CROSSGEN_OPT_VERBOSE = "--verbose";
-static const char* CROSSGEN_OPT_TUNING = "--tuning";
 static std::vector<std::string> REF_VECTOR;
+static std::vector<std::string> INPUTBUBBLE_REF_VECTOR;
+static std::vector<std::string> MIBC_VECTOR;
 
 static int __interval = 0;
 static PathManager* __pm = nullptr;
 
-static bool isCoreLibPrepared(DWORD flags)
+static NIOption* __ni_option = nullptr;
+
+// singleton
+NIOption* getNIOption()
 {
-       if (flags & NI_FLAGS_ENABLER2R) {
-               return true;
+       if (__ni_option == nullptr) {
+               __ni_option = (NIOption*)calloc(sizeof(NIOption), 1);
+               if (__ni_option == nullptr) {
+                       _SERR("Fail to create NIOption");
+               }
        }
+       return __ni_option;
+}
 
+static bool isCoreLibPrepared()
+{
        std::string coreLibBackup = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll.Backup");
        if (isFile(coreLibBackup)) {
                return true;
@@ -195,7 +201,7 @@ static bool createDirsAndCopyOwnerShip(std::string& target_path, const std::stri
        return true;
 }
 
-static std::string getAppNIFilePath(const std::string& absDllPath, DWORD flags)
+static std::string getAppNIFilePath(const std::string& absDllPath, NIOption* opt)
 {
        std::string niDirPath;
        std::string prevPath;
@@ -203,7 +209,7 @@ static std::string getAppNIFilePath(const std::string& absDllPath, DWORD flags)
        prevPath = getBaseName(absDllPath);
        niDirPath = concatPath(prevPath, APP_NI_SUB_DIR);
 
-       if (flags & NI_FLAGS_APP_UNDER_RO_AREA) {
+       if (opt->flags & NI_FLAGS_APP_UNDER_RO_AREA) {
                niDirPath = replaceAll(niDirPath, getBaseName(__pm->getAppRootPath()), __READ_ONLY_APP_UPDATE_DIR);
                _SERR("App is installed in RO area. Change NI path to RW area(%s).", niDirPath.c_str());
                _ERR("App is installed in RO area. Change NI path to RW area(%s).", niDirPath.c_str());
@@ -281,227 +287,7 @@ static ni_error_e getTargetDllList(const std::string& path, std::vector<std::str
        return NI_ERROR_NONE;
 }
 
-#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
-static uintptr_t getFileSize(const std::string& path)
-{
-       struct stat sb;
-
-       if (stat(path.c_str(), &sb) == 0) {
-               return sb.st_size;
-       }
-
-       return 0;
-}
-
-// Get next base address to be used for system ni image from file
-// __SYSTEM_BASE_FILE should be checked for existance before calling this function
-static uintptr_t getNextBaseAddrFromFile()
-{
-       FILE *pFile = fopen(__SYSTEM_BASE_FILE, "r");
-       if (pFile == NULL) {
-               _SERR("Failed to open %s", __SYSTEM_BASE_FILE);
-               return 0;
-       }
-
-       uintptr_t addr = 0;
-       uintptr_t size = 0;
-
-       while (fscanf(pFile, "%" SCNxPTR " %" SCNuPTR "", &addr, &size) != EOF) {
-       }
-
-       fclose(pFile);
-
-       return addr + size;
-}
-
-// Get next base address to be used for system ni image
-static uintptr_t getNextBaseAddr()
-{
-       uintptr_t baseAddr = 0;
-
-       if (!isFile(__SYSTEM_BASE_FILE)) {
-               // This is the starting address for all default base addresses
-               baseAddr = DEFAULT_BASE_ADDR_START;
-       } else {
-               baseAddr = getNextBaseAddrFromFile();
-
-               // Round to a multple of 64K (see ZapImage::CalculateZapBaseAddress in CoreCLR)
-               uintptr_t BASE_ADDRESS_ALIGNMENT = 0xffff;
-               baseAddr = (baseAddr + BASE_ADDRESS_ALIGNMENT) & ~BASE_ADDRESS_ALIGNMENT;
-       }
-
-       return baseAddr;
-}
-
-// Save base address of system ni image to file
-static void updateBaseAddrFile(const std::string& absNIPath, uintptr_t baseAddr)
-{
-       uintptr_t niSize = getFileSize(absNIPath);
-       if (niSize == 0) {
-               _SERR("File %s doesn't exist", absNIPath.c_str());
-               return;
-       }
-
-       // Write new entry to the file
-       FILE *pFile = fopen(__SYSTEM_BASE_FILE, "a");
-       if (pFile == NULL) {
-               _SERR("Failed to open %s", __SYSTEM_BASE_FILE);
-               return;
-       }
-
-       fprintf(pFile, "%" PRIxPTR " %" PRIuPTR "\n", baseAddr, niSize);
-       fclose(pFile);
-}
-
-// check if dll is listed in TPA
-static bool isTPADll(const std::string& dllPath)
-{
-       std::string absPath = getBaseName(getAbsolutePath(dllPath));
-
-       std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
-       for (unsigned int i = 0; i < paths.size(); i++) {
-               if (paths[i].find(getBaseName(absPath)) != std::string::npos) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-#endif
-
-// baseAddr should be checked in file before getting here
-static ni_error_e crossgen(const std::string& dllPath, const std::string& appPath, DWORD flags)
-{
-       std::string absDllPath = getAbsolutePath(dllPath);
-       std::string absNIPath;
-
-       bool isAppNI = flags & NI_FLAGS_APPNI;
-       if (isAppNI && strstr(absDllPath.c_str(), __DOTNET_DIR) == NULL) {
-               absNIPath = getAppNIFilePath(absDllPath, flags);
-               if (exist(absNIPath)) {
-                       return NI_ERROR_ALREADY_EXIST;
-               }
-       } else {
-               absNIPath = getNIFilePath(absDllPath);
-               if (checkNIExistence(absDllPath)) {
-                       return NI_ERROR_ALREADY_EXIST;
-               }
-       }
-
-       if (absNIPath.empty()) {
-               _SERR("Fail to get ni file name");
-               return NI_ERROR_UNKNOWN;
-       }
-
-#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
-       uintptr_t baseAddr = 0;
-
-       if (isTPADll(dllPath)) {
-               baseAddr = getNextBaseAddr();
-       }
-#endif
-
-       pid_t pid = fork();
-       if (pid == -1)
-               return NI_ERROR_UNKNOWN;
-
-       if (pid > 0) {
-               int status;
-               waitpid(pid, &status, 0);
-               if (WIFEXITED(status)) {
-                       // Do not use checkNIExistence() function to check whether ni file created or not.
-                       // checkNIExistence() return false for System.Private.Corelib.dll
-                       if (isFile(absNIPath)) {
-                               copySmackAndOwnership(absDllPath, absNIPath);
-                               std::string absPdbPath = replaceAll(absDllPath, ".dll", ".pdb");
-                               std::string pdbFilePath = replaceAll(absNIPath, ".ni.dll", ".pdb");
-                               if (isFile(absPdbPath) && (absPdbPath != pdbFilePath)) {
-                                       if (!copyFile(absPdbPath, pdbFilePath)) {
-                                               _SERR("Failed to copy a .pdb file");
-                                       } else {
-                                               copySmackAndOwnership(absPdbPath, pdbFilePath);
-                                       }
-                               }
-#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
-                               if (baseAddr != 0) {
-                                       updateBaseAddrFile(absNIPath, baseAddr);
-                               }
-#endif
-                               return NI_ERROR_NONE;
-                       } else {
-                               _SERR("Fail to create native image for %s", dllPath.c_str());
-                               return NI_ERROR_NO_SUCH_FILE;
-                       }
-               }
-       } else {
-               std::string jitPath = __pm->getRuntimePath() + "/libclrjit.so";
-               std::vector<const char*> argv = {
-                       __CROSSGEN_PATH,
-                       "/nologo",
-                       "/JITPath", jitPath.c_str()
-               };
-
-               bool compat = flags & NI_FLAGS_COMPATIBILITY;
-               argv.push_back(compat ? "/Platform_Assemblies_Pathes" : "/p");
-               std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
-               std::string platformAssembliesPaths;
-               for (const auto &path : paths) {
-                       if (!platformAssembliesPaths.empty()) {
-                               platformAssembliesPaths += ":";
-                       }
-                       platformAssembliesPaths += path;
-               }
-               argv.push_back(platformAssembliesPaths.c_str());
-
-               bool enableR2R = flags & NI_FLAGS_ENABLER2R;
-               if (!enableR2R) {
-                       argv.push_back("/FragileNonVersionable");
-               }
-
-               if (flags & NI_FLAGS_VERBOSE) {
-                       argv.push_back("/verbose");
-               }
-
-               if (flags & NI_FLAGS_INSTRUMENT) {
-                       argv.push_back("/Tuning");
-               }
-
-#ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
-               std::string baseAddrString;
-               if (baseAddr != 0) {
-                       argv.push_back("/BaseAddress");
-                       std::stringstream ss;
-                       ss << "0x" << std::hex << baseAddr;
-                       baseAddrString = ss.str();
-                       argv.push_back(baseAddrString.c_str());
-               }
-#endif
-
-               argv.push_back("/App_Paths");
-               std::string absAppPath;
-               if (!appPath.empty()) {
-                       absAppPath = appPath;
-               } else {
-                       absAppPath = getBaseName(absDllPath);
-               }
-               argv.push_back(absAppPath.c_str());
-
-               argv.push_back("/out");
-               argv.push_back(absNIPath.c_str());
-
-               argv.push_back(absDllPath.c_str());
-               argv.push_back(nullptr);
-
-               _SOUT("+ %s (%s)", absDllPath.c_str(), enableR2R ? "R2R" : "FNV");
-
-               execv(__CROSSGEN_PATH, const_cast<char* const*>(argv.data()));
-               exit(0);
-       }
-
-       return NI_ERROR_NONE;
-}
-
-static void makeArgs(std::vector<const char*>& args, const std::vector<std::string>& refPaths, DWORD flags)
+static void makeArgs(std::vector<const char*>& args, const std::vector<std::string>& refPaths, NIOption* opt)
 {
        args.push_back(CORERUN_CMD);
        args.push_back(CROSSGEN2_PATH);
@@ -509,7 +295,7 @@ static void makeArgs(std::vector<const char*>& args, const std::vector<std::stri
        args.push_back(CLRJIT_PATH);
        args.push_back(CROSSGEN_OPT_TARGET_ARCH);
        args.push_back(ARCHITECTURE_IDENTIFIER);
-       if (!(flags & NI_FLAGS_NO_PIPELINE)) {
+       if (!(opt->flags & NI_FLAGS_NO_PIPELINE)) {
                args.push_back(CROSSGEN_OPT_OUT_NEAR_INPUT);
                args.push_back(CROSSGEN_OPT_SINGLE_FILE_COMPILATION);
        }
@@ -519,25 +305,58 @@ static void makeArgs(std::vector<const char*>& args, const std::vector<std::stri
 
        args.push_back(CROSSGEN_OPT_OPTIMIZE);
 
-       if (flags & NI_FLAGS_INPUT_BUBBLE) {
+       if (opt->flags & NI_FLAGS_INPUT_BUBBLE) {
                args.push_back(CROSSGEN_OPT_INPUTBUBBLE);
                args.push_back(CROSSGEN_OPT_COMPILE_BUBBLE_GENERICS);
+
+               if (opt->flags & NI_FLAGS_INPUT_BUBBLE_REF) {
+                       INPUTBUBBLE_REF_VECTOR.clear();
+                       // check inputbubbleref format.
+                       for (const auto &path : opt->inputBubbleRefPath) {
+                               if (checkDllExistInDir(path)) {
+                                       INPUTBUBBLE_REF_VECTOR.push_back("--inputbubbleref:" + path + "/*.dll");
+                               }
+                       }
+                       // add ref path to inputbubble ref
+                       for (const auto &path : refPaths) {
+                               if (checkDllExistInDir(path)) {
+                                       INPUTBUBBLE_REF_VECTOR.push_back("--inputbubbleref:" + path + "/*.dll");
+                               }
+                       }
+                       for (const auto &path : INPUTBUBBLE_REF_VECTOR) {
+                               args.push_back(path.c_str());
+                       }
+               }
        }
 
-       if (flags & NI_FLAGS_VERBOSE) {
-               args.push_back(CROSSGEN_OPT_VERBOSE);
+       if (opt->flags & NI_FLAGS_MIBC) {
+               MIBC_VECTOR.clear();
+               for (const auto &path : opt->mibcPath) {
+                       MIBC_VECTOR.push_back("--mibc:" + path);
+               }
+               for (const auto &path : MIBC_VECTOR) {
+                       args.push_back(path.c_str());
+               }
        }
 
-       if (flags & NI_FLAGS_INSTRUMENT) {
-               args.push_back(CROSSGEN_OPT_TUNING);
+       if (opt->flags & NI_FLAGS_VERBOSE) {
+               args.push_back(CROSSGEN_OPT_VERBOSE);
        }
 
        REF_VECTOR.clear();
 
        // set reference path
-       std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
-       for (const auto &path : paths) {
-               REF_VECTOR.push_back("-r:" + path + "/*.dll");
+       if (opt->flags & NI_FLAGS_REF) {
+               for (const auto &path : opt->refPath) {
+                       REF_VECTOR.push_back("-r:" + path + "/*.dll");
+               }
+       } else {
+               std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
+               for (const auto &path : paths) {
+                       if (checkDllExistInDir(path)) {
+                               REF_VECTOR.push_back("-r:" + path + "/*.dll");
+                       }
+               }
        }
 
        for (const auto &path : refPaths) {
@@ -576,7 +395,7 @@ static ni_error_e makePdbSymlinkForNI(std::string dllPath, std::string niPath)
        return NI_ERROR_NONE;
 }
 
-static ni_error_e crossgen2PipeLine(const std::vector<std::string>& dllList, const std::vector<std::string>& refPaths, DWORD flags)
+static ni_error_e crossgen2PipeLine(const std::vector<std::string>& dllList, const std::vector<std::string>& refPaths, NIOption* opt)
 {
        // fork crossgen2
        pid_t pid = fork();
@@ -597,19 +416,20 @@ static ni_error_e crossgen2PipeLine(const std::vector<std::string>& dllList, con
 
                                copySmackAndOwnership(dllPath, niPath);
                                // if AppNI then move ni.dll file to .native_image and copy pdb to .native_image
-                               if (flags & NI_FLAGS_APPNI) {
-                                       std::string appNIPath = getAppNIFilePath(dllPath, flags);
+                               if (opt->flags & NI_FLAGS_APPNI) {
+                                       std::string appNIPath = getAppNIFilePath(dllPath, opt);
                                        moveFile(niPath, appNIPath);
                                        makePdbSymlinkForNI(dllPath, appNIPath);
                                        niPath = appNIPath;
                                }
+
                                _SOUT("Native image %s generated successfully.", niPath.c_str());
                        }
                }
        } else {
                std::vector<const char*> argv;
 
-               makeArgs(argv, refPaths, flags);
+               makeArgs(argv, refPaths, opt);
 
                // add input files at the end of parameter
                for (const auto &input : dllList) {
@@ -620,7 +440,10 @@ static ni_error_e crossgen2PipeLine(const std::vector<std::string>& dllList, con
                argv.push_back(nullptr);
 
                // print cmd
-               //for (auto &arg: argv) _SOUT("+ %s", arg);
+               if (opt->flags & NI_FLAGS_PRINT_CMD) {
+                       _SOUT("==================== NI Commands =========================");
+                       for (auto &arg: argv) _SOUT("+ %s", arg);
+               }
 
                execv(CORERUN_CMD, const_cast<char* const*>(argv.data()));
 
@@ -631,12 +454,12 @@ static ni_error_e crossgen2PipeLine(const std::vector<std::string>& dllList, con
        return NI_ERROR_NONE;
 }
 
-static ni_error_e crossgen2NoPipeLine(const std::vector<std::string>& dllList, const std::vector<std::string>& refPaths, DWORD flags)
+static ni_error_e crossgen2NoPipeLine(const std::vector<std::string>& dllList, const std::vector<std::string>& refPaths, NIOption* opt)
 {
        for (auto& dllPath : dllList) {
                std::string niPath;
-               if (flags & NI_FLAGS_APPNI) {
-                       niPath = getAppNIFilePath(dllPath, flags);
+               if (opt->flags & NI_FLAGS_APPNI) {
+                       niPath = getAppNIFilePath(dllPath, opt);
                } else {
                        niPath = getNIFilePath(dllPath);
                }
@@ -656,14 +479,15 @@ static ni_error_e crossgen2NoPipeLine(const std::vector<std::string>& dllList, c
                                }
 
                                copySmackAndOwnership(dllPath, niPath);
-                               if (flags & NI_FLAGS_APPNI) {
+                               if (opt->flags & NI_FLAGS_APPNI) {
                                        makePdbSymlinkForNI(dllPath, niPath);
                                }
+
                                _SOUT("Native image %s generated successfully.", niPath.c_str());
                        }
                } else {
                        std::vector<const char*> argv;
-                       makeArgs(argv, refPaths, flags);
+                       makeArgs(argv, refPaths, opt);
 
                        argv.push_back("-o");
                        argv.push_back(niPath.c_str());
@@ -675,7 +499,10 @@ static ni_error_e crossgen2NoPipeLine(const std::vector<std::string>& dllList, c
                        argv.push_back(nullptr);
 
                        // print cmd
-                       //for (auto &arg: argv) _SOUT("+ %s", arg);
+                       if (opt->flags & NI_FLAGS_PRINT_CMD) {
+                               _SOUT("==================== NI Commands =========================");
+                               for (auto &arg: argv) _SOUT("+ %s", arg);
+                       }
 
                        execv(CORERUN_CMD, const_cast<char* const*>(argv.data()));
 
@@ -689,8 +516,7 @@ static ni_error_e crossgen2NoPipeLine(const std::vector<std::string>& dllList, c
        return NI_ERROR_NONE;
 }
 
-
-static ni_error_e doAOTList(std::vector<std::string>& dllList, const std::string& refPaths, DWORD flags)
+static ni_error_e doAOTList(std::vector<std::string>& dllList, const std::string& refPaths, NIOption* opt)
 {
        if (dllList.empty()) {
                return NI_ERROR_INVALID_PARAMETER;
@@ -710,31 +536,19 @@ static ni_error_e doAOTList(std::vector<std::string>& dllList, const std::string
                }
        }
 
-       if (!isFile(concatPath(__pm->getRuntimePath(), "crossgen"))) {
-               _SERR("crossgen1 doesnot supported. use crossgen2 forcibily");
-               flags |= NI_FLAGS_USE_CROSSGEN2;
-       }
-
-       if (flags & NI_FLAGS_USE_CROSSGEN2) {           // crossgen2
-               std::vector<std::string> paths;
-               splitPath(refPaths, paths);
+       std::vector<std::string> paths;
+       splitPath(refPaths, paths);
 
-               if (flags & NI_FLAGS_NO_PIPELINE) {
-                       crossgen2NoPipeLine(dllList, paths, flags);
-               } else {
-                       crossgen2PipeLine(dllList, paths, flags);
-               }
-       } else {                                                                        // crossgen1
-               for (auto& dll : dllList) {
-                       crossgen(dll, refPaths, flags);
-                       waitInterval();
-               }
+       if (opt->flags & NI_FLAGS_NO_PIPELINE) {
+               crossgen2NoPipeLine(dllList, paths, opt);
+       } else {
+               crossgen2PipeLine(dllList, paths, opt);
        }
 
        return NI_ERROR_NONE;
 }
 
-static ni_error_e doAOTFile(const std::string& dllFile, const std::string& refPaths, DWORD flags)
+static ni_error_e doAOTFile(const std::string& dllFile, const std::string& refPaths, NIOption* opt)
 {
        if (!isFile(dllFile)) {
                _SERR("dll file is not exist : %s", dllFile.c_str());
@@ -748,7 +562,7 @@ static ni_error_e doAOTFile(const std::string& dllFile, const std::string& refPa
 
        std::vector<std::string> dllList;
        dllList.push_back(getAbsolutePath(dllFile));
-       return doAOTList(dllList, refPaths, flags);
+       return doAOTList(dllList, refPaths, opt);
 }
 
 // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
@@ -756,7 +570,7 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
        int ret = 0;
-       DWORD *pFlags = (DWORD*)userData;
+       NIOption **pOptions = (NIOption**)userData;
 
        ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
        if (ret != PMINFO_R_OK) {
@@ -769,7 +583,7 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
                return -1;
        }
 
-       if (createNIUnderPkgRoot(pkgId, *pFlags) != NI_ERROR_NONE) {
+       if (createNIUnderPkgRoot(pkgId, *pOptions) != NI_ERROR_NONE) {
                _SERR("Failed to generate NI file [%s]", pkgId);
                return -1;
        } else {
@@ -779,14 +593,14 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
        return 0;
 }
 
-static ni_error_e createCoreLibNI(DWORD flags)
+static ni_error_e createCoreLibNI(NIOption* opt)
 {
        std::string coreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll");
        std::string niCoreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.ni.dll");
        std::string coreLibBackup = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll.Backup");
 
        if (!isFile(coreLibBackup) && !hasCoreLibNI()) {
-               if (doAOTFile(coreLib, std::string(), flags) == NI_ERROR_NONE) {
+               if (doAOTFile(coreLib, std::string(), opt) == NI_ERROR_NONE && exist(niCoreLib)) {
                        if (rename(coreLib.c_str(), coreLibBackup.c_str())) {
                                _SERR("Failed to rename System.Private.CoreLib.dll");
                                return NI_ERROR_CORE_NI_FILE;
@@ -851,32 +665,37 @@ void finalizeNICommon()
 
        delete(__pm);
        __pm = nullptr;
+
+       if (__ni_option) {
+               free(__ni_option);
+               __ni_option = nullptr;
+       }
 }
 
-ni_error_e createNIPlatform(DWORD flags)
+ni_error_e createNIPlatform(NIOption* opt)
 {
-       ni_error_e ret = createCoreLibNI(flags);
+       ni_error_e ret = createCoreLibNI(opt);
        if (ret != NI_ERROR_NONE) {
                return ret;
        }
 
-       return createNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath(), flags);
+       return createNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath(), opt);
 }
 
-ni_error_e createNIDll(const std::string& dllPath, DWORD flags)
+ni_error_e createNIDll(const std::string& dllPath, NIOption* opt)
 {
        if (dllPath.find("System.Private.CoreLib.dll") != std::string::npos) {
-               return createCoreLibNI(flags);
+               return createCoreLibNI(opt);
        }
 
-       if (!isCoreLibPrepared(flags)) {
+       if (!isCoreLibPrepared()) {
                return NI_ERROR_CORE_NI_FILE;
        }
 
-       return doAOTFile(dllPath, std::string(), flags);
+       return doAOTFile(dllPath, std::string(), opt);
 }
 
-ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& refPaths, DWORD flags)
+ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& refPaths, NIOption* opt)
 {
        ni_error_e ret;
 
@@ -900,9 +719,9 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re
        if (!needNIList.empty()) {
                // NI fils of TAC-related dlls under /opt/usr/dotnet should not be created under .native_image directory.
                // So, unset NI_FLAGS_APPNI temporally and restore it after running AOT.
-               flags &= ~NI_FLAGS_APPNI;
-               ret = doAOTList(needNIList, refPaths, flags);
-               flags |= NI_FLAGS_APPNI;
+               opt->flags &= ~NI_FLAGS_APPNI;
+               ret = doAOTList(needNIList, refPaths, opt);
+               opt->flags |= NI_FLAGS_APPNI;
                if (ret != NI_ERROR_NONE) {
                        return ret;
                }
@@ -924,10 +743,10 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re
 }
 
 
-ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags)
+ni_error_e createNIUnderDirs(const std::string& rootPaths, NIOption* opt)
 {
        ni_error_e ret = NI_ERROR_NONE;
-       if (!isCoreLibPrepared(flags)) {
+       if (!isCoreLibPrepared()) {
                return NI_ERROR_CORE_NI_FILE;
        }
 
@@ -941,7 +760,7 @@ ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags)
                }
 
                if (path.find(TAC_SYMLINK_SUB_DIR) != std::string::npos) {
-                       ret = createNIUnderTAC(path, rootPaths, flags);
+                       ret = createNIUnderTAC(path, rootPaths, opt);
                        if (ret != NI_ERROR_NONE) {
                                return ret;
                        }
@@ -957,10 +776,10 @@ ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags)
                return NI_ERROR_NONE;
        }
 
-       return doAOTList(fileList, rootPaths, flags);
+       return doAOTList(fileList, rootPaths, opt);
 }
 
-ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags)
+ni_error_e createNIUnderPkgRoot(const std::string& pkgId, NIOption* opt)
 {
        std::string rootPath = getRootPath(pkgId);
        if (rootPath.empty()) {
@@ -970,19 +789,19 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags)
 
        __pm->setAppRootPath(rootPath);
 
-       flags |= NI_FLAGS_APPNI;
+       opt->flags |= NI_FLAGS_APPNI;
 
        if (isReadOnlyArea(rootPath)) {
-               flags |= NI_FLAGS_APP_UNDER_RO_AREA;
-               flags |= NI_FLAGS_NO_PIPELINE;
+               opt->flags |= NI_FLAGS_APP_UNDER_RO_AREA;
+               opt->flags |= NI_FLAGS_NO_PIPELINE;
                _SERR("Only no-pipeline mode supported for RO app. Set no-pipeline option forcibly");
        } else {
-               flags &= ~NI_FLAGS_APP_UNDER_RO_AREA;
+               opt->flags &= ~NI_FLAGS_APP_UNDER_RO_AREA;
        }
 
        // create native image under bin and lib directory
        // tac directory is skipped in the createNIUnderDirs.
-       return createNIUnderDirs(__pm->getAppPaths(), flags);
+       return createNIUnderDirs(__pm->getAppPaths(), opt);
 }
 
 void removeNIPlatform()
@@ -1073,9 +892,9 @@ ni_error_e removeNIUnderPkgRoot(const std::string& pkgId)
        return NI_ERROR_NONE;
 }
 
-ni_error_e regenerateAppNI(DWORD flags)
+ni_error_e regenerateAppNI(NIOption* opt)
 {
-       if (!isCoreLibPrepared(flags)) {
+       if (!isCoreLibPrepared()) {
                return NI_ERROR_CORE_NI_FILE;
        }
 
@@ -1092,7 +911,7 @@ ni_error_e regenerateAppNI(DWORD flags)
                return NI_ERROR_UNKNOWN;
        }
 
-       ret = pkgmgrMDFilterForeach(handle, appAotCb, &flags);
+       ret = pkgmgrMDFilterForeach(handle, appAotCb, &opt);
        if (ret != 0) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
                return NI_ERROR_UNKNOWN;
@@ -1106,7 +925,7 @@ ni_error_e regenerateAppNI(DWORD flags)
 static int regenTacCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
-       DWORD *pFlags = (DWORD*)userData;
+       NIOption **pOpt = (NIOption**)userData;
 
        int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
        if (ret != PMINFO_R_OK || pkgId == NULL) {
@@ -1139,15 +958,15 @@ static int regenTacCb(pkgmgrinfo_appinfo_h handle, void *userData)
        }
 
        for (auto& nuget : nugets) {
-               createNIUnderTAC(concatPath(__DOTNET_DIR, nuget), nugetPaths, *pFlags);
+               createNIUnderTAC(concatPath(__DOTNET_DIR, nuget), nugetPaths, *pOpt);
        }
 
        return 0;
 }
 
-ni_error_e regenerateTACNI(DWORD flags)
+ni_error_e regenerateTACNI(NIOption* opt)
 {
-       if (!isCoreLibPrepared(flags)) {
+       if (!isCoreLibPrepared()) {
                return NI_ERROR_CORE_NI_FILE;
        }
 
@@ -1165,7 +984,7 @@ ni_error_e regenerateTACNI(DWORD flags)
                return NI_ERROR_UNKNOWN;
        }
 
-       ret = pkgmgrMDFilterForeach(handle, regenTacCb, &flags);
+       ret = pkgmgrMDFilterForeach(handle, regenTacCb, &opt);
        if (ret != 0) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
                return NI_ERROR_UNKNOWN;
index bbed3f2..b48c076 100644 (file)
@@ -49,7 +49,6 @@ static void help(const char *argv0)
 
 int main(int argc, char* argv[])
 {
-       DWORD flags = 0;
        bool pkgMode = false;
        bool dllMode = false;
        bool rmPkgMode = false;
@@ -58,18 +57,15 @@ int main(int argc, char* argv[])
                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;
+       NIOption* opt = getNIOption();
+       if (opt == nullptr) {
+               _SERR("Fail to create option structure.");
+               return -1;
        }
+
+       // Parse optional switches first.
        if (cmdOptionExists(argv, argv+argc, "--verbose")) {
-               flags |= NI_FLAGS_VERBOSE;
+               opt->flags |= NI_FLAGS_VERBOSE;
        }
 
        // The following commands are mutually exclusive.
@@ -77,7 +73,7 @@ int main(int argc, char* argv[])
                help(argv[0]);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--system")) {
-               createNIPlatform(flags);
+               createNIPlatform(opt->flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--dll")) {
                dllMode = true;
@@ -89,7 +85,7 @@ int main(int argc, char* argv[])
        } else if (cmdOptionExists(argv, argv+argc, "--reset-pkg")) {
                rmPkgMode = true;
        } else if (cmdOptionExists(argv, argv+argc, "--regen-all-app")) {
-               regenerateAppNI(flags);
+               regenerateAppNI(opt->flags);
                return 0;
        } else {
                help(argv[0]);
@@ -110,7 +106,7 @@ int main(int argc, char* argv[])
        if (pkgMode) {
                for (const std::string pkg : args) {
                        // if there is AOTed dlls under package root, that is skiped.
-                       int ret = createNIUnderPkgRoot(pkg, flags);
+                       int ret = createNIUnderPkgRoot(pkg, opt->flags);
                        if (ret == NI_ERROR_INVALID_PACKAGE) {
                                _SERR("Failed to get root path from [%s]", pkg.c_str());
                                return -1;
@@ -134,7 +130,7 @@ int main(int argc, char* argv[])
                // 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);
+                       int ret = createNIDll(dll, opt->flags);
                        if (ret == NI_ERROR_ALREADY_EXIST) {
                                // skip for already exist case
                        } else if (ret != NI_ERROR_NONE) {
index f32488b..6c1ff6d 100755 (executable)
@@ -100,13 +100,13 @@ def TC_03():
     if root_path == "None":
         return f"FAIL : Get the root path for {pkg_id}"
 
-    if exist(f"{root_path}/bin/.native_image"):
-        return "FAIL : The .native_image folder should not exist"
+    if not exist(f"{root_path}/bin/.native_image"):
+        return "FAIL : The .native_image folder should exist"
 
     raw = cmd(f"shell find {root_path}/bin/ -name *.ni.dll")
     lines = [l for l in raw.splitlines()]
-    if len(lines) != 0:
-        return "FAIL : The .ni.dll files should not exist"
+    if len(lines) == 0:
+        return "FAIL : The .ni.dll files should exist"
 
     return "PASS"
 
index 7629d7a..5e8a61a 100755 (executable)
@@ -22,7 +22,7 @@ def TC_01():
 
 # The `native image` is generated normally.
 def TC_02():
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-system")
+    cmd(f"shell dotnettool --ni-system")
 
     if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
         return "FAIL : Create the platform native image"
@@ -58,7 +58,7 @@ def TC_02():
 
 # Remove the `platform` native image.
 def TC_03():
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-reset-system")
+    cmd(f"shell dotnettool --ni-reset-system")
 
     if exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
         return "FAIL : Remove the platform native image"
@@ -71,9 +71,9 @@ def TC_04():
         cmd(f"shell rm {RUNTIME_DIR}{SPC_DLL}")
         cmd(f"shell mv {RUNTIME_DIR}{SPC_DLL}.Backup {RUNTIME_DIR}{SPC_DLL}")
 
-    raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-dll {RUNTIME_DIR}{SPC_DLL}")
+    raw = cmd(f"shell dotnettool --ni-dll {RUNTIME_DIR}{SPC_DLL}")
     if (f"{SPC_DLL}" not in raw) or \
-       ("System.Private.CoreLib.ni.dll generated successfully." not in raw):
+       ("System.Private.CoreLib.dll generated successfully." not in raw):
         return f"FAIL : Create native image for {SPC_DLL}"
 
     if not exist(f"{RUNTIME_DIR}{SPC_DLL}.Backup"):
@@ -83,7 +83,7 @@ def TC_04():
 
 # The file name of `.dll` and `.ni.dll` must match in the framework.
 def TC_05():
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-dir {FRAMEWORK_DIR}")
+    cmd(f"shell dotnettool --ni-dir {FRAMEWORK_DIR}")
     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.ni.dll")
     lines1 = [l for l in raw.splitlines()]
     raw = cmd(f"shell find {FRAMEWORK_DIR} -name *.dll -not -name *.ni.dll")
@@ -114,7 +114,7 @@ def TC_06():
 
 # Create native image for Tizen.dll in `R2R` mode.
 def TC_07():
-    raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --r2r --ni-dll {FRAMEWORK_DIR}Tizen.dll")
+    raw = cmd(f"shell dotnettool --r2r --ni-dll {FRAMEWORK_DIR}Tizen.dll")
     if ("Tizen.dll" not in raw) or \
        ("Tizen.ni.dll generated successfully." not in raw):
         return "FAIL : Create native image for Tizen.dll in R2R mode"
@@ -123,7 +123,7 @@ def TC_07():
 
 # Displays detailed information while creating native image for Tizen.Log.dll.
 def TC_08():
-    raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --verbose --ni-dll {FRAMEWORK_DIR}Tizen.Log.dll")
+    raw = cmd(f"shell dotnettool --verbose --ni-dll {FRAMEWORK_DIR}Tizen.Log.dll")
     if ("Tizen.Log.ni.dll generated successfully." not in raw):
         return "FAIL : Displays detailed information while creating native image for Tizen.Log.dll"
 
@@ -150,7 +150,7 @@ def TC_09():
     if not exist(f"{IBCDATA_DIR}netstandard.ibc"):
         return "FAIL : The netstandard.ibc file should exist"
 
-    raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ibc-dir /usr/share/dotnet.tizen/ibcdata/ --ni-dll {RUNTIME_DIR}netstandard.dll")
+    raw = cmd(f"shell dotnettool --ibc-dir /usr/share/dotnet.tizen/ibcdata/ --ni-dll {RUNTIME_DIR}netstandard.dll")
     if ("netstandard.dll" not in raw) or \
        ("netstandard.ni.dll generated successfully." not in raw):
         return "FAIL : Create native image for netstandard.dll"
@@ -209,7 +209,7 @@ def TC_11():
     if exist(f"{root_path}/bin/.native_image"):
         return "FAIL : The .native_image folder not should exist"
 
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-pkg {pkg_id}")
+    cmd(f"shell dotnettool --ni-pkg {pkg_id}")
 
     if not exist(f"{root_path}/bin/.native_image"):
         return "FAIL : The .native_image folder should exist"
@@ -243,7 +243,7 @@ def TC_12():
     if "OK" not in app_install(f"{tpk_path}"):
         return f"FAIL : Install the application for {tpk_path}"
 
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-regen-all-app")
+    cmd(f"shell dotnettool --ni-regen-all-app")
 
     raw = subprocess.run((f"sdb -s {serial} shell pkginfo --metadata-flt").split(), stdout=subprocess.PIPE, input=f"http://tizen.org/metadata/prefer_dotnet_aot\ntrue\n", encoding="utf-8").stdout
     lines = [l for l in raw.splitlines() if "appid" in l]
@@ -283,7 +283,7 @@ def TC_13():
     if "OK" not in app_install(f"{tpk_path}"):
         return f"FAIL : Install the application for {tpk_path}"
 
-    raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --tac-regen-all")
+    raw = cmd(f"shell dotnettool --tac-regen-all")
     if (".dll" not in raw) or \
        (".ni.dll generated successfully." not in raw):
         return "FAIL : Create native image for TAC"
@@ -437,7 +437,7 @@ def TC_17():
 
     cmd(f"shell mount -o remount,ro /")
 
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-regen-all-app")
+    cmd(f"shell dotnettool --ni-regen-all-app")
 
     raw = subprocess.run((f"sdb -s {serial} shell pkginfo --metadata-flt").split(), stdout=subprocess.PIPE, input=f"http://tizen.org/metadata/prefer_dotnet_aot\ntrue\n", encoding="utf-8").stdout
     lines = [l for l in raw.splitlines() if "appid" in l]
@@ -519,7 +519,7 @@ def TC_19():
     if exist(f"{root_path}/bin/.native_image"):
         return "FAIL : The .native_image folder not should exist"
 
-    cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-pkg {pkg_id}")
+    cmd(f"shell dotnettool --ni-pkg {pkg_id}")
 
     if not exist(f"{DOTNET_DIR}apps/{pkg_id}/bin/.native_image"):
         return "FAIL : The .native_image folder should exist"
@@ -598,7 +598,8 @@ def main():
             else:
                 tc_array.append(funcMap[tc_num])
     else:
-        tc_array = [TC_01, TC_02, TC_03, TC_04, TC_05, TC_06, TC_07, TC_08, TC_09, TC_10, TC_11, TC_12, TC_13, TC_14, TC_15, TC_16, TC_17, TC_18, TC_19]
+        # skip TC_07 (--r2r), TC_09 (--ibc-dir)
+        tc_array = [TC_01, TC_02, TC_03, TC_04, TC_05, TC_06, TC_08, TC_10, TC_11, TC_12, TC_13, TC_14, TC_15, TC_16, TC_17, TC_18, TC_19]
 
     global serial
     if len(sys.argv) >= 2 and "TC_" not in sys.argv[1]:
index 03928b6..ae6a785 100755 (executable)
@@ -13,7 +13,6 @@ IBCDATA_DIR = "/usr/share/dotnet.tizen/ibcdata/"
 DOTNET_DIR = "/opt/usr/dotnet/"
 OWNER_DIR = "/home/owner/"
 SPC_DLL = "System.Private.CoreLib.dll"
-CROSSGEN2_OPTION = "--crossgen2"
 
 # Check the sdb connection status and get a device serial number
 def read_serial(serial):
@@ -114,8 +113,8 @@ def get_device_type():
 def create_spc_ni():
     raw = cmd(f"shell find {RUNTIME_DIR} -name {SPC_DLL}.Backup")
     if f"{RUNTIME_DIR}{SPC_DLL}.Backup" not in raw:
-        raw = cmd(f"shell dotnettool {CROSSGEN2_OPTION} --ni-dll {RUNTIME_DIR}{SPC_DLL}")
-        if "System.Private.CoreLib.ni.dll generated successfully." not in raw:
+        raw = cmd(f"shell dotnettool --ni-dll {RUNTIME_DIR}{SPC_DLL}")
+        if "System.Private.CoreLib.dll generated successfully." not in raw:
             return "FAIL"
 
     raw = cmd(f"shell find {RUNTIME_DIR} -name {SPC_DLL}.Backup")