Add switches for crossgen (#91)
author김상욱/Common Platform Lab(SR)/Engineer/삼성전자 <swift.kim@samsung.com>
Thu, 8 Aug 2019 01:55:24 +0000 (10:55 +0900)
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>
Thu, 8 Aug 2019 01:55:24 +0000 (10:55 +0900)
* Refactor to use NI_FLAGS_* flags

* Enable --legacy and --instrument switches

* Change switch name to --compatibility

* Add more description and fix conditions

* Add a verbose flag

* Update descriptions

NativeLauncher/inc/ni_common.h
NativeLauncher/inc/tac_common.h
NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/tool/nitool.cc
NativeLauncher/tool/tac_common.cc

index 9c1fc26..ed88282 100644 (file)
 
 #include <functional>
 
+#ifndef DWORD
+#define DWORD uint32_t
+#endif
+
+/**
+ * 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_INSTRUMENT             0x1000
+
 typedef std::function<void (std::string)> afterCreate;
 
 typedef enum {
@@ -32,7 +45,7 @@ typedef enum {
 } ni_error_e;
 
 /**
- * @brief : structure which contains directory info
+ * @brief : structure which contains base directory info
  */
 typedef struct NiCommonOption {
        std::string runtimeDir; /**< .NETCore Runtime directory */
@@ -42,7 +55,7 @@ typedef struct NiCommonOption {
 
 /**
  * @brief initialize NICommon
- * @param[in] options to initialize path
+ * @param[i] options base directory info
  * @return ni_error_e 0 on success, otherwise a negative error value
  */
 ni_error_e initNICommon(NiCommonOption* option);
@@ -54,74 +67,75 @@ ni_error_e initNICommon(NiCommonOption* option);
 void finalizeNICommon();
 
 /**
- * @brief create native images (NI file) for Platform DLLs (.NETCore + TizenFX)
+ * @brief create native images for platform DLLs (.NETCore + TizenFX)
+ * @param[i] flags additional flags for the image generator
  */
-void createNiPlatform(bool enableR2R);
+void createNiPlatform(DWORD flags);
 
 /**
- * @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
+ * @brief create a native image for a single DLL
+ * @param[i] dllPath path to input DLL
+ * @param[i] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNiDll(const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDll(const std::string& dllPath, DWORD flags);
 
 /**
- * @brief create native images for TAC DLLs.
- * @param[i] rootPaths directories whicn contains DLLs
- * @param[i] count number of rootPath
+ * @brief create native images for TAC DLLs
+ * @param[i] rootPaths paths to TAC directories
+ * @param[i] count length of rootPaths
+ * @param[i] flags additional flags for the image generator
  */
-void createNiUnderTAC(const std::string rootPaths[], int count);
+void createNiUnderTAC(const std::string rootPaths[], int count, DWORD flags);
 
 /**
- * @brief create native images with files under specific directory.
- * @param[i] rootPaths directories whicn contains DLLs
- * @param[i] count number of rootPath
- * @param[i] enableR2R enable ready-to-run mode
- * @param[i] isAppNI if you want to create ni files under nativeImage directory, set it true
+ * @brief create native images for all DLLs under directories
+ * @param[i] rootPaths paths to directories
+ * @param[i] count length of rootPaths
+ * @param[i] flags additional flags for the image generator
  */
-void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R, bool isAppNI = false);
+void createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags);
 
 /**
- * @brief create native images for specific package. (All DLLs)
+ * @brief create native images for all DLLs in a package
  * @param[i] pkgId package ID
- * @param[i] enableR2R enable ready-to-run mode
+ * @param[i] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
+ni_error_e createNiUnderPkgRoot(const std::string& pkgId, DWORD flags);
 
 /**
- * @brief create native image for specific dll in the package.
- * @Details All dlls in the package are added for reference when create native image.
+ * @brief create a native image for a single dll in a package
  * @param[i] pkgId package ID
- * @param[i] enableR2R enable ready-to-run mode
+ * @param[i] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, DWORD flags);
 
 /**
- * @brief remove native images (NI file) for Platform DLLs (.NETCore + TizenFX)
+ * @brief remove platform native images (.NETCore + TizenFX)
  */
 void removeNiPlatform();
 
 /**
- * @brief remove native images under specific directory.
- * @param[i] rootPaths directories whicn contains native image
- * @param[i] count number of rootPath
+ * @brief remove native images under directories
+ * @param[i] rootPaths paths to directories
+ * @param[i] count length of rootPaths
  */
 void removeNiUnderDirs(const std::string rootPaths[], int count);
 
 /**
- * @brief remove native images for specific package.
+ * @brief remove native images of a package
  * @param[i] pkgId package ID
  * @return ni_error_e
  */
 ni_error_e removeNiUnderPkgRoot(const std::string& pkgId);
 
 /**
- * @brief regenerate native image for all installed application
+ * @brief regenerate native images of all installed applications
+ * @param[i] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e regenerateAppNI(bool enableR2R = true);
+ni_error_e regenerateAppNI(DWORD flags);
 
 #endif /* __NI_COMMON_H__ */
index e18f4a7..26e3edf 100644 (file)
@@ -47,13 +47,13 @@ tac_error_e resetTACPackage(const std::string& pkgId);
  * @param[i] pkgId package ID
  * @return tac_error_e
  */
-tac_error_e createTACPackage(const std::string& pkgId);
+tac_error_e createTACPackage(const std::string& pkgId, DWORD flags);
 
 /**
  * @brief regenerate native image of TAC for all shared assembly.
  * @return tac_error_e
  */
-tac_error_e regenerateTAC();
+tac_error_e regenerateTAC(DWORD flags);
 
 /**
  * @brief disable tac feature.
index f48ffe7..3801a84 100644 (file)
@@ -56,7 +56,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                        return -1;
                }
 
-               if (createNiUnderPkgRoot(pkgId, false) != NI_ERROR_NONE) {
+               if (createNiUnderPkgRoot(pkgId, 0) != NI_ERROR_NONE) {
                        _ERR("Failed to get root path from [%s]", pkgId);
                        return -1;
                } else {
@@ -84,7 +84,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                                                std::string originPath = bf::read_symlink(symPath).string();
                                                std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
                                                if (!bf::exists(originNiPath)) {
-                                                       if(createNiDllUnderPkgRoot(pkgId, originPath, false) != NI_ERROR_NONE) {
+                                                       if(createNiDllUnderPkgRoot(pkgId, originPath, 0) != NI_ERROR_NONE) {
                                                                _ERR("Failed to create NI file [%s]", originPath.c_str());
                                                                return -1;
                                                        }
@@ -101,7 +101,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                                        }
                                }
                        } catch (const bf::filesystem_error& error) {
-                               _ERR("Failed to recursive directory: %s", error.what());
+                               _ERR("File system error while interating files: %s", error.what());
                                return -1;
                        }
                }
index a6d3e01..5c3f6e8 100644 (file)
@@ -48,15 +48,15 @@ std::vector<std::string> getCmdArgs(char** begin, char** end)
 static void help(const char *argv0)
 {
        const char* helpDesc =
-               "Usage: %s [args] <root paths or pkg name>\n"
+               "Usage: %s [OPTIONS] COMMAND <paths or pkg name>\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"
-               "       --r2r                  - Use ready-to-run option (default: FNV)\n"
-               "                                (This option should be used with other options)\n"
                "       --ni-reset-system      - Remove System NI files\n"
                "       --ni-reset-pkg         - Remove App NI files\n"
                "       --ni-regen-all-app     - Re-generate All App NI files\n"
@@ -65,6 +65,13 @@ static void help(const char *argv0)
                "       --tac-disable-pkg      - Disable TAC for package\n"
                "       --tac-enable-pkg       - Enable TAC for package\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"
+               "\n"
                "Example:\n"
                "1. Create native image for dlls and exes under platform directories\n"
                "   # %s --ni-system\n"
@@ -79,30 +86,40 @@ static void help(const char *argv0)
 
 int main(int argc, char* argv[])
 {
+       DWORD flags = 0;
        bool pkgMode = false;
        bool dllMode = false;
        bool dirMode = false;
        bool rmPkgMode = false;
-       bool enableR2R = false;
        bool pkgDllMode = false;
        bool disableTacMode = false;
        bool enableTacMode = false;
 
        NiCommonOption option = {std::string(), std::string(), std::string()};
        if (initNICommon(&option) != NI_ERROR_NONE) {
-               fprintf(stderr, "Fail to initialize NI Common\n");
                return -1;
        }
 
+       // Parse optional switches first.
        if (cmdOptionExists(argv, argv+argc, "--r2r")) {
-               enableR2R = true;
+               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;
        }
 
+       // 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(enableR2R);
+               createNiPlatform(flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--ni-dll")) {
                dllMode = true;
@@ -118,10 +135,10 @@ int main(int argc, char* argv[])
        } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg-dll")) {
                pkgDllMode = true;
        } else if (cmdOptionExists(argv, argv+argc, "--ni-regen-all-app")) {
-               regenerateAppNI(enableR2R);
+               regenerateAppNI(flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--tac-regen-all")) {
-               regenerateTAC();
+               regenerateTAC(flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--tac-restore-db")) {
                restoreTACDB();
@@ -141,22 +158,22 @@ int main(int argc, char* argv[])
                if (pkgMode || rmPkgMode || disableTacMode || enableTacMode) {
                        fprintf(stderr, "Package name is missed\n");
                } else if (dllMode) {
-                       fprintf(stderr, "DLL path is missed\n");
+                       fprintf(stderr, "DLL path is missing.\n");
                }
                help(argv[0]);
-               return 1;
+               return -1;
        } else if (args.size() < 2) {
                if (pkgDllMode) {
-                       fprintf(stderr, "Package name or DLL path is missed\n");
+                       fprintf(stderr, "Package name or DLL path is missing.\n");
                        help(argv[0]);
-                       return 1;
+                       return -1;
                }
        }
 
        if (pkgMode) {
                for (const std::string pkg : args) {
                        // if there is AOTed dlls under package root, that is skiped.
-                       int ret = createNiUnderPkgRoot(pkg, enableR2R);
+                       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;
@@ -164,7 +181,7 @@ int main(int argc, char* argv[])
                                fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
                                return -1;
                        }
-                       ret = createTACPackage(pkg);
+                       ret = createTACPackage(pkg, flags);
                        if (ret == TAC_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
                                return -1;
@@ -174,7 +191,7 @@ int main(int argc, char* argv[])
                        }
                }
        } else if (pkgDllMode) {
-               int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
+               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;
@@ -208,7 +225,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, enableR2R);
+                       int ret = createNiDll(dll, flags);
                        if (ret == NI_ERROR_ALREADY_EXIST) {
                                // skip for already exist case
                        } else if (ret != NI_ERROR_NONE) {
@@ -216,7 +233,7 @@ int main(int argc, char* argv[])
                        }
                }
        } else if (dirMode) {
-               createNiUnderDirs(args.data(), args.size(), enableR2R);
+               createNiUnderDirs(args.data(), args.size(), flags);
        } else if (disableTacMode) {
                for (const std::string pkg : args) {
                        int ret = disableTACPackage(pkg);
index 493078e..ffe7b48 100644 (file)
@@ -216,7 +216,7 @@ static bool isTPADll(const std::string &dllPath)
 #endif
 
 // baseAddr should be checked in file before getting here
-static ni_error_e 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, DWORD flags)
 {
        if (!isFileExist(dllPath)) {
                fprintf(stderr, "dll file is not exist : %s\n", dllPath.c_str());
@@ -240,6 +240,7 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
                return NI_ERROR_UNKNOWN;
        }
 
+       bool isAppNI = flags & NI_FLAGS_APPNI;
        if (isAppNI && strstr(absNiPath.c_str(), __TAC_DIR) == NULL) {
                absNiPath = getAppNIPath(absNiPath);
        }
@@ -280,14 +281,26 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
                std::vector<const char*> argv = {
                        __CROSSGEN_PATH,
                        "/nologo",
-                       "/r", __tpa.c_str(),
                        "/JITPath", jitPath.c_str()
                };
 
+               bool compat = flags & NI_FLAGS_COMPATIBILITY;
+               argv.push_back(compat ? "/Trusted_Platform_Assemblies" : "/r");
+               argv.push_back(__tpa.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
                if (baseAddr != 0) {
                        argv.push_back("/BaseAddress");
@@ -324,7 +337,7 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
        int ret = 0;
-       bool* enableR2R = (bool*)userData;
+       DWORD *pFlags = (DWORD*)userData;
 
        ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
        if (ret != PMINFO_R_OK) {
@@ -343,14 +356,14 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
        }
 
        // Regenerate ni files with R2R mode forcibiliy. (there is no way to now which option is used)
-       if (createNiUnderPkgRoot(pkgId, *enableR2R) != NI_ERROR_NONE) {
+       if (createNiUnderPkgRoot(pkgId, *pFlags) != NI_ERROR_NONE) {
                fprintf(stderr, "Failed to generate NI file [%s]\n", pkgId);
                return -1;
        } else {
                fprintf(stderr, "Complete make application to native image\n");
        }
 
-       if (createTACPackage(pkgId) != TAC_ERROR_NONE) {
+       if (createTACPackage(pkgId, *pFlags) != TAC_ERROR_NONE) {
                fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkgId);
                return -1;
        }else {
@@ -360,7 +373,7 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
        return 0;
 }
 
-static void createCoreLibNI(bool enableR2R)
+static void createCoreLibNI(DWORD flags)
 {
        std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
        std::string niCoreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.ni.dll");
@@ -368,7 +381,7 @@ static void createCoreLibNI(bool enableR2R)
 
        if (!isFileExist(coreLibBackup)) {
 
-               if (!crossgen(coreLib, std::string(), enableR2R)) {
+               if (!crossgen(coreLib, std::string(), flags)) {
                        if (rename(coreLib.c_str(), coreLibBackup.c_str())) {
                                fprintf(stderr, "Failed to rename System.Private.CoreLib.dll\n");
                        }
@@ -421,27 +434,27 @@ void finalizeNICommon()
 }
 
 
-void createNiPlatform(bool enableR2R)
+void createNiPlatform(DWORD flags)
 {
        const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
-       createNiUnderDirs(platformDirs, 2, enableR2R);
+       createNiUnderDirs(platformDirs, 2, flags);
 }
 
-ni_error_e createNiDll(const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDll(const std::string& dllPath, DWORD flags)
 {
-       createCoreLibNI(enableR2R);
+       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;
        }
 
-       ni_error_e status = crossgen(dllPath, std::string(), enableR2R);
+       ni_error_e status = crossgen(dllPath, std::string(), flags);
 
        return status;
 }
 
-void createNiUnderTAC(const std::string rootPaths[], int count)
+void createNiUnderTAC(const std::string rootPaths[], int count, DWORD flags)
 {
        std::string appPaths;
        try {
@@ -456,12 +469,12 @@ void createNiUnderTAC(const std::string rootPaths[], int count)
                        appPaths.pop_back();
                }
 
-               auto convert = [&appPaths](const std::string& path, const char* name) {
+               auto convert = [&appPaths, flags](const std::string& path, const char* name) {
                        if (strstr(path.c_str(), TAC_APP_LIST_DB) != NULL ||
                                strstr(path.c_str(), TAC_APP_LIST_RESTORE_DB) != NULL ||
                                strstr(path.c_str(), TAC_SHA_256_INFO) != NULL)
                                return;
-                       if (!crossgen(path, appPaths.c_str(), false)) {
+                       if (!crossgen(path, appPaths.c_str(), flags)) {
                                waitInterval();
                        }
                };
@@ -475,9 +488,9 @@ void createNiUnderTAC(const std::string rootPaths[], int count)
        }
 }
 
-void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R, bool isAppNI)
+void createNiUnderDirs(const std::string rootPaths[], int count, DWORD flags)
 {
-       createCoreLibNI(enableR2R);
+       createCoreLibNI(flags);
 
        std::string appPaths;
        for (int i = 0; i < count; i++) {
@@ -491,7 +504,8 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R,
        std::vector<std::string> tpaAssemblies;
        splitPath(__tpa, tpaAssemblies);
 
-       auto convert = [&appPaths, enableR2R, isAppNI, tpaAssemblies](const std::string& path, const char* name) {
+       auto convert = [&appPaths, flags, tpaAssemblies](const std::string& path, const char* name) {
+               bool isAppNI = flags & NI_FLAGS_APPNI;
                if (isAppNI) {
                        std::string assembly = path.substr(path.rfind('/') + 1);
                        bool isExist = false;
@@ -506,7 +520,7 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R,
                                return;
                        }
                }
-               if (!crossgen(path, appPaths.c_str(), enableR2R, isAppNI)) {
+               if (!crossgen(path, appPaths.c_str(), flags)) {
                        waitInterval();
                }
        };
@@ -518,7 +532,7 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R,
        tpaAssemblies.clear();
 }
 
-ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R)
+ni_error_e createNiUnderPkgRoot(const std::string& pkgId, DWORD flags)
 {
        std::string pkgRoot;
        if (getRootPath(pkgId, pkgRoot) < 0) {
@@ -530,12 +544,13 @@ ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R)
        std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
        std::string paths[] = {binDir, libDir, tacDir};
 
-       createNiUnderDirs(paths, 3, enableR2R, true);
+       flags |= NI_FLAGS_APPNI;
+       createNiUnderDirs(paths, 3, flags);
 
        return NI_ERROR_NONE;
 }
 
-ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, DWORD flags)
 {
        std::string pkgRoot;
        if (getRootPath(pkgId, pkgRoot) < 0) {
@@ -553,7 +568,7 @@ ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string&
                                std::string originPath = bf::read_symlink(dllPath).string();
                                std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
                                if (!bf::exists(originNiPath)) {
-                                       if(createNiDll(originPath, false) != NI_ERROR_NONE) {
+                                       if(createNiDll(originPath, flags) != NI_ERROR_NONE) {
                                                fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
                                                return NI_ERROR_UNKNOWN;
                                        }
@@ -583,7 +598,8 @@ ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string&
                        fprintf(stderr, "%s present in the TPA list skips generation of NI file.\n", dllPath.c_str());
                        return NI_ERROR_NONE;
                } else {
-                       return crossgen(dllPath, paths, enableR2R, true);
+                       flags |= NI_FLAGS_APPNI;
+                       return crossgen(dllPath, paths, flags);
                }
        }
 }
@@ -662,7 +678,7 @@ ni_error_e removeNiUnderPkgRoot(const std::string& pkgId)
        return NI_ERROR_NONE;
 }
 
-ni_error_e regenerateAppNI(bool enableR2R)
+ni_error_e regenerateAppNI(DWORD flags)
 {
        int ret = 0;
        pkgmgrinfo_appinfo_metadata_filter_h handle;
@@ -677,7 +693,7 @@ ni_error_e regenerateAppNI(bool enableR2R)
                return NI_ERROR_UNKNOWN;
        }
 
-       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, &enableR2R);
+       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, &flags);
        if (ret != PMINFO_R_OK) {
                fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
index 1b35305..0b55ac4 100644 (file)
@@ -44,28 +44,38 @@ static void help(const char *argv0)
 
 int main(int argc, char* argv[])
 {
+       DWORD flags = 0;
        bool pkgMode = false;
        bool dllMode = false;
        bool dirMode = false;
        bool rmPkgMode = false;
-       bool enableR2R = false;
        bool pkgDllMode = false;
 
        NiCommonOption option = {std::string(), std::string(), std::string()};
        if (initNICommon(&option) != NI_ERROR_NONE) {
-               fprintf(stderr, "Fail to initialize NI Common\n");
                return -1;
        }
 
+       // Parse optional switches first.
        if (cmdOptionExists(argv, argv+argc, "--r2r")) {
-               enableR2R = true;
+               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;
        }
 
+       // The following commands are mutually exclusive.
        if (cmdOptionExists(argv, argv+argc, "--help")) {
                help(argv[0]);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--system")) {
-               createNiPlatform(enableR2R);
+               createNiPlatform(flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--dll")) {
                dllMode = true;
@@ -79,7 +89,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(enableR2R);
+               regenerateAppNI(flags);
                return 0;
        } else if (cmdOptionExists(argv, argv+argc, "--pkg-dll")) {
                pkgDllMode = true;
@@ -92,17 +102,17 @@ int main(int argc, char* argv[])
 
        if (args.size() < 1) {
                if (pkgMode)
-                       fprintf(stderr, "Package name is missed\n");
+                       fprintf(stderr, "Package name is missing.\n");
                else if (dllMode)
-                       fprintf(stderr, "DLL path is missed\n");
+                       fprintf(stderr, "DLL path is missing.\n");
                help(argv[0]);
-               return 1;
+               return -1;
        }
 
        if (pkgMode) {
                for (const std::string pkg : args) {
                        // if there is AOTed dlls under package root, that is skiped.
-                       int ret = createNiUnderPkgRoot(pkg, enableR2R);
+                       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;
@@ -112,7 +122,7 @@ int main(int argc, char* argv[])
                        }
                }
        } else if (pkgDllMode) {
-               int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
+               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;
@@ -138,7 +148,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, enableR2R);
+                       int ret = createNiDll(dll, flags);
                        if (ret == NI_ERROR_ALREADY_EXIST) {
                                // skip for already exist case
                        } else if (ret != NI_ERROR_NONE) {
@@ -146,7 +156,7 @@ int main(int argc, char* argv[])
                        }
                }
        } else if (dirMode) {
-               createNiUnderDirs(args.data(), args.size(), enableR2R);
+               createNiUnderDirs(args.data(), args.size(), flags);
        }
 
        return 0;
index b767c91..1614e77 100644 (file)
@@ -235,7 +235,7 @@ tac_error_e resetTACPackage(const std::string& pkgId)
        return TAC_ERROR_NONE;
 }
 
-tac_error_e createTACPackage(const std::string& pkgId)
+tac_error_e createTACPackage(const std::string& pkgId, DWORD flags)
 {
        std::string pkgRoot;
        if (getRootPath(pkgId, pkgRoot) < 0) {
@@ -254,7 +254,7 @@ tac_error_e createTACPackage(const std::string& pkgId)
                                                std::string originPath = bf::read_symlink(symPath).string();
                                                std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
                                                if (!bf::exists(originNiPath)) {
-                                                       if(createNiDll(originPath, false) != NI_ERROR_NONE) {
+                                                       if(createNiDll(originPath, flags) != NI_ERROR_NONE) {
                                                                fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
                                                                return TAC_ERROR_UNKNOWN;
                                                        }
@@ -282,11 +282,11 @@ tac_error_e createTACPackage(const std::string& pkgId)
        return TAC_ERROR_NONE;
 }
 
-tac_error_e regenerateTAC()
+tac_error_e regenerateTAC(DWORD flags)
 {
        const std::string tacDir[] = {__TAC_DIR};
        removeNiUnderDirs(tacDir, 1);
-       createNiUnderTAC(tacDir, 1);
+       createNiUnderTAC(tacDir, 1, flags);
        return TAC_ERROR_NONE;
 }