The policy of NI file created in .NET8 is changed to use '.dll' extension (#535)
author최종헌/MDE Lab(SR)/삼성전자 <j-h.choi@samsung.com>
Wed, 29 May 2024 07:53:51 +0000 (16:53 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Wed, 29 May 2024 07:53:51 +0000 (16:53 +0900)
NativeLauncher/inc/path_manager.h
NativeLauncher/inc/utils.h
NativeLauncher/launcher/lib/core_runtime.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/tool/tac_common.cc
NativeLauncher/tool/tac_installer.cc
NativeLauncher/util/path_manager.cc
NativeLauncher/util/utils.cc

index b3bc88e38f2f3a8d0da1de6a5c1dbee5aa90f3a2..ab23578a23711d3f4611698d3bc94e91cfba4b7d 100644 (file)
@@ -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;
index ec74c3dffce00535909d0d7cc8b9a07a9e44ee32..6dd5467a6333ef8c0bc4acb34354d5bcec0175a4 100644 (file)
@@ -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.
index e7c0e5422d782ceab773c7ee2b88e1fae5ec2693..94c732623bea7b5f1639439dd5a99ad7dde6cc03 100644 (file)
@@ -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;
 }
 
index ed4e7aaf046f5453e7b65b0954e81982e29bbd12..6cd025f78e1744fc33d0b3c999a8d140ead72f58 100644 (file)
@@ -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<std::string> paths;
+       splitPath(rootPaths, paths);
+       for (const auto &path : paths) {
+               scanFilesInDirectory(path, convert, -1);
+       }
+}
+
 ni_error_e removeNIUnderPkgRoot(const std::string& pkgId)
 {
        std::vector<std::string> 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);
+                               }
                        }
                }
        }
index e0575c98c642c8b8e04aa58dd8708a308711fa12..9dbe5ef81a63c4085ef1410befd72a662e45d04b 100644 (file)
@@ -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<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName)
 {
        std::vector<std::string> 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)) {
index 3fe444691eaef54353986f03c8dc72020e5898f4..9260cba9fd836cd464eb26e269d334d85121a9bf 100644 (file)
@@ -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());
                                        }
                                }
 
index 2eac3b738e561eb1996d419ecd1e697cd5ce0472..2d1f41c54fc6e3cfbda86bed9a7dc9415c147c98 100644 (file)
@@ -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()
 {
index 29d26d289e3560d1b1a12adba37bddab61cfd63a..a637db91c81d6aafdcf62d1a57be96aeba9b515c 100644 (file)
@@ -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)