From: 최종헌/MDE Lab(SR)/삼성전자 Date: Wed, 29 May 2024 07:53:51 +0000 (+0900) Subject: The policy of NI file created in .NET8 is changed to use '.dll' extension (#535) X-Git-Tag: accepted/tizen/unified/20240621.010434~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=201ef8afc604ef491fd9b91e49208dc6319322cc;p=platform%2Fcore%2Fdotnet%2Flauncher.git The policy of NI file created in .NET8 is changed to use '.dll' extension (#535) --- diff --git a/NativeLauncher/inc/path_manager.h b/NativeLauncher/inc/path_manager.h index b3bc88e..ab23578 100644 --- a/NativeLauncher/inc/path_manager.h +++ b/NativeLauncher/inc/path_manager.h @@ -132,6 +132,12 @@ public: */ const std::string& getAppNIPaths(); + /** + * @brief Get the list of directories for using as a value for CLR APP_PATHS key + * @return the list(":" seperated) of paths to probe in + */ + const std::string& getAppCLRPaths(); + /** * @brief Set addtional dll searching path for App. * @param[in] paths path @@ -163,6 +169,7 @@ private: std::string tizenfxPath; std::string appPaths; std::string appNIPaths; + std::string appCLRPaths; std::string nativeDllSearchingPaths; std::string appTacPath; std::string extraDllPaths; diff --git a/NativeLauncher/inc/utils.h b/NativeLauncher/inc/utils.h index ec74c3d..6dd5467 100644 --- a/NativeLauncher/inc/utils.h +++ b/NativeLauncher/inc/utils.h @@ -185,6 +185,13 @@ bool isDirectory(const std::string& path); */ bool isManagedAssembly(const std::string& fileName); +/** + * @brief check the file is native image or not. + * @param[in] file path + * @return return true when the file is native image. + */ +bool isNativeImage(const std::string& filePath); + /** * @brief Resolve assembly files from directories and append their paths to the given list. * @remark If a native image exists for an assembly in the same directory, it will be used. diff --git a/NativeLauncher/launcher/lib/core_runtime.cc b/NativeLauncher/launcher/lib/core_runtime.cc index e7c0e54..94c7326 100644 --- a/NativeLauncher/launcher/lib/core_runtime.cc +++ b/NativeLauncher/launcher/lib/core_runtime.cc @@ -262,7 +262,7 @@ bool initializeCoreClr(PathManager* pm, const std::string& tpa) const char *propertyValues[] = { tpa.c_str(), - pm->getAppPaths().c_str(), + pm->getAppCLRPaths().c_str(), pm->getAppNIPaths().c_str(), pm->getNativeDllSearchingPaths().c_str(), "UseLatestBehaviorWhenTFMNotSpecified", @@ -527,6 +527,7 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i return -1; } + std::string newPath = path; pluginSetAppInfo(appId, path); // temporal root path is overrided to real application root path @@ -573,14 +574,19 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i setSwitch("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true); + std::string exec = replaceAll(path, "/bin/", "/bin/.native_image/"); + if (exist(exec)) { + newPath = exec; + } + pluginBeforeExecute(); - _INFO("execute assembly : %s", path); + _INFO("execute assembly : %s", newPath.c_str()); unsigned int ret = 0; - int st = executeAssembly(__hostHandle, __domainId, argc, (const char**)argv, path, &ret); + int st = executeAssembly(__hostHandle, __domainId, argc, (const char**)argv, newPath.c_str(), &ret); if (st < 0) - _ERR("Failed to Execute Assembly %s (0x%08x)", path, st); + _ERR("Failed to Execute Assembly %s (0x%08x)", newPath.c_str(), st); return ret; } diff --git a/NativeLauncher/tool/ni_common.cc b/NativeLauncher/tool/ni_common.cc index ed4e7aa..6cd025f 100644 --- a/NativeLauncher/tool/ni_common.cc +++ b/NativeLauncher/tool/ni_common.cc @@ -262,7 +262,7 @@ static std::string getNIFilePath(const std::string& absDllPath, NIOption* opt) size_t index = dllPath.find_last_of("."); if (index == std::string::npos) { - _SERR("File doesnot contain extension. fail to get NI file name"); + _SERR("File does not contain extension. fail to get NI file name"); return ""; } std::string fName = dllPath.substr(0, index); @@ -687,6 +687,18 @@ static void renameAppNITmpPath(NIOption* opt) _SERR("Fail to rename from .native_image_tmp to .native_image"); } else { _SOUT("Success to rename from %s to %s", niTmpPath.c_str(), niPath.c_str()); + try { + for (auto& ni : bf::recursive_directory_iterator(niPath)) { + std::string niFile = ni.path().string(); + if (isNativeImage(niFile)) { + std::string dllFile = changeExtension(niFile, ".ni.dll", ".dll"); + bf::create_symlink(niFile, dllFile); + copySmackAndOwnership(niFile, dllFile, true); + } + } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to recursive directory: %s", error.what()); + } } } } @@ -938,7 +950,7 @@ ni_error_e createNIDll(const std::string& dllPath, NIOption* opt) return doAOTFile(dllPath, std::string(), opt); } -ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& refPaths, NIOption* opt) +static ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& refPaths, NIOption* opt) { ni_error_e ret; @@ -995,6 +1007,12 @@ ni_error_e createNIUnderTAC(const std::string& targetPath, const std::string& re _SOUT("%s symbolic link file generated successfully.", symNIPath.c_str()); _INFO("%s symbolic link file generated successfully.", symNIPath.c_str()); } + std::string symPath = changeExtension(symNIPath, ".ni.dll", ".dll"); + removeFile(symPath); + bf::create_symlink(niPath, symPath); + copySmackAndOwnership(targetPath.c_str(), symPath.c_str(), true); + _SOUT("%s symbolic link file generated successfully.", symPath.c_str()); + _INFO("%s symbolic link file generated successfully.", symPath.c_str()); } } } @@ -1144,6 +1162,28 @@ void removeNIUnderDirs(const std::string& rootPaths) } } +static void removeNIUnderTAC(const std::string& rootPaths) +{ + auto convert = [&rootPaths](const std::string& path, const std::string& filename) { + if (isNativeImage(path)) { + std::string assemblyPath = changeExtension(path, ".ni.dll", ".dll"); + if (exist(assemblyPath)) { + if (removeFile(assemblyPath)) { + bf::create_symlink(changeExtension(bf::read_symlink(path).string(), ".ni.dll", ".dll"), assemblyPath); + copySmackAndOwnership(rootPaths.c_str(), assemblyPath.c_str(), true); + } + } + removeFile(path); + } + }; + + std::vector paths; + splitPath(rootPaths, paths); + for (const auto &path : paths) { + scanFilesInDirectory(path, convert, -1); + } +} + ni_error_e removeNIUnderPkgRoot(const std::string& pkgId) { std::vector paths; @@ -1176,7 +1216,7 @@ ni_error_e removeNIUnderPkgRoot(const std::string& pkgId) if (!isReadOnlyArea(path)) { // Only the native image inside the TAC should be removed. if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) { - removeNIUnderDirs(path); + removeNIUnderTAC(path); } else { if (isDirectory(path)) { if (!removeAll(path.c_str())) { @@ -1186,14 +1226,19 @@ ni_error_e removeNIUnderPkgRoot(const std::string& pkgId) } } } + paths.clear(); // In special cases, the ni file may exist in the dll location. // The code below is to avoid this exceptional case. std::string appPaths = __pm->getAppPaths(); splitPath(appPaths, paths); for (const auto &path : paths) { - if (isDirectory(path)) { - removeNIUnderDirs(path); + if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) { + removeNIUnderTAC(path); + } else { + if (isDirectory(path)) { + removeNIUnderDirs(path); + } } } } diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index e0575c9..9dbe5ef 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -252,20 +252,23 @@ tac_error_e disableTACPackage(const std::string& pkgId) std::string fileName = symlinkAssembly.path().filename().string(); if (isSymlinkFile(symPath)) { std::string originPath = bf::read_symlink(symPath).string(); - if (!isR2RImage(symPath)) { - std::string dllPath = concatPath(binDir, fileName); - if (!copyFile(originPath, dllPath)) { - _SERR("Failed to copy of %s", dllPath.c_str()); - return TAC_ERROR_UNKNOWN; - } - copySmackAndOwnership(binDir.c_str(), concatPath(binDir, fileName).c_str()); - } else { + if (isNativeImage(fileName)) { std::string niPath = concatPath(binNIDir, fileName); if (!copyFile(originPath, niPath)) { _SERR("Failed to copy of %s", niPath.c_str()); return TAC_ERROR_UNKNOWN; } copySmackAndOwnership(binDir.c_str(), niPath.c_str()); + std::string dllFile = changeExtension(niPath, ".ni.dll", ".dll"); + bf::create_symlink(niPath, dllFile); + copySmackAndOwnership(niPath, dllFile, true); + } else { + std::string dllPath = concatPath(binDir, fileName); + if (!copyFile(changeExtension(originPath, ".ni.dll", ".dll"), dllPath)) { + _SERR("Failed to copy of %s", dllPath.c_str()); + return TAC_ERROR_UNKNOWN; + } + copySmackAndOwnership(binDir.c_str(), concatPath(binDir, fileName).c_str()); } } } @@ -348,16 +351,25 @@ tac_error_e enableTACPackage(const std::string& pkgId) for (auto& originPath : enableNuget) { if (exist(originPath)) { std::string fileName = originPath.substr(originPath.rfind('/') + 1); + std::string originNIPath = changeExtension(originPath, ".dll", ".ni.dll"); if (exist(binNIDir)) { - std::string originNIPath = changeExtension(originPath, "dll", "ni.dll"); if (exist(originNIPath)) { - if (createSymlinkFile(tacDir, binNIDir, originNIPath, changeExtension(fileName, "dll", "ni.dll")) != TAC_ERROR_NONE) { + if (createSymlinkFile(tacDir, binNIDir, originNIPath, changeExtension(fileName, ".dll", ".ni.dll")) != TAC_ERROR_NONE) { return TAC_ERROR_UNKNOWN; + } else { + if (remove(concatPath(binNIDir, fileName).c_str())) { + _SERR("Failed to remove of %s", concatPath(binNIDir, fileName).c_str()); + return TAC_ERROR_UNKNOWN; + } } } - } - if (createSymlinkFile(tacDir, binDir, originPath, fileName) != TAC_ERROR_NONE) { - return TAC_ERROR_UNKNOWN; + if (createSymlinkFile(tacDir, binDir, originNIPath, fileName) != TAC_ERROR_NONE) { + return TAC_ERROR_UNKNOWN; + } + } else { + if (createSymlinkFile(tacDir, binDir, originPath, fileName) != TAC_ERROR_NONE) { + return TAC_ERROR_UNKNOWN; + } } } } @@ -370,7 +382,7 @@ tac_error_e enableTACPackage(const std::string& pkgId) std::vector depsJsonParser(const std::string& rootPath, const std::string& execName) { std::vector parserData; - std::string depsJsonName = changeExtension(execName, "dll", "deps.json"); + std::string depsJsonName = changeExtension(execName, ".dll", ".deps.json"); std::string depsJsonPath = concatPath(rootPath, depsJsonName); try { if (exist(depsJsonPath)) { diff --git a/NativeLauncher/tool/tac_installer.cc b/NativeLauncher/tool/tac_installer.cc index 3fe4446..9260cba 100644 --- a/NativeLauncher/tool/tac_installer.cc +++ b/NativeLauncher/tool/tac_installer.cc @@ -146,9 +146,9 @@ static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, s break; } if (exist(concatPath(tac_version_dir, niFile)) && exist(binNiPath)) { - bf::create_symlink(concatPath(tac_version_dir, niFile), concatPath(tacDir, niFile), error); + bf::create_symlink(concatPath(tac_version_dir, niFile), concatPath(tacDir, assembly), error); if (error) { - _ERR("Failed to create symlink %s file", concatPath(tacDir, niFile).c_str()); + _ERR("Failed to create symlink %s file", concatPath(tacDir, assembly).c_str()); } } diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc index 2eac3b7..2d1f41c 100644 --- a/NativeLauncher/util/path_manager.cc +++ b/NativeLauncher/util/path_manager.cc @@ -65,10 +65,12 @@ void PathManager::updateAppRelatedPath(const std::string& appRootPath, const std appTacPath = concatPath(appBinPath, TAC_SYMLINK_SUB_DIR); appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath; appNIPaths = appNIBinPath + ":" + appNILibPath + ":" + appTacPath; + appCLRPaths = appNIPaths + ":" + appPaths; if (!extraDllPaths.empty()) { appPaths = appPaths + ":" + extraDllPaths; appNIPaths = appNIPaths + ":" + extraDllPaths; + appCLRPaths = appCLRPaths + ":" + extraDllPaths; } } @@ -192,6 +194,7 @@ void PathManager::setExtraDllPaths(const char* paths) if (!extraDllPaths.empty()) { appPaths = appPaths + ":" + extraDllPaths; appNIPaths = appNIPaths + ":" + extraDllPaths; + appCLRPaths = appCLRPaths + ":" + extraDllPaths; } } @@ -235,6 +238,12 @@ const std::string& PathManager::getAppNIPaths() return appNIPaths; } +// return ni dll and dll searching paths for app +const std::string& PathManager::getAppCLRPaths() +{ + return appCLRPaths; +} + // return native dll searching paths for app const std::string& PathManager::getNativeDllSearchingPaths() { diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index 29d26d2..a637db9 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -66,6 +66,11 @@ bool isManagedAssembly(const std::string& fileName) return iCompare(fileName, fileName.size()-4, ".dll", 0, 4); } +bool isNativeImage(const std::string& fileName) +{ + return iCompare(fileName, fileName.size()-7, ".ni", 0, 3); +} + std::string concatPath(const std::string& path1, const std::string& path2) { std::string path(path1); @@ -337,7 +342,11 @@ std::string replaceAll(const std::string& str, const std::string& pattern, const std::string changeExtension(const std::string& path, const std::string& from, const std::string& to) { - return path.substr(0, path.rfind(from)) + to; + std::string result = path; + if (path.rfind(from) != std::string::npos) { + result = path.substr(0, path.rfind(from)) + to; + } + return result; } bool isFile(const std::string& path)