From: Woongsuk Cho Date: Wed, 5 Jun 2019 01:58:03 +0000 (+0900) Subject: - generate NI for System.Private.CoreLib.dll X-Git-Tag: accepted/tizen/unified/20190611.110407^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e9f2d500598799af1bcc2df051eb86ebdc3eea9c;p=platform%2Fcore%2Fdotnet%2Flauncher.git - generate NI for System.Private.CoreLib.dll - 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. --- diff --git a/NativeLauncher/installer-plugin/ni_common.cc b/NativeLauncher/installer-plugin/ni_common.cc index cd2c473..cf3e85e 100644 --- a/NativeLauncher/installer-plugin/ni_common.cc +++ b/NativeLauncher/installer-plugin/ni_common.cc @@ -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; } diff --git a/NativeLauncher/installer-plugin/ni_common.h b/NativeLauncher/installer-plugin/ni_common.h index b36282f..0981090 100644 --- a/NativeLauncher/installer-plugin/ni_common.h +++ b/NativeLauncher/installer-plugin/ni_common.h @@ -21,6 +21,16 @@ typedef std::function 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__ */ diff --git a/NativeLauncher/installer-plugin/nitool.cc b/NativeLauncher/installer-plugin/nitool.cc index aac3d0e..4ff2679 100644 --- a/NativeLauncher/installer-plugin/nitool.cc +++ b/NativeLauncher/installer-plugin/nitool.cc @@ -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()); } } diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 74b03ba..cfebd0c 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -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