- generate NI for System.Private.CoreLib.dll
authorWoongsuk Cho <ws77.cho@samsung.com>
Wed, 5 Jun 2019 01:58:03 +0000 (10:58 +0900)
committerWoongsuk Cho <ws77.cho@samsung.com>
Mon, 10 Jun 2019 04:48:03 +0000 (13:48 +0900)
- add error code for ni_common

Generate native image for System.Private.CoreLib.dll when dotnet-launcher package installed.
System.Private.CoreLib.dll should be AOTed for other dll's AOTC.

NativeLauncher/installer-plugin/ni_common.cc
NativeLauncher/installer-plugin/ni_common.h
NativeLauncher/installer-plugin/nitool.cc
packaging/dotnet-launcher.spec

index cd2c473..cf3e85e 100644 (file)
@@ -129,33 +129,33 @@ static void updateNiFileInfo(const std::string& dllPath, const std::string& niPa
        }
 }
 
-static int crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R)
+static ni_error_e crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R)
 {
        if (!isFileExist(dllPath)) {
                fprintf(stderr, "dll file is not exist : %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_NO_SUCH_FILE;
        }
 
        if (!isManagedAssembly(dllPath)) {
                fprintf(stderr, "Input file is not a dll file : %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PARAMETER;
        }
 
        if (niExist(dllPath)) {
                fprintf(stderr, "Already ni file is exist for %s\n", dllPath.c_str());
-               return -1;
+               return NI_ERROR_ALREADY_EXIST;
        }
 
        std::string absDllPath = absolutePath(dllPath);
        std::string absNiPath = getNiFileName(dllPath);
        if (absNiPath.empty()) {
                fprintf(stderr, "Fail to get ni file name\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        pid_t pid = fork();
        if (pid == -1)
-               return -1;
+               return NI_ERROR_UNKNOWN;
 
        if (pid > 0) {
                int status;
@@ -165,10 +165,10 @@ static int crossgen(const std::string& dllPath, const std::string& appPath, bool
                        // niEixst() return false for System.Private.Corelib.dll
                        if (isFileExist(absNiPath)) {
                                updateNiFileInfo(absDllPath, absNiPath);
-                               return 0;
+                               return NI_ERROR_NONE;
                        } else {
                                fprintf(stderr, "Fail to create native image for %s\n", dllPath.c_str());
-                               return -1;
+                               return NI_ERROR_NO_SUCH_FILE;
                        }
                }
        } else {
@@ -205,10 +205,10 @@ static int crossgen(const std::string& dllPath, const std::string& appPath, bool
                exit(0);
        }
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-static int getRootPath(std::string pkgId, std::string& rootPath)
+static ni_error_e getRootPath(std::string pkgId, std::string& rootPath)
 {
        int ret = 0;
        char *path = 0;
@@ -217,32 +217,32 @@ static int getRootPath(std::string pkgId, std::string& rootPath)
 
        if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
                _ERR("Failed to get UID");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        pkgmgrinfo_pkginfo_h handle;
        if (uid == 0) {
                ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
                if (ret != PMINFO_R_OK)
-                       return -1;
+                       return NI_ERROR_UNKNOWN;
        } else {
                ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
                if (ret != PMINFO_R_OK)
-                       return -1;
+                       return NI_ERROR_UNKNOWN;
        }
 
        ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
        if (ret != PMINFO_R_OK) {
                pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
        rootPath = path;
        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-
+// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
 static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
 {
        char *pkgId = NULL;
@@ -291,7 +291,7 @@ static void createCoreLibNI(bool enableR2R)
        }
 }
 
-int initNICommon(NiCommonOption* option)
+ni_error_e initNICommon(NiCommonOption* option)
 {
 #if defined(__arm__)
        // get interval value
@@ -304,19 +304,19 @@ int initNICommon(NiCommonOption* option)
 
        if (initializePluginManager("normal")) {
                fprintf(stderr, "Fail to initialize plugin manager\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
        if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) {
                fprintf(stderr, "Fail to initialize path manager\n");
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        __tpa = getTPA();
 
-       return 0;
+       return NI_ERROR_NONE;
 #else
        fprintf(stderr, "crossgen supports arm architecture only. skip ni file generation\n");
-       return -1;
+       return NI_ERROR_NOT_SUPPORTED;
 #endif
 }
 
@@ -337,9 +337,15 @@ void createNiPlatform(bool enableR2R)
        createNiUnderDirs(platformDirs, 2, enableR2R);
 }
 
-int createNiDll(const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDll(const std::string& dllPath, bool enableR2R)
 {
        createCoreLibNI(enableR2R);
+       // System.Private.CoreLib.dll is generated in the createCoreLibNI function.
+       // Skip if input dll is System.Private.CoreLib.dll
+       if (dllPath.find("System.Private.CoreLib.dll") != std::string::npos) {
+               return NI_ERROR_NONE;
+       }
+
        return crossgen(dllPath, std::string(), enableR2R);
 }
 
@@ -367,12 +373,12 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R)
        }
 }
 
-int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
+ni_error_e createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
 {
        std::string pkgRoot;
-       if (getRootPath(pkgName, pkgRoot) < 0) {
+       if (getRootPath(pkgName, pkgRoot) != NI_ERROR_NONE) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -381,15 +387,15 @@ int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
 
        createNiUnderDirs(paths, 2, enableR2R);
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-int createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
 {
        std::string pkgRoot;
        if (getRootPath(pkgName, pkgRoot) < 0) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -436,12 +442,12 @@ void removeNiUnderDirs(const std::string rootPaths[], int count)
                scanFilesInDir(rootPaths[i], convert, -1);
 }
 
-int removeNiUnderPkgRoot(const std::string& pkgName)
+ni_error_e removeNiUnderPkgRoot(const std::string& pkgName)
 {
        std::string pkgRoot;
        if (getRootPath(pkgName, pkgRoot) < 0) {
                fprintf(stderr, "Failed to get root path from [%s]\n", pkgName.c_str());
-               return -1;
+               return NI_ERROR_INVALID_PACKAGE;
        }
 
        std::string binDir = concatPath(pkgRoot, "bin");
@@ -450,34 +456,34 @@ int removeNiUnderPkgRoot(const std::string& pkgName)
 
        removeNiUnderDirs(paths, 2);
 
-       return 0;
+       return NI_ERROR_NONE;
 }
 
-int regenerateAppNI(bool enableR2R)
+ni_error_e regenerateAppNI(bool enableR2R)
 {
        int ret = 0;
        pkgmgrinfo_appinfo_metadata_filter_h handle;
 
        ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
        if (ret != PMINFO_R_OK)
-               return -1;
+               return NI_ERROR_UNKNOWN;
 
        ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, "http://tizen.org/metadata/prefer_dotnet_aot", "true");
        if (ret != PMINFO_R_OK) {
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, &enableR2R);
        if (ret != PMINFO_R_OK) {
                fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
                pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
+               return NI_ERROR_UNKNOWN;
        }
 
        fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
 
        pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-       return 0;
+       return NI_ERROR_NONE;
 }
 
index b36282f..0981090 100644 (file)
 
 typedef std::function<void (std::string)> afterCreate;
 
+typedef enum {
+       NI_ERROR_NONE = 0,
+       NI_ERROR_INVALID_PARAMETER = -1,
+       NI_ERROR_ALREADY_EXIST = -2,
+       NI_ERROR_NO_SUCH_FILE = -3,
+       NI_ERROR_INVALID_PACKAGE = -4,
+       NI_ERROR_NOT_SUPPORTED = -5,
+       NI_ERROR_UNKNOWN = -9
+} ni_error_e;
+
 /**
  * @brief : structure which contains directory info
  */
@@ -33,9 +43,9 @@ typedef struct NiCommonOption {
 /**
  * @brief initialize NICommon
  * @param[in] options to initialize path
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e 0 on success, otherwise a negative error value
  */
-int initNICommon(NiCommonOption* option);
+ni_error_e initNICommon(NiCommonOption* option);
 
 /**
  * @brief finalize NICommon
@@ -52,9 +62,9 @@ void createNiPlatform(bool enableR2R);
  * @brief create native image for specific dll with file path.
  * @param[i] dllPath file path to generate native image
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiDll(const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDll(const std::string& dllPath, bool enableR2R);
 
 /**
  * @brief create native images with files under specific directory.
@@ -68,18 +78,18 @@ void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R)
  * @brief create native images for specific package. (All DLLs)
  * @param[i] pkgId package ID
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
+ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
 
 /**
  * @brief create native image for specific dll in the package.
  * @Details All dlls in the package are added for reference when create native image.
  * @param[i] pkgId package ID
  * @param[i] enableR2R enable ready-to-run mode
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
+ni_error_e createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
 
 /**
  * @brief remove native images (NI file) for Platform DLLs (.NETCore + TizenFX)
@@ -96,13 +106,14 @@ void removeNiUnderDirs(const std::string rootPaths[], int count);
 /**
  * @brief remove native images for specific package.
  * @param[i] pkgId package ID
- * @return 0 on success, otherwise a negative error value
+ * @return ni_error_e
  */
-int removeNiUnderPkgRoot(const std::string& pkgId);
+ni_error_e removeNiUnderPkgRoot(const std::string& pkgId);
 
 /**
  * @brief regenerate native image for all installed application
+ * @return ni_error_e
  */
-int regenerateAppNI(bool enableR2R = true);
+ni_error_e regenerateAppNI(bool enableR2R = true);
 
 #endif /* __NI_COMMON_H__ */
index aac3d0e..4ff2679 100644 (file)
@@ -74,7 +74,7 @@ int main(int argc, char* argv[])
        bool pkgDllMode = false;
 
        NiCommonOption option = {std::string(), std::string(), std::string()};
-       if (initNICommon(&option) < 0) {
+       if (initNICommon(&option) != NI_ERROR_NONE) {
                fprintf(stderr, "Fail to initialize NI Common\n");
                return -1;
        }
@@ -123,26 +123,47 @@ int main(int argc, char* argv[])
 
        if (pkgMode) {
                for (const std::string pkg : args) {
-                       if (createNiUnderPkgRoot(pkg, enableR2R) != 0) {
+                       // if there is AOTed dlls under package root, that is skiped.
+                       int ret = createNiUnderPkgRoot(pkg, enableR2R);
+                       if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
                                return -1;
+                       } else if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+                               return -1;
                        }
                }
        } else if (pkgDllMode) {
-               if (createNiDllUnderPkgRoot(args[0], args[1], enableR2R) != 0) {
+               int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
+               if (ret == NI_ERROR_INVALID_PACKAGE) {
                        fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
                        return -1;
+               } else if (ret == NI_ERROR_ALREADY_EXIST) {
+                       // skip for already exist case
+                       return -1;
+               } else if (ret != NI_ERROR_NONE) {
+                       fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+                       return -1;
                }
        } else if (rmPkgMode) {
                for (const std::string pkg : args) {
-                       if (removeNiUnderPkgRoot(pkg) != 0) {
+                       int ret = removeNiUnderPkgRoot(pkg);
+                       if (ret == NI_ERROR_INVALID_PACKAGE) {
                                fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
                                return -1;
+                       } else if (ret != NI_ERROR_NONE) {
+                               fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
+                               return -1;
                        }
                }
        } else if (dllMode) {
+               // donot return error code for generation failure.
+               // we have to run crossgen for all input dlls.
                for (const std::string dll : args) {
-                       if (createNiDll(dll, enableR2R) != 0) {
+                       int ret = createNiDll(dll, enableR2R);
+                       if (ret == NI_ERROR_ALREADY_EXIST) {
+                               // skip for already exist case
+                       } else if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
                        }
                }
index 74b03ba..cfebd0c 100644 (file)
@@ -112,6 +112,7 @@ install -m 0644 %{name}.conf %{buildroot}/etc/tmpfiles.d/%{name}.conf
 %post
 mkdir -p /opt/etc/skel/.dotnet
 chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
+%{_bindir}/nitool --dll %{_runtime_dir}/System.Private.CoreLib.dll
 
 %files
 %manifest dotnet-launcher.manifest