Refactoring path manager
authorWoongsuk Cho <ws77.cho@samsung.com>
Mon, 29 Jun 2020 03:50:55 +0000 (12:50 +0900)
committer조웅석/Common Platform Lab(SR)/Principal Engineer/삼성전자 <ws77.cho@samsung.com>
Wed, 8 Jul 2020 00:15:17 +0000 (09:15 +0900)
The existing path manager provided only the function to create and provide TPA with some directories (runtime/tizenfx/etc).
As a result, a lot of path related duplicate code was used in launcher internal code,

To modify this, the PathManager was refactored as follows:
  1. The paths required for app execution and native image creation are obtained through path manager.
  2. The path manager is created as an object so that it can be maintained and managed where it is needed.
  3. The dependency between path manager and the plugin manager has been removed.
  4. Platform assembly searching path can be updated. (To support dotnet-plugin, system library upgrade)
  5. The nitool doesnot supported any more
  6. --ni-pkg-dll option is removed from dotnettool
  7. TPA related code is moved out from PathManager

Interface change
  1. The parameter of initNICommon() function is removed.
  2. Some functions in ni_common.h, tac_common.h are removed or changed

20 files changed:
NativeLauncher/CMakeLists.txt
NativeLauncher/hydra/hydra_main.cc
NativeLauncher/inc/ni_common.h
NativeLauncher/inc/path_manager.h
NativeLauncher/inc/tac_common.h
NativeLauncher/inc/utils.h
NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc
NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc
NativeLauncher/launcher/exec/launcher.cc
NativeLauncher/launcher/exec/loader.cc
NativeLauncher/launcher/lib/core_runtime.cc
NativeLauncher/launcher/lib/core_runtime.h
NativeLauncher/tool/dotnettool.cc
NativeLauncher/tool/ni_common.cc
NativeLauncher/tool/nitool.cc
NativeLauncher/tool/tac_common.cc
NativeLauncher/tool/tpatool.cc
NativeLauncher/util/path_manager.cc
NativeLauncher/util/utils.cc
packaging/dotnet-launcher.spec

index 17fb44f147362c3411c654ec4da92b5e33a644e9..53cdf861064c023faa443594e71af06495dde729 100644 (file)
@@ -191,14 +191,6 @@ ADD_LIBRARY(${NI_COMMON} SHARED ${${NI_COMMON}_SOURCE_FILES})
 SET_TARGET_PROPERTIES(${NI_COMMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_LIB})
 TARGET_LINK_LIBRARIES(${NI_COMMON} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${TAC_COMMON})
 
-SET(NITOOL "nitool")
-SET(${NITOOL}_SOURCE_FILES
-    tool/nitool.cc
-)
-ADD_EXECUTABLE(${NITOOL} ${${NITOOL}_SOURCE_FILES})
-SET_TARGET_PROPERTIES(${NITOOL} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_EXE})
-TARGET_LINK_LIBRARIES(${NITOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
-
 SET(TPATOOL "tpatool")
 SET(${TPATOOL}_SOURCE_FILES
     tool/tpatool.cc
@@ -241,7 +233,6 @@ INSTALL(TARGETS ${DOTNET_CORERUN} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${DOTNET_HYDRA_LOADER} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${TAC_COMMON} DESTINATION ${LIBDIR})
 INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR})
-INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${DOTNETTOOL} DESTINATION ${BINDIR})
 INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
index 3e45eb2824ec474517c852dce29694c56354c41b..b14f1efb52c6fc6d100d6973d983bb5d275a7e44 100644 (file)
@@ -52,7 +52,7 @@ static std::string getAbsolutePath(const std::string& path)
 static bool isFile(const std::string& path)
 {
        struct stat sb;
-       return stat(path.c_str(), &sb) == 0;
+       return lstat(path.c_str(), &sb) == 0;
 }
 
 static std::string replaceAll(const std::string& str, const std::string& pattern, const std::string& replace)
index d1ade3dec613735980f568eb06442011d19a0a48..2b00a6fb0600793926a780430231181e6123a354 100644 (file)
@@ -45,21 +45,11 @@ typedef enum {
        NI_ERROR_UNKNOWN = -9
 } ni_error_e;
 
-/**
- * @brief : structure which contains base directory info
- */
-typedef struct NICommonOption {
-       std::string runtimeDir; /**< .NETCore Runtime directory */
-       std::string tizenFXDir; /**< TizenFX directory */
-       std::string extraDirs; /**< ":" seperated directories which can be set by plugins */
-} NICommonOption;
-
 /**
  * @brief initialize NICommon
- * @param[i] options base directory info
  * @return ni_error_e 0 on success, otherwise a negative error value
  */
-ni_error_e initNICommon(NICommonOption* option);
+ni_error_e initNICommon();
 
 /**
  * @brief finalize NICommon
@@ -82,22 +72,14 @@ ni_error_e createNIPlatform(DWORD flags);
  */
 ni_error_e createNIDll(const std::string& dllPath, DWORD flags);
 
-/**
- * @brief creates a symbolic link file, the native image of TAC for specific package.
- * @param[i] pkgId package ID
- * @param[i] flags additional flags for the image generator
- * @return ni_error_e
- */
-ni_error_e createTACPkgRoot(const std::string& pkgId, DWORD flags);
 
 /**
  * @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
  * @return ni_error_e
  */
-ni_error_e createNIUnderDirs(const std::string rootPaths[], int count, DWORD flags);
+ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags);
 
 /**
  * @brief create native images for all DLLs in a package
@@ -107,15 +89,6 @@ ni_error_e createNIUnderDirs(const std::string rootPaths[], int count, DWORD fla
  */
 ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags);
 
-/**
- * @brief create a native image for a single dll in a package
- * @param[i] pkgId package ID
- * @param[i] dllPath path to input DLL
- * @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, DWORD flags);
-
 /**
  * @brief remove platform native images (.NETCore + TizenFX)
  */
@@ -124,9 +97,8 @@ void removeNIPlatform();
 /**
  * @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);
+void removeNIUnderDirs(const std::string rootPaths);
 
 /**
  * @brief remove native images of a package
index 6843c6140dd4f1cc9eaf7d070d51299a13b77895..264d4b6fdc791a0c9093888bcbff0702811a5c1b 100644 (file)
  * limitations under the License.
  */
 
+#include <string>
+#include <vector>
+
 #ifndef __DLL_PATH_MANAGER_H__
 #define __DLL_PATH_MANAGER_H__
 
-int initializePathManager(const std::string& runtimeDir, const std::string& tizenFXDir, const std::string& extraDir);
-void finalizePathManager();
+/**
+ * This class helps to easily obtain paths that are frequently used in the implementation.
+ * The following paths are the major paths managed by this class.
+ *
+ * 1. Platform Assemblies Path
+ *    - Paths where the platform assemblies exist
+ *    - Installation directory of coreclr and tizenfx are included by default
+ *
+ * 2. Application Root Path
+ *    - Installation directory of a Tizen application associated with the current process
+ *    - bin, lib, data, res directories are under Application Root Path
+ *
+ * 3. AppPaths
+ *    - The ":" separated paths where applications's managed assemblies exist
+ *    - Returns the bin, lib, and .tac_symlink under AppRootPath
+ *    - ":" separated path list
+ *
+ * 4. AppNIPaths
+ *    - Paths where applications's native image files exist
+ *    - Returns bin/.native_image, lib/.native_image, and .tac_symlink under AppRootPath
+ *    - ":" separated path list
+ *
+ * 5. Native Dll Searching Path
+ *    - Path to find native libraries required by coreclr
+ *
+ * Platform Assemblies Path can be expanded through the addPlatformAssembliesPath () function.
+ * For example, middleware library path which is passed through plugin can be added to platform assemblies path.
+ *
+ * Application related path (AppPath / AppNIPaths / Native Dll Searching Path) is created based on AppRootPath.
+ * Therefore, it has a temporary location before the AppRootPath is set up,
+ * and has the actual location after the setAppRootPath() function is called.
+*/
+class PathManager 
+{
+public:
+       /**
+        * @brief Platform defined path (runtime and tizenfx path) is set by default
+        *        Temporal application root path is set by default, and paths which based on application root path is also set.
+        *        These paths are updated by calling @setAppRootPath()
+        */
+       PathManager();
+
+       /**
+        * @brief destructor
+        */
+       ~PathManager();
+
+       /**
+        * @brief Add platform assemblies paths. The TPA(Trusted-Platform-Assembly) is generated based on this paths
+        * @param[i] paths the paths to be added
+        * @param[i] isHighPriority if true, paths are added in front of the current list, otherwise added at the end of the list
+        */
+       void addPlatformAssembliesPaths(const std::string& paths, bool isHighPriority = false);
+
+       /**
+        * @brief Set application root path.
+        *        All application related paths ("bin", "lib", ".tac_symlink", ".native_image") are generated based on it.
+        *        A temporary path (/proc/self/fd/[fd]) is used if this function is never called.
+        * @param[i] rootPath application root path
+        */
+       void setAppRootPath(const std::string& rootPath);
+
+       /**
+        * @brief Get runtime path which contains coreclr and corefx
+        * @return[i] runtime path
+        */
+       const std::string& getRuntimePath();
+
+       /**
+        * @brief Get tizenfx path which contains tizenfx
+        * @return[i] runtime path
+        */
+       const std::string& getTizenFXPath();
+
+       /**
+        * @brief Get platform assemblies paths
+        * @return[i] return path vector
+        */
+       const std::vector<std::string>& getPlatformAssembliesPaths();
+
+       /**
+        * @brief Get application root path
+        * @see setAppRootPath()
+        * @return[i] system paths
+        */
+       const std::string& getAppRootPath();
+
+       /**
+        * @brief Get the path of .tac_symlink of application
+        * @return[i] .tac_symlink path
+        */
+       const std::string& getAppTacPath();
+
+       /**
+        * @brief Get the list of directories where the assemlies of this application exist
+        * @return[i] the list(":" seperated) of paths to probe in for an assembly
+        */
+       const std::string& getAppPaths();
+
+       /**
+        * @brief Get the list of directories where the native image of this application exist
+        * @return[i] the list(":" seperated) of paths to probe in for an native image
+        */
+       const std::string& getAppNIPaths();
+
+       /**
+        * @brief Get the list of directories where the native libraries of this application exist
+        * @return[i] the list(":" seperated) of paths the loader should probe when looking for native libraries
+        */
+       const std::string& getNativeDllSearchingPaths();
+
+private:
+       // update application related path (bin, lib, tac_symlink, native_image)
+       void updateAppRelatedPath(const std::string& appRootPath);
 
-std::string getRuntimeDir();
-std::string getTizenFXDir();
-std::string getTizenFXRefDir();
-std::string getExtraDirs();
-std::string getTPA();
+private:
+       std::vector<std::string> platformAssembliesPaths;
+       std::string systemPaths;
+       std::string appRootPath;
+       std::string runtimePath;
+       std::string tizenfxPath;
+       std::string appPaths;
+       std::string appNIPaths;
+       std::string nativeDllSearchingPaths;
+       std::string appTacPath;
+       int rootFD;
+};
 
 #endif /* __DLL_PATH_MANAGER_H__ */
index ae0a221eeceaec1df3cd72a02d9f8c3013917e93..aa09464db708332c5708047a8c95d8ad8bcc09fa 100644 (file)
@@ -35,13 +35,6 @@ typedef enum {
  */
 tac_error_e restoreTACDB();
 
-/**
- * @brief remove a symbolic link file, the native images of TAC for specific package.
- * @param[i] pkgId package ID
- * @return tac_error_e
- */
-tac_error_e resetTACPackage(const std::string& pkgId);
-
 /**
  * @brief disable tac feature.
  * @param[i] pkgId package ID
@@ -60,9 +53,8 @@ tac_error_e enableTACPackage(const std::string& pkgId);
  * @brief .deps.json file parser
  * @param[in] root path
  * @param[in] exec name
- * @param[in] tpa list
  * @return std::vector<std::string> parser data
  */
-std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName, const std::string& tpaList);
+std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName);
 
 #endif /* __TAC_COMMON_H__ */
index 1c930eeb78a660f9e0e719b154172fdaa06b32a8..3c4e758cde6221f9f366dd1a55f636688c6ee22d 100644 (file)
@@ -108,6 +108,7 @@ void splitPath(const std::string& path, std::vector<std::string>& out);
 
 /**
  * @brief check file exists
+ *        in case of symlink file, check both input file and link reference file.
  * @param[in] source path
  * @return bool
  */
index 17a07187aeb1a293fa7bec302bd60d4ea3ae70d3..86fbc3c38fd3c4eae2235531170e340e646bef87 100644 (file)
@@ -57,8 +57,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
        if (metaValue == METADATA_VALUE) {
                _DBG("Prefer dotnet application AOT set TRUE");
 
-               NICommonOption option = {std::string(), std::string(), std::string()};
-               if (initNICommon(&option) < 0) {
+               if (initNICommon() != NI_ERROR_NONE) {
                        _ERR("Fail to initialize NI Common");
                        return -1;
                }
@@ -66,53 +65,9 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                if (createNIUnderPkgRoot(pkgId, 0) != NI_ERROR_NONE) {
                        _ERR("Failed to get root path from [%s]", pkgId);
                        return -1;
-               } else {
-                       _INFO("Complete make application to native image");
                }
 
-               std::string rootPath = getRootPath(std::string(pkgId));
-               if (rootPath.empty()) {
-                       _ERR("Failed to get root path from [%s]", pkgId);
-                       return -1;
-               }
-
-               std::string binDir = concatPath(rootPath, "bin");
-               std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-               if (bf::exists(tacDir)) {
-                       uid_t g_uid = 0;
-                       gid_t g_gid = 0;
-                       if (pkgmgr_installer_info_get_target_uid(&g_uid) < 0) {
-                               _ERR("Failed to get UID");
-                               return -1;
-                       }
-                       try {
-                               for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
-                                       std::string symPath = symlinkAssembly.path().string();
-                                       if (!isNativeImage(symPath)) {
-                                               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, 0) != NI_ERROR_NONE) {
-                                                               _ERR("Failed to create NI file [%s]", originPath.c_str());
-                                                               return -1;
-                                                       }
-                                               }
-                                               std::string setNIPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll";
-                                               if (!bf::exists(setNIPath)) {
-                                                       bf::create_symlink(originNIPath, setNIPath);
-                                                       _INFO("%s symbolic link file generated successfully.", setNIPath.c_str());
-                                                       if (lchown(setNIPath.c_str(), g_uid, g_gid)) {
-                                                               _ERR("Failed to change owner of: %s", setNIPath.c_str());
-                                                               return -1;
-                                                       }
-                                               }
-                                       }
-                               }
-                       } catch (const bf::filesystem_error& error) {
-                               _ERR("File system error while interating files: %s", error.what());
-                               return -1;
-                       }
-               }
+               _INFO("Complete make application to native image");
        }
        return 0;
 }
@@ -134,10 +89,13 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_REMOVED(const char *pkgId, const char *app
 
 extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list)
 {
+       // it can be call without initializeNICommon()
+       finalizeNICommon();
        return 0;
 }
 
 extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list)
 {
+       finalizeNICommon();
        return 0;
 }
index 769f2f69b6e76a1eaab199c68158701f3ea3c1b0..2d77a80c872a0c0190a88d026be98a594c2ff3bd 100644 (file)
@@ -17,8 +17,6 @@
 #include "log.h"
 #include "utils.h"
 #include "db_manager.h"
-#include "path_manager.h"
-#include "plugin_manager.h"
 #include "tac_common.h"
 
 #include <cstring>
@@ -178,7 +176,7 @@ static int copyNCreateSymlink(std::string binPath, std::string tacVersionDir, st
 
 static void depsJsonCheck(std::string rootPath, std::string binPath, std::string execName)
 {
-       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
+       for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
                std::string nuget_package = npAssembly.substr(0, npAssembly.rfind(':'));
                std::string assembly_name = npAssembly.substr(npAssembly.rfind(':') + 1);
                tacDB.push_back(nuget_package);
@@ -203,11 +201,6 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
        }
        tacPluginInstalled = true;
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               _ERR("Fail to initialize PathManger");
-               return 0;
-       }
-
        std::string appType = getAppType(std::string(pkgId));
        if (strstr(appType.c_str(), "dotnet") == NULL) {
                _ERR("App type is not dotnet");
@@ -351,11 +344,6 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
        }
        tacPluginInstalled = true;
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               _ERR("Fail to initialize PathManger");
-               return 0;
-       }
-
        std::string appType = getAppType(std::string(pkgId));
        if (strstr(appType.c_str(), "dotnet") == NULL) {
                _ERR("App type is not dotnet");
index a302bb40e3fbe434936412ff2b7e836e32558b03..e52001e7dae0f167120df3ec045dc866d65d87a0 100644 (file)
@@ -102,19 +102,19 @@ int main(int argc, char *argv[])
        snprintf(argv[0], cmdlineSize - 1, "%s", standalonePath);
 
        // initialize CoreRuntime
-       if (CoreRuntime::initialize(appType, LaunchMode::launcher) != 0) {
+       int err = CoreRuntime::initialize(appType, LaunchMode::launcher);
+       if (err) {
                _ERR("Failed to initialize");
-               return -1;
-       }
-
-       // launch application
-       if (CoreRuntime::launch(appId, appRootPath, standalonePath, vargs.size(), &vargs[0])) {
-               _ERR("Failed to launch");
-               return -1;
+       } else {
+               // launch application
+               err = CoreRuntime::launch(appId, appRootPath, standalonePath, vargs.size(), &vargs[0]);
+               if (err) {
+                       _ERR("Failed to launch");
+               }
        }
 
-       // finalize runtime
+       // finalize CoreRuntime
        CoreRuntime::finalize();
 
-       return 0;
+       return err;
 }
index 757aa19179ea83c3f7254e4eaa95605a788954f0..08505ffb78615ac6a1cf678f6c5b9bae2a5b46f6 100644 (file)
@@ -203,9 +203,8 @@ extern "C" int realMain(int argc, char *argv[])
        };
 
        int ret = launchpad_loader_main(argc, argv, &callbacks, &adapter, NULL);
-       if (ret >= 0) {
-               CoreRuntime::finalize();
-       }
+
+       CoreRuntime::finalize();
 
        return ret;
 }
index 3fd90bb77df6437520e3f4903c5344699bf365c1..8f0cd264a51a89298021f0e9c2feb17ee4cdc48a 100644 (file)
@@ -59,85 +59,9 @@ static set_environment_variable_ptr setEnvironmentVariable = nullptr;
 static void* __coreclrLib = nullptr;
 static void* __hostHandle = nullptr;
 static unsigned int __domainId = -1;
-static int __fd = -1;
 static bool __initialized = false;
 static bool __isProfileMode = false;
-
-#define __XSTR(x) #x
-#define __STR(x) __XSTR(x)
-
-#ifdef NATIVE_LIB_DIR
-static std::string __nativeLibDirectory = __STR(NATIVE_LIB_DIR);
-#endif
-
-#undef __STR
-#undef __XSTR
-
-#if defined (__aarch64__)
-#define ARCHITECTURE_IDENTIFIER "arm64"
-
-#elif defined (__arm__)
-#define ARCHITECTURE_IDENTIFIER "armel"
-
-#elif defined (__x86_64__)
-#define ARCHITECTURE_IDENTIFIER "x64"
-
-#elif defined (__i386__)
-#define ARCHITECTURE_IDENTIFIER "x86"
-
-#else
-#error "Unknown target"
-#endif
-
-static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version";
-
-// The sequence of RID_FALLBACK graphs must be:
-// 1. Tizen + Version + Architecture
-// 2. Tizen + Version
-// 3. OS(tizen, linux, unix) + Architecture
-// 4. OS(tizen, linux, unix)
-// 5. any, base
-static std::string getExtraNativeLibDirs(const std::string& appRoot)
-{
-       std::vector<std::string> RID_FALLBACK_GRAPH;
-       char* tizen_rid = vconf_get_str(__TIZEN_RID_VERSION_KEY);
-       if (tizen_rid) {
-               std::vector<std::string> version;
-               splitPath(tizen_rid, version);
-               std::reverse(std::begin(version), std::end(version));
-               for (unsigned int i = 0; i < version.size(); i++) {
-                       RID_FALLBACK_GRAPH.push_back(std::string("tizen." + version[i] + "-" + ARCHITECTURE_IDENTIFIER));
-                       RID_FALLBACK_GRAPH.push_back(std::string("tizen." + version[i]));
-               }
-               free(tizen_rid);
-       }
-
-       std::vector<std::string> RID_FALLBACK_OS = {"tizen", "linux", "unix"};
-       for (unsigned int i = 0; i < RID_FALLBACK_OS.size(); i++) {
-               RID_FALLBACK_GRAPH.push_back(std::string(RID_FALLBACK_OS[i] + "-" +  ARCHITECTURE_IDENTIFIER));
-               RID_FALLBACK_GRAPH.push_back(std::string(RID_FALLBACK_OS[i]));
-       }
-       RID_FALLBACK_GRAPH.push_back("any");
-       RID_FALLBACK_GRAPH.push_back("base");
-
-       std::string candidate;
-       for (unsigned int i = 0; i < RID_FALLBACK_GRAPH.size(); i++) {
-               if (!candidate.empty()) {
-                       candidate += ":";
-               }
-               candidate += concatPath(appRoot, "bin/runtimes/" + RID_FALLBACK_GRAPH[i] + "/native");
-       }
-
-       candidate = candidate + ":" + concatPath(appRoot, "lib/" ARCHITECTURE_IDENTIFIER);
-       if (!strncmp(ARCHITECTURE_IDENTIFIER, "arm64", 5)) {
-               candidate = candidate + ":" + concatPath(appRoot, "lib/aarch64");
-       } else if (!strncmp(ARCHITECTURE_IDENTIFIER, "armel", 5)) {
-               candidate = candidate + ":" + concatPath(appRoot, "lib/arm");
-       }
-
-       return candidate;
-}
-
+PathManager* CoreRuntime::__pm = nullptr;
 
 static std::vector<std::string> __envList;
 
@@ -316,13 +240,11 @@ void preload()
        } else {
                preloadDelegate();
        }
+
+       pluginPreload();
 }
 
-bool initializeCoreClr(const char* appId,
-                                                                        const char* assemblyProbePaths,
-                                                                        const char* NIProbePaths,
-                                                                        const char* pinvokeProbePaths,
-                                                                        const char* tpaList)
+bool initializeCoreClr(PathManager* pm, const std::string& tpa)
 {
        const char *propertyKeys[] = {
                "TRUSTED_PLATFORM_ASSEMBLIES",
@@ -333,17 +255,17 @@ bool initializeCoreClr(const char* appId,
        };
 
        const char *propertyValues[] = {
-               tpaList,
-               assemblyProbePaths,
-               NIProbePaths,
-               pinvokeProbePaths,
+               tpa.c_str(),
+               pm->getAppPaths().c_str(),
+               pm->getAppNIPaths().c_str(),
+               pm->getNativeDllSearchingPaths().c_str(),
                "UseLatestBehaviorWhenTFMNotSpecified"
        };
 
        std::string selfPath = readSelfPath();
 
        int st = initializeClr(selfPath.c_str(),
-                                                       appId,
+                                                       "TizenDotnetApp",
                                                        sizeof(propertyKeys) / sizeof(propertyKeys[0]),
                                                        propertyKeys,
                                                        propertyValues,
@@ -425,11 +347,18 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode)
        // read string from external file and set them to environment value.
        setEnvFromFile();
 
-       if (initializePathManager(std::string(), std::string(), std::string()) < 0) {
-               _ERR("Failed to initialize PathManager");
+       try {
+               __pm = new PathManager();
+       } catch (const std::exception& e) {
+               _ERR("Failed to create PathManager");
                return -1;
        }
 
+       char* pluginPath = pluginGetDllPath();
+       if (pluginPath) {
+               __pm->addPlatformAssembliesPaths(pluginPath);
+       }
+
        if (!pluginHasLogControl()) {
                if (initializeLogManager() < 0) {
                        _ERR("Failed to initnialize LogManager");
@@ -437,7 +366,7 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode)
                }
        }
 
-       std::string libCoreclr(concatPath(getRuntimeDir(), "libcoreclr.so"));
+       std::string libCoreclr(concatPath(__pm->getRuntimePath(), "libcoreclr.so"));
 
        __coreclrLib = dlopen(libCoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
        if (__coreclrLib == nullptr) {
@@ -472,24 +401,15 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode)
        // To avoid gdbus blocking issue, below function should be called after fork()
        initEnvForSpecialFolder();
 
-       __fd = open("/proc/self", O_DIRECTORY);
-       if (__fd < 0) {
-               _ERR("Failed to open /proc/self");
-               return -1;
+       std::string tpa;
+       char* pluginTPA = pluginGetTPA();
+       if (pluginTPA) {
+               tpa = std::string(pluginTPA);
+       } else {
+               addAssembliesFromDirectories(__pm->getPlatformAssembliesPaths(), tpa);
        }
 
-       std::string tpa = getTPA();
-       std::string runtimeDir = getRuntimeDir();
-       std::string appName = std::string("dotnet-launcher-") + std::to_string(getpid());
-       std::string appRoot = std::string("/proc/self/fd/") + std::to_string(__fd);
-       std::string appBin = concatPath(appRoot, "bin");
-       std::string appLib = concatPath(appRoot, "lib");
-       std::string appTac = concatPath(appBin, TAC_SYMLINK_SUB_DIR);
-       std::string probePath = appRoot + ":" + appBin + ":" + appLib + ":" + appTac;
-       std::string NIprobePath = concatPath(appBin, APP_NI_SUB_DIR) + ":" + concatPath(appLib, APP_NI_SUB_DIR) + ":" + appTac;
-       std::string nativeLibPath = runtimeDir + ":" + __nativeLibDirectory + ":" + getExtraNativeLibDirs(appRoot) + ":" + appBin + ":" + appLib;
-
-       if (!initializeCoreClr(appName.c_str(), probePath.c_str(), NIprobePath.c_str(), nativeLibPath.c_str(), tpa.c_str())) {
+       if (!initializeCoreClr(__pm, tpa)) {
                _ERR("Failed to initialize coreclr");
                return -1;
        }
@@ -500,17 +420,17 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode)
                return -1;
        }
 
-       __initialized = true;
-
        if (launchMode == LaunchMode::loader) {
                // terminate candidate process if language is changed.
                // CurrentCulture created for preloaded dlls should be updated.
                vconf_notify_key_changed(VCONFKEY_LANGSET, langChangedCB, NULL);
 
-               pluginPreload();
-               preload();              // Preload common managed code
+               // preload libraries and manage dlls for optimizing startup time
+               preload();
        }
 
+       __initialized = true;
+
        _INFO("CoreRuntime initialize success");
 
        return 0;
@@ -518,11 +438,6 @@ int CoreRuntime::initialize(const char* appType, LaunchMode launchMode)
 
 void CoreRuntime::finalize()
 {
-       if (!__initialized) {
-               _ERR("Runtime is not initialized");
-               return;
-       }
-
        // call plugin finalize function to notify finalize to plugin
        // dlclose shoud be done after coreclr shutdown to avoid breaking signal chain
        pluginFinalize();
@@ -554,7 +469,9 @@ void CoreRuntime::finalize()
        }
 
        finalizePluginManager();
-       finalizePathManager();
+
+       delete __pm;
+       __pm = NULL;
 
        __envList.clear();
 
@@ -593,13 +510,8 @@ int CoreRuntime::launch(const char* appId, const char* root, const char* path, i
 
        pluginSetAppInfo(appId, path);
 
-       // override root path for application launch mode (candidate / standalone mode)
-       if (__fd >= 0) {
-               int fd2 = open(root, O_DIRECTORY);
-               dup3(fd2, __fd, O_CLOEXEC);
-               if (fd2 >= 0)
-                       close(fd2);
-       }
+       // temporal root path is overrided to real application root path
+       __pm->setAppRootPath(root);
 
        // set application data path to coreclr environment.
        // application data path can be changed by owner. So, we have to set data path just before launching.
index 27b97b9c01bb97d7e85cdc7bd1386c2336672d34..c4aa53f09460e8789bbc513f2c892e816b3a676b 100644 (file)
@@ -20,7 +20,7 @@
 #include <string>
 
 #include "coreclr_host.h"
-#include "plugin_manager.h"
+#include "path_manager.h"
 
 enum LaunchMode {
        corerun = 0,
@@ -38,6 +38,9 @@ class CoreRuntime
                static int initialize(const char* appType, LaunchMode launchMode);
                static void finalize();
                static int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]);
+
+       private:
+               static PathManager* __pm;
 };
 
 }  // dotnetcore
index ff4db076193430a157c022a8e8cf757521f6839a..57f4a7ab5a3cd933080359dfedec522e2ed3f6cb 100644 (file)
@@ -32,7 +32,6 @@ void DisplayUsage() {
                "       --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"
                "       --ni-reset-system         - Remove System NI files\n"
                "       --ni-reset-pkg            - Remove App NI files\n"
@@ -83,11 +82,6 @@ int main(int argc, char* argv[])
                return -1;
        }
 
-       NICommonOption option = {std::string(), std::string(), std::string()};
-       if (initNICommon(&option) != NI_ERROR_NONE) {
-               return -1;
-       }
-
        //sh-3.2# dotnettool --[r2r|compatibility|instrument|verbose]
        DWORD flags = 0;
        std::vector<std::string> args;
@@ -127,6 +121,10 @@ int main(int argc, char* argv[])
                }
        }
 
+       if (initNICommon() != NI_ERROR_NONE) {
+               return -1;
+       }
+
        std::vector<std::string>::iterator it = args.begin();
        std::string cmd = std::string(*it);
        it = args.erase(it);
@@ -166,40 +164,17 @@ int main(int argc, char* argv[])
                                fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
                                break;
                        }
-                       ret = createTACPkgRoot(pkg, flags);
-                       if (ret != NI_ERROR_NONE) {
-                               fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkg.c_str());
-                               break;
-                       }
                        it = args.erase(it);
                }
        }
-       //sh-3.2# dotnettool --ni-pkg-dll [pkgId] [pkgAssemblyPath] [pkgAssemblyPath] ...
-       else if (cmd == "--ni-pkg-dll") {
-               if (args.size() < 2) {
-                       fprintf(stderr, "Package name or DLL path is missing\n");
-               } else {
-                       std::string pkg = std::string(*it);
-                       it = args.erase(it);
-                       while (it != args.end()) {
-                               std::string dll = std::string(*it);
-                               int ret = createNIDllUnderPkgRoot(pkg, dll, flags);
-                               if (ret != NI_ERROR_NONE) {
-                                       fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
-                                       break;
-                               }
-                               it = args.erase(it);
-                       }
-               }
-       }
        //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
        else if (cmd == "--ni-dir") {
                if (args.size() < 1) {
                        fprintf(stderr, "Directory path is missing\n");
                }
                while (it != args.end()) {
-                       const std::string dir[] = {std::string(*it)};
-                       int ret = createNIUnderDirs(dir, 1, flags);
+                       const std::string dir = std::string(*it);
+                       int ret = createNIUnderDirs(dir, flags);
                        if (ret != NI_ERROR_NONE) {
                                fprintf(stderr, "Failed to generate NI directory\n");
                                break;
@@ -223,11 +198,6 @@ int main(int argc, char* argv[])
                                fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
                                break;
                        }
-                       ret = resetTACPackage(pkg);
-                       if (ret != TAC_ERROR_NONE) {
-                               fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkg.c_str());
-                               break;
-                       }
                        it = args.erase(it);
                }
        }
@@ -237,8 +207,8 @@ int main(int argc, char* argv[])
                        fprintf(stderr, "Directory path is missing\n");
                }
                while (it != args.end()) {
-                       const std::string dir[] = {std::string(*it)};
-                       removeNIUnderDirs(dir, 1);
+                       const std::string dir = std::string(*it);
+                       removeNIUnderDirs(dir);
                        it = args.erase(it);
                }
        }
@@ -298,6 +268,8 @@ int main(int argc, char* argv[])
                DisplayUsage();
        }
 
+       finalizeNICommon();
+
        gettimeofday(&tv, NULL);
        endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
        fprintf(stdout, "\nSpend time for dotnettool is [%d]ms\n", (int)(endtime - starttime));
index 6e9af2fac8cbfb58fe6315599fdf4de6a8dd4e5c..3f73edbb8e31c2aa3dd01a008e349a1bc032bb87 100644 (file)
@@ -65,7 +65,7 @@ static const char* __SYSTEM_BASE_FILE = __STR(SYSTEM_BASE_FILE);
 #undef __XSTR
 
 static int __interval = 0;
-static std::string __tpa;
+static PathManager* __pm = nullptr;
 
 static void waitInterval()
 {
@@ -93,7 +93,7 @@ static std::string getNIFilePath(const std::string& dllPath)
        return niPath;
 }
 
-static std::string getAppNIPath(const std::string& niPath)
+static std::string getAppNIFilePath(const std::string& niPath)
 {
        std::string fileName;
        std::string niDirPath;
@@ -219,10 +219,13 @@ static void updateBaseAddrFile(const std::string& absNIPath, uintptr_t baseAddr)
 // check if dll is listed in TPA
 static bool isTPADll(const std::string& dllPath)
 {
-       std::string absDllPath = getAbsolutePath(dllPath);
+       std::string absPath = getBaseName(getAbsolutePath(dllPath));
 
-       if (__tpa.find(absDllPath) != std::string::npos) {
-               return true;
+       std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
+       for (unsigned int i = 0; i < paths.size(); i++) {
+               if (paths[i].find(getBaseName(absPath)) != std::string::npos) {
+                       return true;
+               }
        }
 
        return false;
@@ -250,7 +253,6 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
        std::string absDllPath = getAbsolutePath(dllPath);
        std::string absNIPath = getNIFilePath(dllPath);
 
-
        if (absNIPath.empty()) {
                fprintf(stderr, "Fail to get ni file name\n");
                return NI_ERROR_UNKNOWN;
@@ -258,7 +260,7 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
 
        bool isAppNI = flags & NI_FLAGS_APPNI;
        if (isAppNI && strstr(absNIPath.c_str(), __DOTNET_DIR) == NULL) {
-               absNIPath = getAppNIPath(absNIPath);
+               absNIPath = getAppNIFilePath(absNIPath);
        }
 
 #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
@@ -302,7 +304,7 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
                        }
                }
        } else {
-               std::string jitPath = getRuntimeDir() + "/libclrjit.so";
+               std::string jitPath = __pm->getRuntimePath() + "/libclrjit.so";
                std::vector<const char*> argv = {
                        __CROSSGEN_PATH,
                        "/nologo",
@@ -310,8 +312,16 @@ static ni_error_e crossgen(const std::string& dllPath, const std::string& appPat
                };
 
                bool compat = flags & NI_FLAGS_COMPATIBILITY;
-               argv.push_back(compat ? "/Trusted_Platform_Assemblies" : "/r");
-               argv.push_back(__tpa.c_str());
+               argv.push_back(compat ? "/Platform_Assemblies_Pathes" : "/p");
+               std::vector<std::string> paths = __pm->getPlatformAssembliesPaths();
+               std::string platformAssembliesPaths;
+               for (const auto &path : paths) {
+                       if (!platformAssembliesPaths.empty()) {
+                               platformAssembliesPaths += ":";
+                       }
+                       platformAssembliesPaths += path;
+               }
+               argv.push_back(platformAssembliesPaths.c_str());
 
                bool enableR2R = flags & NI_FLAGS_ENABLER2R;
                if (!enableR2R) {
@@ -375,12 +385,6 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
                return -1;
        }
 
-       if (resetTACPackage(pkgId) != TAC_ERROR_NONE) {
-               fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkgId);
-               return -1;
-       }
-
-       // Regenerate ni files with R2R mode forcibiliy. (there is no way to now which option is used)
        if (createNIUnderPkgRoot(pkgId, *pFlags) != NI_ERROR_NONE) {
                fprintf(stderr, "Failed to generate NI file [%s]\n", pkgId);
                return -1;
@@ -388,13 +392,6 @@ static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
                fprintf(stdout, "Complete make application to native image\n");
        }
 
-       if (createTACPkgRoot(pkgId, *pFlags) != NI_ERROR_NONE) {
-               fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkgId);
-               return -1;
-       } else {
-               fprintf(stdout, "Complete make symbolic link file to tac\n");
-       }
-
        return 0;
 }
 
@@ -404,7 +401,7 @@ static bool isCoreLibPrepared(DWORD flags)
                return true;
        }
 
-       std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
+       std::string coreLibBackup = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll.Backup");
        if (isFile(coreLibBackup)) {
                return true;
        } else {
@@ -419,8 +416,8 @@ static bool hasCoreLibNI()
 {
        FILE *fp;
        char buff[1024];
-       std::string ildasm = concatPath(getRuntimeDir(), "ildasm");
-       std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
+       std::string ildasm = concatPath(__pm->getRuntimePath(), "ildasm");
+       std::string coreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll");
        std::string cmd = ildasm + " " + coreLib + " | grep '\\.corflags'";
        fp = popen(cmd.c_str(), "r");
        if (fp != NULL) {
@@ -441,9 +438,9 @@ static bool hasCoreLibNI()
 
 static ni_error_e createCoreLibNI(DWORD flags)
 {
-       std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
-       std::string niCoreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.ni.dll");
-       std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
+       std::string coreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll");
+       std::string niCoreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.ni.dll");
+       std::string coreLibBackup = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll.Backup");
 
        if (!isFile(coreLibBackup) && !hasCoreLibNI()) {
                if (!crossgen(coreLib, std::string(), flags)) {
@@ -463,7 +460,7 @@ static ni_error_e createCoreLibNI(DWORD flags)
        return NI_ERROR_NONE;
 }
 
-ni_error_e initNICommon(NICommonOption* option)
+ni_error_e initNICommon()
 {
 #if defined(__arm__) || defined(__aarch64__)
        // get interval value
@@ -478,12 +475,18 @@ ni_error_e initNICommon(NICommonOption* option)
                fprintf(stderr, "Fail to initialize PluginManager\n");
                return NI_ERROR_UNKNOWN;
        }
-       if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) {
-               fprintf(stderr, "Fail to initialize PathManager\n");
+
+       try {
+               __pm = new PathManager();
+       } catch (const std::exception& e) {
+               fprintf(stderr, "Failed to create PathManager");
                return NI_ERROR_UNKNOWN;
        }
 
-       __tpa = getTPA();
+       char* pluginDllPaths = pluginGetDllPath();
+       if (pluginDllPaths) {
+               __pm->addPlatformAssembliesPaths(pluginDllPaths);
+       }
 
        return NI_ERROR_NONE;
 #else
@@ -497,9 +500,9 @@ void finalizeNICommon()
        __interval = 0;
 
        finalizePluginManager();
-       finalizePathManager();
 
-       __tpa.clear();
+       delete(__pm);
+       __pm = nullptr;
 }
 
 ni_error_e createNIPlatform(DWORD flags)
@@ -508,8 +511,7 @@ ni_error_e createNIPlatform(DWORD flags)
                return NI_ERROR_CORE_NI_FILE;
        }
 
-       const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
-       return createNIUnderDirs(platformDirs, 2, flags);
+       return createNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath(), flags);
 }
 
 ni_error_e createNIDll(const std::string& dllPath, DWORD flags)
@@ -525,121 +527,67 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags)
        return crossgen(dllPath, std::string(), flags);
 }
 
-static void createNIUnderTAC(const std::vector<std::string>& nugets, DWORD flags)
+ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags)
 {
-       std::string appPaths;
-       for (auto& nuget : nugets) {
-               appPaths += concatPath(__DOTNET_DIR, nuget);
-               appPaths += ':';
-       }
-       if (appPaths.back() == ':') {
-               appPaths.pop_back();
+       if (!isCoreLibPrepared(flags)) {
+               return NI_ERROR_CORE_NI_FILE;
        }
 
-       auto convert = [&appPaths, flags](const std::string& path, const std::string& filename) {
-               if (strstr(path.c_str(), TAC_SHA_256_INFO) != NULL)
-                       return;
-               if (!crossgen(path, appPaths.c_str(), flags)) {
+       auto convert = [&rootPaths, flags](const std::string& path, const std::string& filename) {
+
+               // if path is symlink, donot generate crossgen
+               if (!crossgen(path, rootPaths.c_str(), flags)) {
                        waitInterval();
                }
        };
-       for (auto& nuget : nugets) {
-               scanFilesInDirectory(concatPath(__DOTNET_DIR, nuget), convert, -1);
-       }
-}
 
-ni_error_e createTACPkgRoot(const std::string& pkgId, DWORD flags)
-{
-       if (!isCoreLibPrepared(flags)) {
-               return NI_ERROR_CORE_NI_FILE;
-       }
+       std::vector<std::string> targetPaths;
+       splitPath(rootPaths, targetPaths);
+       for (const auto &path : targetPaths) {
+               // TAC directory should be handled specially because that contains symlink of native image file.
+               if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) {
+                       if (!isDirectory(path)) {
+                               continue;
+                       }
+                       // make native image symlink if not exist under tac directory
+                       try {
+                               for (auto& symlinkAssembly : bf::recursive_directory_iterator(path)) {
+                                       std::string symPath = symlinkAssembly.path().string();
+                                       if (!isManagedAssembly(symPath)) {
+                                               continue;
+                                       }
 
-       std::string rootPath = getRootPath(pkgId);
-       if (rootPath.empty()) {
-               fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
-               return NI_ERROR_INVALID_PACKAGE;
-       }
+                                       // if there is symlink and original file for native image, skip generation
+                                       std::string symNIPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll";
+                                       if (isFile(symNIPath)) {
+                                               continue;
+                                       }
 
-       std::string binDir = concatPath(rootPath, "bin");
-       std::string libDir = concatPath(rootPath, "lib");
-       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
-       std::string paths = binDir + ":" + libDir + ":" + tacDir;
-       if (bf::exists(tacDir)) {
-               try {
-                       for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
-                               std::string symPath = symlinkAssembly.path().string();
-                               if (bf::is_symlink(symPath)) {
-                                       if (!isNativeImage(symPath)) {
-                                               std::string originPath = bf::read_symlink(symPath).string();
-                                               std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
-                                               if (!bf::exists(originNIPath)) {
-                                                       flags |= NI_FLAGS_APPNI;
-                                                       if (crossgen(originPath, paths, flags) != NI_ERROR_NONE) {
-                                                               fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
-                                                               return NI_ERROR_UNKNOWN;
-                                                       }
-                                               }
-                                               std::string symNIPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll";
-                                               if (!bf::exists(symNIPath)) {
-                                                       bf::create_symlink(originNIPath, symNIPath);
-                                                       fprintf(stdout, "%s symbolic link file generated successfully.\n", symNIPath.c_str());
-                                                       copySmackAndOwnership(tacDir.c_str(), symNIPath.c_str(), true);
-
-                                                       std::string niFileName = symNIPath.substr(symNIPath.rfind('/') + 1);
-                                                       if (!removeFile(concatPath(binNIDir, niFileName))) {
-                                                               fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, niFileName).c_str());
-                                                       }
+                                       // if original native image not exist, generate native image
+                                       std::string originPath = bf::read_symlink(symPath).string();
+                                       std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
+                                       if (!isFile(originNIPath)) {
+                                               if (!crossgen(originPath, path.c_str(), flags)) {
+                                                       waitInterval();
                                                }
                                        }
-                               }
-                       }
-               } catch (const bf::filesystem_error& error) {
-                       fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
-                       return NI_ERROR_UNKNOWN;
-               }
-       }
-       return NI_ERROR_NONE;
-}
-
-ni_error_e createNIUnderDirs(const std::string rootPaths[], int count, DWORD flags)
-{
-       if (!isCoreLibPrepared(flags)) {
-               return NI_ERROR_CORE_NI_FILE;
-       }
-
-       std::string appPaths;
-       for (int i = 0; i < count; i++) {
-               appPaths += rootPaths[i];
-               appPaths += ':';
-       }
 
-       if (appPaths.back() == ':')
-               appPaths.pop_back();
-
-       std::vector<std::string> tpaAssemblies;
-       splitPath(__tpa, tpaAssemblies);
-
-       auto convert = [&appPaths, flags, tpaAssemblies](const std::string& path, const std::string& filename) {
-               bool isAppNI = flags & NI_FLAGS_APPNI;
-               if (isAppNI) {
-                       for (auto& tpa : tpaAssemblies) {
-                               if (!strcmp(replaceAll(tpa.substr(tpa.rfind('/') + 1), ".ni.dll", ".dll").c_str(), filename.c_str())) {
-                                       fprintf(stderr, "%s present in the TPA list skips generation of NI file.\n", filename.c_str());
-                                       return;
+                                       // if no symlink file exist, create symlink
+                                       if (!isFile(symNIPath)) {
+                                               bf::create_symlink(originNIPath, symNIPath);
+                                               copySmackAndOwnership(symPath.c_str(), symNIPath.c_str(), true);
+                                               fprintf(stdout, "%s symbolic link file generated successfully.\n", symNIPath.c_str());
+                                       }
                                }
+                       } catch (const bf::filesystem_error& error) {
+                               fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
+                               return NI_ERROR_UNKNOWN;
                        }
+               } else {
+                       scanFilesInDirectory(path, convert, 0);
                }
-               if (!crossgen(path, appPaths.c_str(), flags)) {
-                       waitInterval();
-               }
-       };
-
-       for (int i = 0; i < count; i++) {
-               scanFilesInDirectory(rootPaths[i], convert, 0);
        }
 
-       tpaAssemblies.clear();
        return NI_ERROR_NONE;
 }
 
@@ -651,78 +599,19 @@ ni_error_e createNIUnderPkgRoot(const std::string& pkgId, DWORD flags)
                return NI_ERROR_INVALID_PACKAGE;
        }
 
-       std::string binDir = concatPath(rootPath, "bin");
-       std::string libDir = concatPath(rootPath, "lib");
-       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       std::string paths[] = {binDir, libDir, tacDir};
+       __pm->setAppRootPath(rootPath);
 
        flags |= NI_FLAGS_APPNI;
-       return createNIUnderDirs(paths, 3, flags);
-}
-
-ni_error_e createNIDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, DWORD flags)
-{
-       if (!isCoreLibPrepared(flags)) {
-               return NI_ERROR_CORE_NI_FILE;
-       }
-
-       std::string rootPath = getRootPath(pkgId);
-       if (rootPath.empty()) {
-               fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
-               return NI_ERROR_INVALID_PACKAGE;
-       }
 
-       std::string binDir = concatPath(rootPath, "bin");
-       std::string libDir = concatPath(rootPath, "lib");
-       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
-       std::string paths = binDir + ":" + libDir + ":" + tacDir;
-
-       if (bf::is_symlink(dllPath)) {
-               if (bf::exists(tacDir)) {
-                       if (!isNativeImage(dllPath)) {
-                               std::string originPath = bf::read_symlink(dllPath).string();
-                               std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
-                               if (!bf::exists(originNIPath)) {
-                                       flags |= NI_FLAGS_APPNI;
-                                       if (crossgen(originPath, paths, flags) != NI_ERROR_NONE) {
-                                               fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
-                                               return NI_ERROR_UNKNOWN;
-                                       }
-                               }
-                               std::string setNIPath = dllPath.substr(0, dllPath.rfind(".dll")) + ".ni.dll";
-                               if (!bf::exists(setNIPath)) {
-                                       bf::create_symlink(originNIPath, setNIPath);
-                                       fprintf(stdout, "%s symbolic link file generated successfully.\n", setNIPath.c_str());
-                                       copySmackAndOwnership(tacDir.c_str(), setNIPath.c_str(), true);
-                               }
-                               std::string niFileName = setNIPath.substr(setNIPath.rfind('/') + 1);
-                               if (!removeFile(concatPath(binNIDir, niFileName))) {
-                                       fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, niFileName).c_str());
-                               }
-                       }
-               }
-               return NI_ERROR_NONE;
-       } else {
-               std::string assembly = dllPath.substr(dllPath.rfind('/') + 1);
-               std::vector<std::string> tpaAssemblies;
-               splitPath(__tpa, tpaAssemblies);
-               for (auto& tpa : tpaAssemblies) {
-                       if (!strcmp(replaceAll(tpa.substr(tpa.rfind('/') + 1), ".ni.dll", ".dll").c_str(), assembly.c_str())) {
-                               fprintf(stderr, "%s present in the TPA list skips generation of NI file.\n", assembly.c_str());
-                               return NI_ERROR_NONE;
-                       }
-               }
-               tpaAssemblies.clear();
-               flags |= NI_FLAGS_APPNI;
-               return crossgen(dllPath, paths, flags);
-       }
+       // create native image under bin and lib directory
+       // tac directory is skipped in the createNIUnderDirs.
+       return createNIUnderDirs(__pm->getAppPaths(), flags);
 }
 
 void removeNIPlatform()
 {
-       std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
-       std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
+       std::string coreLib = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll");
+       std::string coreLibBackup = concatPath(__pm->getRuntimePath(), "System.Private.CoreLib.dll.Backup");
 
        if (hasCoreLibNI()) {
                if (!isFile(coreLibBackup)) {
@@ -745,12 +634,10 @@ void removeNIPlatform()
        }
 #endif
 
-       const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
-
-       removeNIUnderDirs(platformDirs, 2);
+       removeNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath());
 }
 
-void removeNIUnderDirs(const std::string rootPaths[], int count)
+void removeNIUnderDirs(const std::string rootPaths)
 {
        auto convert = [](const std::string& path, const std::string& filename) {
                if (isNativeImage(path)) {
@@ -760,8 +647,10 @@ void removeNIUnderDirs(const std::string rootPaths[], int count)
                }
        };
 
-       for (int i = 0; i < count; i++) {
-               scanFilesInDirectory(rootPaths[i], convert, -1);
+       std::vector<std::string> paths;
+       splitPath(rootPaths, paths);
+       for (const auto &path : paths) {
+               scanFilesInDirectory(path, convert, -1);
        }
 }
 
@@ -773,23 +662,22 @@ ni_error_e removeNIUnderPkgRoot(const std::string& pkgId)
                return NI_ERROR_INVALID_PACKAGE;
        }
 
-       std::string binDir = concatPath(rootPath, "bin");
-       std::string libDir = concatPath(rootPath, "lib");
-       std::string paths[] = {binDir, libDir};
-
-       removeNIUnderDirs(paths, 2);
+       __pm->setAppRootPath(rootPath);
 
-       std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
-       if (isFile(binNIDir)) {
-               if (!removeAll(binNIDir.c_str())) {
-                       fprintf(stderr, "Failed to remove app ni dir [%s]\n", binNIDir.c_str());
-               }
-       }
-
-       std::string libNIDir = concatPath(libDir, APP_NI_SUB_DIR);
-       if (isFile(libNIDir)) {
-               if (!removeAll(libNIDir.c_str())) {
-                       fprintf(stderr, "Failed to remove app ni dir [%s]\n", libNIDir.c_str());
+       // getAppNIPaths returns bin/.native_image, lib/.native_image and .tac_symlink.
+       std::string appNIPaths = __pm->getAppNIPaths();
+       std::vector<std::string> paths;
+       splitPath(appNIPaths, paths);
+       for (const auto &path : paths) {
+               // Only the native image inside the TAC should be removed.
+               if (strstr(path.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) {
+                       removeNIUnderDirs(path);
+               } else {
+                       if (isDirectory(path)) {
+                               if (!removeAll(path.c_str())) {
+                                       fprintf(stderr, "Failed to remove app ni dir [%s]\n", path.c_str());
+                               }
+                       }
                }
        }
 
@@ -835,7 +723,7 @@ static int regenTacCb(pkgmgrinfo_appinfo_h handle, void *userData)
        DWORD *pFlags = (DWORD*)userData;
 
        int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
-       if (ret != PMINFO_R_OK) {
+       if (ret != PMINFO_R_OK || pkgId == NULL) {
                fprintf(stderr, "Failed to get pkgid\n");
                return -1;
        }
@@ -855,7 +743,25 @@ static int regenTacCb(pkgmgrinfo_appinfo_h handle, void *userData)
                tac_db = NULL;
        }
 
-       createNIUnderTAC(nugets, *pFlags);
+       std::string nugetPaths;
+       for (const auto &nuget : nugets) {
+               if (!nugetPaths.empty()) {
+                       nugetPaths += ":";
+               }
+               nugetPaths += concatPath(__DOTNET_DIR, nuget);
+       }
+
+       auto convert = [&nugetPaths, pFlags](const std::string& path, const std::string& filename) {
+               if (strstr(path.c_str(), TAC_SHA_256_INFO) != NULL)
+                       return;
+               if (!crossgen(path, nugetPaths.c_str(), *pFlags)) {
+                       waitInterval();
+               }
+       };
+
+       for (auto& nuget : nugets) {
+               scanFilesInDirectory(concatPath(__DOTNET_DIR, nuget), convert, -1);
+       }
 
        return 0;
 }
@@ -866,8 +772,7 @@ ni_error_e regenerateTACNI(DWORD flags)
                return NI_ERROR_CORE_NI_FILE;
        }
 
-       const std::string tacDir[] = {__DOTNET_DIR};
-       removeNIUnderDirs(tacDir, 1);
+       removeNIUnderDirs(__DOTNET_DIR);
 
        pkgmgrinfo_appinfo_metadata_filter_h handle;
        int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
index 29b6b788861e7e38cb0cf566f5bb06d042121f2b..1b99e3fea82301b42bbfb4b418ce6408c9fdf339 100644 (file)
@@ -52,12 +52,9 @@ int main(int argc, char* argv[])
        DWORD flags = 0;
        bool pkgMode = false;
        bool dllMode = false;
-       bool dirMode = false;
        bool rmPkgMode = false;
-       bool pkgDllMode = false;
 
-       NICommonOption option = {std::string(), std::string(), std::string()};
-       if (initNICommon(&option) != NI_ERROR_NONE) {
+       if (initNICommon() != NI_ERROR_NONE) {
                return -1;
        }
 
@@ -86,8 +83,6 @@ int main(int argc, char* argv[])
                dllMode = true;
        } else if (cmdOptionExists(argv, argv+argc, "--pkg")) {
                pkgMode = true;
-       } else if (cmdOptionExists(argv, argv+argc, "--dir")) {
-               dirMode = true;
        } else if (cmdOptionExists(argv, argv+argc, "--reset-system")) {
                removeNIPlatform();
                return 0;
@@ -96,8 +91,6 @@ int main(int argc, char* argv[])
        } else if (cmdOptionExists(argv, argv+argc, "--regen-all-app")) {
                regenerateAppNI(flags);
                return 0;
-       } else if (cmdOptionExists(argv, argv+argc, "--pkg-dll")) {
-               pkgDllMode = true;
        } else {
                help(argv[0]);
                return 0;
@@ -126,18 +119,6 @@ int main(int argc, char* argv[])
                                return -1;
                        }
                }
-       } else if (pkgDllMode) {
-               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;
-               } 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) {
                        int ret = removeNIUnderPkgRoot(pkg);
@@ -160,8 +141,6 @@ int main(int argc, char* argv[])
                                fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
                        }
                }
-       } else if (dirMode) {
-               createNIUnderDirs(args.data(), args.size(), flags);
        }
 
        return 0;
index 844ad5e65708865259ac290b2a4795f20a555daf..a982b267703a4fe14e2b699120f436afefdc1abc 100644 (file)
@@ -107,7 +107,7 @@ static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
        std::vector<std::string> parserData;
        std::string binDir = concatPath(rootPath, "bin");
        std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
+       for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
                std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
                std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
                if (bf::exists(tacDir) && bf::exists(concatPath(tacDir, assemblyName))) {
@@ -146,11 +146,6 @@ tac_error_e restoreTACDB()
                return TAC_ERROR_UNKNOWN;
        }
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               fprintf(stderr, "Fail to initialize PathManger\n");
-               return TAC_ERROR_UNKNOWN;
-       }
-
        tac_db = dbCreate(TAC_APP_LIST_RESTORE_DB, CREATE_TAC_DB_TABLE);
        if (!tac_db) {
                fprintf(stderr, "Sqlite create error\n");
@@ -217,42 +212,6 @@ tac_error_e restoreTACDB()
        return TAC_ERROR_NONE;
 }
 
-tac_error_e resetTACPackage(const std::string& pkgId)
-{
-       std::string rootPath = getRootPath(pkgId);
-       if (rootPath.empty()) {
-               fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
-               return TAC_ERROR_INVALID_PACKAGE;
-       }
-
-       std::vector<std::string> tacNativeImage;
-       std::string binDir = concatPath(rootPath, "bin");
-       std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
-       if (bf::exists(tacDir)) {
-               try {
-                       for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
-                               std::string symPath = symlinkAssembly.path().string();
-                               if (bf::is_symlink(symPath)) {
-                                       if (isNativeImage(symPath)) {
-                                               tacNativeImage.push_back(symPath);
-                                       }
-                               }
-                       }
-                       for (auto& path : tacNativeImage) {
-                               if (!removeFile(path)) {
-                                       fprintf(stderr, "Failed to remove of %s\n", path.c_str());
-                                       return TAC_ERROR_UNKNOWN;
-                               }
-                       }
-                       tacNativeImage.clear();
-               } catch (const bf::filesystem_error& error) {
-                       fprintf(stderr, "Failed to recursive directory: %s\n", error.what());
-                       return TAC_ERROR_UNKNOWN;
-               }
-       }
-       return TAC_ERROR_NONE;
-}
-
 tac_error_e disableTACPackage(const std::string& pkgId)
 {
        std::string rootPath = getRootPath(pkgId);
@@ -320,11 +279,6 @@ tac_error_e enableTACPackage(const std::string& pkgId)
                return TAC_ERROR_INVALID_PACKAGE;
        }
 
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               fprintf(stderr, "Fail to initialize PathManger\n");
-               return TAC_ERROR_UNKNOWN;
-       }
-
        if (!strcmp(metaValue.c_str(), "true")) {
                std::string binDir = concatPath(rootPath, "bin");
                std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
@@ -337,7 +291,7 @@ tac_error_e enableTACPackage(const std::string& pkgId)
                        copySmackAndOwnership(binDir.c_str(), tacDir.c_str());
 
                        std::vector<std::string> enableNuget;
-                       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
+                       for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
                                std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
                                std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
                                std::string nugetPath = concatPath(__DOTNET_DIR, nugetPackage);
@@ -390,11 +344,8 @@ tac_error_e enableTACPackage(const std::string& pkgId)
 }
 
 //Parser the .deps.json file to get nuget information.
-std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName, const std::string& tpaList)
+std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::string& execName)
 {
-       std::vector<std::string> tpaAssemblies;
-       splitPath(tpaList, tpaAssemblies);
-
        std::vector<std::string> parserData;
        std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json";
        std::string depsJsonPath = concatPath(rootPath, depsJsonName);
@@ -408,7 +359,6 @@ std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::
                                if (!Json::parseFromStream(reader, ifs, &root, &error)) {
                                        _ERR("Failed to parse of deps.json");
                                        ifs.close();
-                                       tpaAssemblies.clear();
                                        return parserData;
                                }
                                const Json::Value runtimeTargetName = root["runtimeTarget"]["name"];
@@ -453,25 +403,11 @@ std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::
                                                                }
                                                        }
                                                        if (!hasDependency) {
-                                                               bool isExistTpaAssembly = false;
+                                                               // handle assembly even though that is included in the TPA.
                                                                for (auto& assembly : assemblies.getMemberNames()) {
                                                                        std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
-                                                                       //Skip the assembly present in the TPA list
-                                                                       for (auto& tpaPath : tpaAssemblies) {
-                                                                               std::string tpaName = replaceAll(tpaPath.substr(tpaPath.rfind('/') + 1), ".ni.dll", ".dll");
-                                                                               if (!strcmp(tpaName.c_str(), assemblyName.c_str())) {
-                                                                                       isExistTpaAssembly = true;
-                                                                                       break;
-                                                                               }
-                                                                       }
-                                                                       if (isExistTpaAssembly) break;
-                                                               }
-                                                               if (!isExistTpaAssembly) {
-                                                                       for (auto& assembly : assemblies.getMemberNames()) {
-                                                                               std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
-                                                                               parserData.push_back(nuget + ":" + assemblyName);
-                                                                               _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str());
-                                                                       }
+                                                                       parserData.push_back(nuget + ":" + assemblyName);
+                                                                       _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str());
                                                                }
                                                        }
                                                }
@@ -484,6 +420,5 @@ std::vector<std::string> depsJsonParser(const std::string& rootPath, const std::
        } catch (const Json::LogicError& error) {
                _ERR("Failed to parse Json: %s", error.what());
        }
-       tpaAssemblies.clear();
        return parserData;
 }
index 197bf50ddb5a5ec6797f3e705fbade7ab8633556..ef00bf51047392777784a837f5e798dd4b562ba9 100644 (file)
 
 int main(int argc, char* argv[])
 {
-       if (initializePathManager(std::string(), std::string(), std::string())) {
-               fprintf(stderr, "Fail to initialize PathManager\n");
+       PathManager* __pm = nullptr;
+       try {
+               __pm = new PathManager();
+       }  catch (const std::exception& e) {
+               fprintf(stderr, "Failed to create PathManager");
                return -1;
        }
 
-       std::string tpaList = getTPA();
+       std::string tpaList;
+       addAssembliesFromDirectories(__pm->getPlatformAssembliesPaths(), tpaList);
+
        if (!bf::is_symlink(PLATFORM_TPA_CACHE)) {
                std::ofstream out(PLATFORM_TPA_CACHE);
                out << tpaList;
@@ -38,5 +43,8 @@ int main(int argc, char* argv[])
                return -1;
        }
 
+       delete(__pm);
+       __pm = nullptr;
+
        return 0;
 }
index d89b84e02335d44d2eb3ee57c2b955dfd9e553b4..250f6fbb1db5edba311bf31c8e97fbb91679999a 100644 (file)
  * limitations under the License.
  */
 
-#include <vector>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #include <iterator>
 #include <sstream>
 #include <vconf.h>
 #include <fstream>
 
 #include "utils.h"
+#include "path_manager.h"
 #include "plugin_manager.h"
 #include "log.h"
 
 static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path";
+static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version";
 
 #define __XSTR(x) #x
 #define __STR(x) __XSTR(x)
 static const char* __DEVICE_API_DIR = __STR(DEVICE_API_DIR);
 static const char* __RUNTIME_DIR = __STR(RUNTIME_DIR);
+static const char* __NATIVE_LIB_DIR = __STR(NATIVE_LIB_DIR);
+
 #undef __STR
 #undef __XSTR
 
-typedef struct DllPath {
-       std::string runtime_dir;
-       std::string tizenfx_dir;
-       std::string tizenfx_ref_dir;
-       std::vector<std::string> extra_dirs;
-       std::vector<std::string> plugin_dirs;
-} DllPath;
+#if defined (__aarch64__)
+#define ARCHITECTURE_IDENTIFIER "arm64"
 
-static DllPath* __dllPath = nullptr;
-static std::string __tpa;
-bool initializedPathManager = false;
+#elif defined (__arm__)
+#define ARCHITECTURE_IDENTIFIER "armel"
 
-// on success, return 0. otherwise return -1.
-int initializePathManager(const std::string& runtimeDir, const std::string& tizenFXDir, const std::string& extraDir)
-{
-       if (initializedPathManager) {
-               _INFO("Path manager already initialized");
-               return 0;
-       }
+#elif defined (__x86_64__)
+#define ARCHITECTURE_IDENTIFIER "x64"
 
-       __dllPath = new DllPath();
-       if (!__dllPath) {
-               _ERR("fail to allocate memory for dll path structure\n");
-               return -1;
-       }
+#elif defined (__i386__)
+#define ARCHITECTURE_IDENTIFIER "x86"
 
-       if (!runtimeDir.empty()) {
-               __dllPath->runtime_dir = getAbsolutePath(runtimeDir);
-       } else {
-               __dllPath->runtime_dir = getAbsolutePath(__RUNTIME_DIR);
-       }
+#else
+#error "Unknown target"
+#endif
 
-       if (!tizenFXDir.empty()) {
-               __dllPath->tizenfx_dir = getAbsolutePath(tizenFXDir);
-       } else {
-               char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY);
-               if (tmp) {
-                       __dllPath->tizenfx_dir = std::string(tmp);
-                       _DBG("Device API Directory is set by vconf : %s", tmp);
-                       free(tmp);
-               } else {
-                       __dllPath->tizenfx_dir = getAbsolutePath(__DEVICE_API_DIR);
+// The sequence of RID_FALLBACK graphs must be:
+// 1. Tizen + Version + Architecture
+// 2. Tizen + Version
+// 3. OS(tizen, linux, unix) + Architecture
+// 4. OS(tizen, linux, unix)
+// 5. any, base
+static std::string getExtraNativeLibDirs(const std::string& appRoot)
+{
+       std::vector<std::string> RID_FALLBACK_GRAPH;
+       char* tizen_rid = vconf_get_str(__TIZEN_RID_VERSION_KEY);
+       if (tizen_rid) {
+               std::vector<std::string> version;
+               splitPath(tizen_rid, version);
+               std::reverse(std::begin(version), std::end(version));
+               for (unsigned int i = 0; i < version.size(); i++) {
+                       RID_FALLBACK_GRAPH.push_back(std::string("tizen." + version[i] + "-" + ARCHITECTURE_IDENTIFIER));
+                       RID_FALLBACK_GRAPH.push_back(std::string("tizen." + version[i]));
                }
+               free(tizen_rid);
        }
 
-       __dllPath->tizenfx_ref_dir = __dllPath->tizenfx_dir + "/ref";
+       std::vector<std::string> RID_FALLBACK_OS = {"tizen", "linux", "unix"};
+       for (unsigned int i = 0; i < RID_FALLBACK_OS.size(); i++) {
+               RID_FALLBACK_GRAPH.push_back(std::string(RID_FALLBACK_OS[i] + "-" +  ARCHITECTURE_IDENTIFIER));
+               RID_FALLBACK_GRAPH.push_back(std::string(RID_FALLBACK_OS[i]));
+       }
+       RID_FALLBACK_GRAPH.push_back("any");
+       RID_FALLBACK_GRAPH.push_back("base");
 
-       // ":" seperated extra directories
-       if (!extraDir.empty()) {
-               splitPath(extraDir, __dllPath->extra_dirs);
+       std::string candidate;
+       for (unsigned int i = 0; i < RID_FALLBACK_GRAPH.size(); i++) {
+               if (!candidate.empty()) {
+                       candidate += ":";
+               }
+               candidate += concatPath(appRoot, "bin/runtimes/" + RID_FALLBACK_GRAPH[i] + "/native");
        }
 
-       char* pluginPath = pluginGetDllPath();
-       if (pluginPath) {
-               splitPath(pluginPath, __dllPath->plugin_dirs);
+       candidate = candidate + ":" + concatPath(appRoot, "lib/" ARCHITECTURE_IDENTIFIER);
+       if (!strncmp(ARCHITECTURE_IDENTIFIER, "arm64", 5)) {
+               candidate = candidate + ":" + concatPath(appRoot, "lib/aarch64");
+       } else if (!strncmp(ARCHITECTURE_IDENTIFIER, "armel", 5)) {
+               candidate = candidate + ":" + concatPath(appRoot, "lib/arm");
        }
 
-       _INFO("Path manager initialize success");
+       return candidate;
+}
 
-       initializedPathManager = true;
-       return 0;
+void PathManager::updateAppRelatedPath(const std::string& appRootPath)
+{
+       std::string appBinPath = concatPath(appRootPath, "bin");
+       std::string appLibPath = concatPath(appRootPath, "lib");
+
+       appTacPath = concatPath(appBinPath, TAC_SYMLINK_SUB_DIR);
+       appPaths = appRootPath + ":" + appBinPath + ":" + appLibPath + ":" + appTacPath;
+       appNIPaths = concatPath(appBinPath, APP_NI_SUB_DIR) + ":" + concatPath(appLibPath, APP_NI_SUB_DIR) + ":"+ appTacPath;
+       nativeDllSearchingPaths = runtimePath + ":" + __NATIVE_LIB_DIR + ":" + getExtraNativeLibDirs(appRootPath) + ":" + appBinPath + ":" + appLibPath;
 }
 
-void finalizePathManager()
+PathManager::PathManager() :
+       rootFD(-1)
 {
-       _INFO("Path manager finalize called");
-       if (__dllPath) {
-               delete __dllPath;
-               __dllPath = NULL;
+       // set runtime path
+       runtimePath = getAbsolutePath(__RUNTIME_DIR);
+       platformAssembliesPaths.push_back(runtimePath);
+
+       // set tizenfx path
+       char* tmp = vconf_get_str(__TIZEN_API_PATH_KEY);
+       if (tmp) {
+               tizenfxPath = std::string(tmp);
+               _DBG("Device API Directory is set by vconf : %s", tmp);
+               free(tmp);
+       } else {
+               tizenfxPath = getAbsolutePath(__DEVICE_API_DIR);
        }
+       platformAssembliesPaths.push_back(tizenfxPath);
+       platformAssembliesPaths.push_back(tizenfxPath + "/ref");
+
+       // set temporal application root path for candidate process
+       rootFD = open("/proc/self", O_DIRECTORY);
+       if (rootFD < 0) {
+               _ERR("Failed to open /proc/self");
+               throw std::ios_base::failure("Fail to open /proc/self");
+       }
+
+       appRootPath = std::string("/proc/self/fd/") + std::to_string(rootFD);
+       updateAppRelatedPath(appRootPath);
 
-       initializedPathManager = false;
+       _INFO("Path manager created successfully");
 }
 
-std::string getRuntimeDir()
+PathManager::~PathManager()
 {
-       return __dllPath->runtime_dir;
+       _INFO("Path manager destroyed");
 }
 
-std::string getTizenFXDir()
+// paths: ":" separated muliple path.
+void PathManager::addPlatformAssembliesPaths(const std::string& paths, bool isHighPriority)
 {
-       return __dllPath->tizenfx_dir;
+       std::vector<std::string>::iterator it;
+       std::vector<std::string> pathVec;
+       splitPath(paths, pathVec);
+
+       for (unsigned int i = 0; i < pathVec.size(); i++) {
+               pathVec[i] = getAbsolutePath(pathVec[i]);
+       }
+
+       if (isHighPriority) {
+               it = platformAssembliesPaths.begin();
+       } else {
+               it = platformAssembliesPaths.end();
+       }
+
+       platformAssembliesPaths.insert(it, pathVec.begin(), pathVec.end());
 }
 
-std::string getTizenFXRefDir()
+void PathManager::setAppRootPath(const std::string& rootPath)
 {
-       return __dllPath->tizenfx_ref_dir;
+       // override root path for application launch mode (candidate / standalone mode)
+       if (rootFD >= 0) {
+               int tmpFD = open(rootPath.c_str(), O_DIRECTORY);
+               dup3(tmpFD, rootFD, O_CLOEXEC);
+               if (tmpFD >= 0)
+                       close(tmpFD);
+       }
+
+       appRootPath = getAbsolutePath(rootPath);
+       updateAppRelatedPath(appRootPath);
 }
 
-std::vector<std::string> getExtraDirs()
+const std::string& PathManager::getRuntimePath()
 {
-       return __dllPath->extra_dirs;
+       return runtimePath;
 }
 
-std::vector<std::string> getPluginDirs()
+const std::string& PathManager::getTizenFXPath()
 {
-       return __dllPath->plugin_dirs;
+       return tizenfxPath;
 }
 
-static std::string getPlatformTPA()
+// return platform assembly paths
+const std::vector<std::string>& PathManager::getPlatformAssembliesPaths()
 {
-       std::string platform_tpa;
-
-       if (isFile(PLATFORM_TPA_CACHE)) {
-               _INFO("platform tpa cache found.");
-               std::ifstream cacheFile;
-               cacheFile.open(PLATFORM_TPA_CACHE);
-               std::getline(cacheFile, platform_tpa);
-               cacheFile.close();
-       } else {
-               std::vector<std::string> tpaDirs = { getRuntimeDir(), getTizenFXDir(), getTizenFXRefDir() };
-               tpaDirs.insert(tpaDirs.end(), getExtraDirs().begin(), getExtraDirs().end());
-               addAssembliesFromDirectories(tpaDirs, platform_tpa);
-       }
-
-       return platform_tpa;
+       return platformAssembliesPaths;
 }
 
-static std::string getPluginTPA()
+// return app root path
+const std::string& PathManager::getAppRootPath()
 {
-       std::string plugin_tpa;
-       char* plugin_tpa_list = pluginGetTPA();
-       if (plugin_tpa_list) {
-               _INFO("plugin TPA list found. use TPA list for plugin");
-               plugin_tpa = plugin_tpa_list;
-       } else if (!getPluginDirs().empty()) {
-               _INFO("Plugin directory found. use plugin directroy for TPA");
-               addAssembliesFromDirectories(getPluginDirs(), plugin_tpa);
-       }
+       return appRootPath;
+}
 
-       return plugin_tpa;
+// return .tac_symlink path
+const std::string& PathManager::getAppTacPath()
+{
+       return appTacPath;
 }
 
-std::string getTPA()
+// return dll searching paths for app
+const std::string& PathManager::getAppPaths()
 {
-       if (!__tpa.empty()) {
-               return __tpa;
-       }
+       return appPaths;
+}
 
-       if (__dllPath == NULL) {
-               return std::string("");
-       }
+// return ni dll searching paths for app
+const std::string& PathManager::getAppNIPaths()
+{
+       return appNIPaths;
+}
 
-       return getPlatformTPA() + ":" + getPluginTPA();
+// return native dll searching paths for app 
+const std::string& PathManager::getNativeDllSearchingPaths()
+{
+       return nativeDllSearchingPaths;
 }
+
index 5b047aed3907b3e9f6bed73518f674bd9e974f36..90fd0e432a0227703dd89081a641c0fc4fd37b10 100644 (file)
@@ -269,7 +269,7 @@ std::string replaceAll(const std::string& str, const std::string& pattern, const
 bool isFile(const std::string& path)
 {
        struct stat sb;
-       return stat(path.c_str(), &sb) == 0;
+       return lstat(path.c_str(), &sb) == 0;
 }
 
 bool isDirectory(const std::string& path)
@@ -339,9 +339,6 @@ void scanFilesInDirectory(const std::string& directory, FileReader reader, unsig
        struct dirent* entry;
        bool isDir;
 
-       if (strstr(directory.c_str(), TAC_SYMLINK_SUB_DIR) != NULL)
-               return;
-
        dir = opendir(directory.c_str());
 
        if (dir == nullptr)
@@ -357,14 +354,12 @@ void scanFilesInDirectory(const std::string& directory, FileReader reader, unsig
                        case DT_DIR:
                                isDir = true;
                                break;
+                       // symlink is added to the list even if there is no original file.
+                       // It used to remove broken symlinks related to TAC
                        case DT_LNK:
+                               break;
                        case DT_UNKNOWN:
-                               struct stat sb;
-                               if (stat(path.c_str(), &sb) == -1)
-                                       continue;
-
-                               if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode))
-                                       break;
+                               continue;
                        default:
                                continue;
                }
index 00ad53ab80540d31f11fc7955d8964b03faacb61..8670b5e1a1d99b60488fa5b4302a1548df8719d5 100644 (file)
@@ -169,7 +169,6 @@ chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
 %{_loaderdir}/dotnet-nui.launcher
 %{_loaderdir}/dotnet-nui.debugger
 %{_native_lib_dir}/libsqlite3.so
-%{_bindir}/nitool
 %{_bindir}/tpatool
 %{_bindir}/dotnettool
 %{_install_mdplugin_dir}/libprefer_nuget_cache_plugin.so