Refactoring dotnet-launcher 57/182657/3
authorWoongsuk Cho <ws77.cho@samsung.com>
Wed, 27 Jun 2018 02:23:14 +0000 (11:23 +0900)
committerWoongsuk Cho <ws77.cho@samsung.com>
Wed, 27 Jun 2018 04:29:34 +0000 (13:29 +0900)
- remove unused code
- use std::string instead of char* to reduce human failure
- remove LauncherInterface
- create path manager and plugin manager
- provide AOT functionality to external
- dev package support
- some AOT functionality is added (dlls under package root)

Change-Id: I26972910324b60174cc2cf3ff6ec28da4a2fcd18

23 files changed:
NativeLauncher/CMakeLists.txt
NativeLauncher/dotnet-launcher.pc.in [new file with mode: 0644]
NativeLauncher/inc/coreclr_host.h [new file with mode: 0644]
NativeLauncher/inc/dotnet_launcher_plugin.h [new file with mode: 0644]
NativeLauncher/inc/plugin_manager.h [new file with mode: 0644]
NativeLauncher/inc/utils.h
NativeLauncher/installer-plugin/common.cc [deleted file]
NativeLauncher/installer-plugin/common.h [deleted file]
NativeLauncher/installer-plugin/ni_common.cc [new file with mode: 0644]
NativeLauncher/installer-plugin/ni_common.h [new file with mode: 0644]
NativeLauncher/installer-plugin/nitool.cc
NativeLauncher/installer-plugin/prefer_dotnet_aot_plugin.cc
NativeLauncher/installer-plugin/ui-application.cc
NativeLauncher/launcher/dotnet/dotnet_launcher.cc
NativeLauncher/launcher/dotnet/dotnet_launcher.h
NativeLauncher/launcher/launcher.cc
NativeLauncher/launcher/launcher.h
NativeLauncher/launcher/main.cc
NativeLauncher/util/path_manager.cc [new file with mode: 0644]
NativeLauncher/util/path_manager.h [new file with mode: 0644]
NativeLauncher/util/plugin_manager.cc [new file with mode: 0644]
NativeLauncher/util/utils.cc
packaging/dotnet-launcher.spec

index 98d60c894e6a993a39013cb2b14365472d7b13bc..b53ec6fc2f4bdd169f755810eb748efecde67a4e 100644 (file)
@@ -3,12 +3,8 @@ PROJECT("dotnet-tools")
 
 MESSAGE("CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
 
-IF(DEFINED NO_TIZEN)
-    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DNO_TIZEN")
-ELSE(DEFINED NO_TIZEN)
-    INCLUDE(FindPkgConfig)
-    PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer dlog ecore bundle dlog launchpad elementary glib-2.0)
-ENDIF(DEFINED NO_TIZEN)
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(${PROJECT_NAME} REQUIRED aul pkgmgr-info pkgmgr-installer dlog ecore bundle dlog launchpad elementary glib-2.0 libsmack)
 
 FOREACH(flag ${${PROJECT_NAME}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -68,35 +64,45 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
 
 INCLUDE_DIRECTORIES(inc launcher util)
 
+SET(DOTNET_LAUNCHER_UTIL "dotnet_launcher_util")
+SET(${DOTNET_LAUNCHER_UTIL}_SOURCE_FILES
+    util/utils.cc
+    util/plugin_manager.cc
+    util/path_manager.cc
+)
+ADD_LIBRARY(${DOTNET_LAUNCHER_UTIL} SHARED ${${DOTNET_LAUNCHER_UTIL}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER_UTIL} PROPERTIES COMPILE_FLAGS "-fPIC")
+TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER_UTIL} ${${PROJECT_NAME}_LDFLAGS})
+
 SET(DOTNET_LAUNCHER "dotnet-launcher")
 SET(${DOTNET_LAUNCHER}_SOURCE_FILES
     launcher/main.cc
-    util/utils.cc
     launcher/launcher.cc
     launcher/dotnet/dotnet_launcher.cc
 )
 ADD_EXECUTABLE(${DOTNET_LAUNCHER} ${${DOTNET_LAUNCHER}_SOURCE_FILES})
 SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER} PROPERTIES COMPILE_FLAGS "-fPIE")
-
-
-IF(NOT DEFINED NO_TIZEN)
-    TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER} aul)
-ENDIF(NOT DEFINED NO_TIZEN)
-TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread")
+TARGET_LINK_LIBRARIES(${DOTNET_LAUNCHER} ${${PROJECT_NAME}_LDFLAGS} "-pie -ldl -lpthread" aul ${DOTNET_LAUNCHER_UTIL})
 
 SET_TARGET_PROPERTIES(${DOTNET_LAUNCHER}
     PROPERTIES SKIP_BUILD_RPATH TRUE
 ) # remove rpath option that is automatically generated by cmake.
 
+SET(NI_COMMON "ni_common")
+SET(${NI_COMMON}_SOURCE_FILES
+    installer-plugin/ni_common.cc
+)
+ADD_LIBRARY(${NI_COMMON} SHARED ${${NI_COMMON}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${NI_COMMON} PROPERTIES COMPILE_FLAGS "-fPIC")
+TARGET_LINK_LIBRARIES(${NI_COMMON} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL})
+
 SET(NITOOL "nitool")
 SET(${NITOOL}_SOURCE_FILES
-    util/utils.cc
-    installer-plugin/common.cc
     installer-plugin/nitool.cc
 )
 ADD_EXECUTABLE(${NITOOL} ${${NITOOL}_SOURCE_FILES})
 SET_TARGET_PROPERTIES(${NITOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
-TARGET_LINK_LIBRARIES(${NITOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie")
+TARGET_LINK_LIBRARIES(${NITOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
 
 #SET(INSTALLER_PLUGIN "ui-application")
 #SET(${INSTALLER_PLUGIN}_SOURCE_FILES
@@ -111,21 +117,25 @@ TARGET_LINK_LIBRARIES(${NITOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie")
 
 SET(PREFER_DOTNET_AOT_PLUGIN "prefer_dotnet_aot_plugin")
 SET(${PREFER_DOTNET_AOT_PLUGIN}_SOURCE_FILES
-    util/utils.cc
-    installer-plugin/common.cc
     installer-plugin/prefer_dotnet_aot_plugin.cc
 )
 ADD_LIBRARY(${PREFER_DOTNET_AOT_PLUGIN} SHARED ${${PREFER_DOTNET_AOT_PLUGIN}_SOURCE_FILES})
 SET_TARGET_PROPERTIES(${PREFER_DOTNET_AOT_PLUGIN} PROPERTIES COMPILE_FLAGS "-fPIC")
-TARGET_LINK_LIBRARIES(${PREFER_DOTNET_AOT_PLUGIN} ${${PROJECT_NAME}_LDFLAGS})
-
-
-IF(NOT DEFINED NO_TIZEN)
-    INSTALL(TARGETS ${DOTNET_LAUNCHER} DESTINATION ${BINDIR})
-    INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
-#    INSTALL(TARGETS ${INSTALLER_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
-    INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
-    INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR})
-    INSTALL(FILES dotnet.launcher DESTINATION ${LOADERDIR})
-    INSTALL(FILES dotnet.debugger DESTINATION ${LOADERDIR})
-ENDIF(NOT DEFINED NO_TIZEN)
+TARGET_LINK_LIBRARIES(${PREFER_DOTNET_AOT_PLUGIN} ${${PROJECT_NAME}_LDFLAGS} ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
+
+CONFIGURE_FILE(dotnet-launcher.pc.in dotnet-launcher.pc @ONLY)
+
+INSTALL(TARGETS ${DOTNET_LAUNCHER_UTIL} DESTINATION ${LIBDIR})
+INSTALL(TARGETS ${DOTNET_LAUNCHER} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR})
+INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
+#INSTALL(TARGETS ${INSTALLER_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
+INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
+INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR})
+INSTALL(FILES dotnet.launcher DESTINATION ${LOADERDIR})
+INSTALL(FILES dotnet.debugger DESTINATION ${LOADERDIR})
+INSTALL(FILES inc/coreclr_host.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES inc/dotnet_launcher_plugin.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES installer-plugin/ni_common.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ../dotnet-launcher.pc DESTINATION ${LIBDIR}/pkgconfig)
+
diff --git a/NativeLauncher/dotnet-launcher.pc.in b/NativeLauncher/dotnet-launcher.pc.in
new file mode 100644 (file)
index 0000000..cf3257d
--- /dev/null
@@ -0,0 +1,9 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: dotnet-launcher
+Description: Launchpad plugin for launching dotnet app and tools to generate ni files
+Version: @Version@
+Libs: -L${libdir} -ldotnet_launcher_util -lni_common
+Cflags: -I${includedir}
diff --git a/NativeLauncher/inc/coreclr_host.h b/NativeLauncher/inc/coreclr_host.h
new file mode 100644 (file)
index 0000000..7dbd137
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CORECLR_HOST_H__
+#define __CORECLR_HOST_H__
+
+extern "C"
+{
+       typedef int (*coreclr_initialize_ptr)(
+                       const char* exePath,
+                       const char* appDomainFriendlyName,
+                       int propertyCount,
+                       const char** propertyKeys,
+                       const char** propertyValues,
+                       void** hostHandle,
+                       unsigned int* domainId);
+
+       typedef int (*coreclr_execute_assembly_ptr)(
+                       void* hostHandle,
+                       unsigned int domainId,
+                       int argc,
+                       const char** argv,
+                       const char* managedAssemblyPath,
+                       unsigned int* exitCode);
+
+       typedef int (*coreclr_shutdown_ptr)(
+                       void* hostHandle,
+                       unsigned int domainId);
+
+       typedef int (*coreclr_create_delegate_ptr)(
+                       void* hostHandle,
+                       unsigned int domainId,
+                       const char* entryPointAssemblyName,
+                       const char* entryPointTypeName,
+                       const char* entryPointMethodName,
+                       void** delegate);
+}
+
+#endif /* __CORECLR_HOST_H__ */
diff --git a/NativeLauncher/inc/dotnet_launcher_plugin.h b/NativeLauncher/inc/dotnet_launcher_plugin.h
new file mode 100644 (file)
index 0000000..4e75917
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __DOTNET_LAUNCHER_PLUGIN_H__
+#define __DOTNET_LAUNCHER_PLUGIN_H__
+
+#include "coreclr_host.h"
+
+extern "C"
+{
+       typedef void (*plugin_initialize_ptr)(const char* mode);
+       typedef void (*plugin_preload_ptr)();
+       typedef void (*plugin_set_app_info_ptr)(
+                       const char* appId,
+                       const char* managedAssemblyPath);
+       typedef void (*plugin_set_coreclr_info_ptr)(
+                       void* hostHandle,
+                       unsigned int domainId,
+                       coreclr_create_delegate_ptr delegateFunc);
+       typedef char* (*plugin_get_dll_path_ptr)();
+       typedef void (*plugin_before_execute_ptr)();
+       typedef void (*plugin_finalize_ptr)();
+}
+
+#endif /* __DOTNET_LAUNCHER_PLUGIN_H__ */
diff --git a/NativeLauncher/inc/plugin_manager.h b/NativeLauncher/inc/plugin_manager.h
new file mode 100644 (file)
index 0000000..94e1798
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PLUGIN_MANAGER_H__
+#define __PLUGIN_MANAGER_H__
+
+#include "dotnet_launcher_plugin.h"
+#include "coreclr_host.h"
+
+extern "C"
+{
+
+
+typedef struct PluginFunc {
+       plugin_initialize_ptr initialize;
+       plugin_preload_ptr preload;
+       plugin_set_app_info_ptr set_app_info;
+       plugin_set_coreclr_info_ptr set_coreclr_info;
+       plugin_get_dll_path_ptr get_dll_path;
+       plugin_before_execute_ptr before_execute;
+       plugin_finalize_ptr finalize;
+} PluginFunc;
+
+// plugin functions
+void pluginPreload();
+void pluginSetAppInfo(const char* appId, const char* managedAssemblyPath);
+void pluginSetCoreclrInfo(void* hostHandle, unsigned int domainId, coreclr_create_delegate_ptr delegateFunc);
+char* pluginGetDllPath();
+void pluginBeforeExecute();
+
+// initialize / finalize plugin manager
+int initializePluginManager(const char* mode);
+void finalizePluginManager();
+
+}
+
+#endif /* __PLUGIN_MANAGER_H__ */
index 18fdaa083b225f2b994faf3467eb4698702eea54..534be8b83b48fa2999abdccce8d373010b0fe199 100644 (file)
 #define PATH_SEPARATOR '/'
 #endif
 
-bool iCompare(const std::string& a, const std::string& b);
-bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length);
-bool isManagedAssembly(const std::string& fileName);
-bool isNativeImage(const std::string& fileName);
 std::string readSelfPath();
+
 std::string concatPath(const std::string& path1, const std::string& path2);
-void splitPath(const std::string& path, std::vector<std::string>& out);
-void appendPath(std::string& path1, const std::string& path2);
 std::string absolutePath(const std::string& path);
 std::string baseName(const std::string& path);
-bool endWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& fileName);
-void assembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList);
+void splitPath(const std::string& path, std::vector<std::string>& out);
+void appendPath(std::string& path1, const std::string& path2);
+
+bool isFileExist(const std::string& path);
+
+bool isManagedAssembly(const std::string& fileName);
+bool isNativeImage(const std::string& fileName);
 
-bool fileNotExist(const std::string& path);
-std::string joinStrings(const std::vector<std::string>& strings, const char* const delimeter);
+void assembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList);
 
-typedef std::function<void (const char*, const char*)> FileReader;
-void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth);
+typedef std::function<void (const std::string&, const char*)> FileReader;
+void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth);
 
 int runLoggingThread();
 #endif /* __UTILS_H__ */
diff --git a/NativeLauncher/installer-plugin/common.cc b/NativeLauncher/installer-plugin/common.cc
deleted file mode 100644 (file)
index 31596f4..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <pkgmgr-info.h>
-#include <pkgmgr_installer_info.h>
-#include <aul.h>
-
-#include "log.h"
-#include "utils.h"
-#include "pkgmgr_parser_plugin_interface.h"
-
-#include <wait.h>
-#include <dirent.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <string>
-
-#include <pwd.h>
-#include <grp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <fstream>
-
-#include "common.h"
-
-#ifdef  LOG_TAG
-#undef  LOG_TAG
-#endif
-#define LOG_TAG "NETCORE_INSTALLER_PLUGIN"
-
-#ifndef DEVICE_API_DIR
-#error "DEVICE_API_DIR is missed"
-#endif
-
-#ifndef RUNTIME_DIR
-#error "RUNTIME_DIR is missed"
-#endif
-
-#ifndef CROSSGEN_PATH
-#error "CROSSGEN_PATH is missed"
-#endif
-
-#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* __CROSSGEN_PATH = __STR(CROSSGEN_PATH);
-static const char* __JIT_PATH = __STR(RUNTIME_DIR)"/libclrjit.so";
-#undef __STR
-#undef __XSTR
-
-#if 0
-static std::string replace(std::string &str, const std::string& from, const std::string& to)
-{
-       size_t startPos = 0;
-       while ((startPos = str.find(from, startPos)) != std::string::npos) {
-               str.replace(startPos, from.length(), to);
-               startPos += to.length();
-       }
-       return str;
-}
-#endif
-
-static void smack_(const char* dllPath, const char* label)
-{
-       static const char* chsmack = "/usr/bin/chsmack";
-       pid_t pid = fork();
-       if (pid == -1)
-               return;
-
-       if (pid > 0) {
-               int status;
-               waitpid(pid, &status, 0);
-               if (WIFEXITED(status))
-                       return;
-       } else {
-               const char* args[] = {
-                       chsmack,
-                       "-a", label,
-                       dllPath,
-                       nullptr
-               };
-               execv(chsmack, const_cast<char*const*>(args));
-
-               exit(0);
-       }
-}
-
-static void crossgen(const char* dllPath, const char* appPath, bool enableR2R)
-{
-       //pid_t parent = getpid();
-       pid_t pid = fork();
-       if (pid == -1)
-               return;
-
-       if (pid > 0) {
-               int status;
-               waitpid(pid, &status, 0);
-               if (WIFEXITED(status))
-                       return;
-       } else {
-               // search dlls in the application directory first, to use application dlls
-               // instead of system dlls when proceeding NI
-               std::vector<std::string> tpaDir;
-               if (appPath != NULL) {
-                       std::string path(appPath);
-                       std::string::size_type prevPos = 0, pos = 0;
-                       while ((pos = path.find(':', pos)) != std::string::npos) {
-                               std::string substring(path.substr(prevPos, pos - prevPos));
-                               tpaDir.push_back(substring);
-                               prevPos = ++pos;
-                       }
-                       std::string substring(path.substr(prevPos, pos - prevPos));
-                       tpaDir.push_back(substring);
-               }
-               tpaDir.push_back(__RUNTIME_DIR);
-               tpaDir.push_back(__DEVICE_API_DIR);
-
-               // get reference API directory ([DEVICE_API_DIR]/ref)
-               int len = strlen(__DEVICE_API_DIR);
-               char* refAPIDir = (char*)calloc(len + 5, 1);
-               if (!refAPIDir) {
-                       printf("fail to allocate memory for reference API directory\n");
-                       return;
-               }
-               snprintf(refAPIDir, len + 5, "%s%s", __DEVICE_API_DIR, "/ref");
-               tpaDir.push_back(refAPIDir);
-
-               std::string tpa;
-               assembliesInDirectory(tpaDir, tpa);
-
-               std::vector<const char*> argv = {
-                       __CROSSGEN_PATH,
-                       "/Trusted_Platform_Assemblies", tpa.c_str(),
-                       "/JITPath", __JIT_PATH
-               };
-
-               if (!enableR2R) {
-                       fprintf(stderr, "FNV mode enabled!!!\n");
-                       argv.push_back("/FragileNonVersionable");
-               } else {
-                       fprintf(stderr, "R2R mode enabled!!!\n");
-               }
-
-               if (appPath != nullptr) {
-                       argv.push_back("/App_Paths");
-                       argv.push_back(appPath);
-               }
-               argv.push_back(dllPath);
-               argv.push_back(nullptr);
-
-               printf("+ %s\n", dllPath);
-
-               execv(__CROSSGEN_PATH, const_cast<char* const*>(argv.data()));
-               exit(0);
-       }
-}
-
-static int getRootPath(const char *pkgId, std::string& rootPath)
-{
-       int ret = 0;
-       char *path = 0;
-
-       uid_t uid = 0;
-
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return -1;
-       }
-
-       _INFO("user id is %d", uid);
-
-       pkgmgrinfo_pkginfo_h handle;
-       if (uid == 0) {
-               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId, &handle);
-               if (ret != PMINFO_R_OK)
-                       return -1;
-       } else {
-               ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId, uid, &handle);
-               if (ret != PMINFO_R_OK)
-                       return -1;
-       }
-
-       ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
-       if (ret != PMINFO_R_OK) {
-               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-               return -1;
-       }
-       rootPath = path;
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-
-       return 0;
-}
-
-static bool niExist(const std::string& path, std::string& ni)
-{
-       // native image of System.Private.CoreLib.dll should have to overwrite
-       // original file to support new coreclr
-       if (path.find("System.Private.CoreLib.dll") != std::string::npos) {
-               std::string coreLibBackup = path + ".Backup";
-               if (!fileNotExist(coreLibBackup)) {
-                       ni = path;
-                       return true;
-               }
-               return false;
-       }
-
-       static const char* possibleExts[] = {
-               ".ni.dll", ".NI.dll", ".NI.DLL", ".ni.DLL",
-               ".ni.exe", ".NI.exe", ".NI.EXE", ".ni.EXE"
-       };
-       std::string fName = path.substr(0, path.size() - 4);
-
-       struct stat sb;
-
-       for (const char* ext : possibleExts) {
-               std::string f = fName + ext;
-               if (stat(f.c_str(), &sb) == 0) {
-                       ni = f;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
-{
-       char *pkgId = NULL;
-       int ret = 0;
-
-       ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
-       if (ret != PMINFO_R_OK) {
-               _DBG("Failed to get pkgid");
-               return -1;
-       }
-
-       // When you create native image with pkgid, ni file is generated even though already ni file exist.
-       // Regenerate ni files with R2R mode forcibiliy. (there is no way to now which option is used)
-       if (createNiUnderPkgRoot(pkgId, true) != 0) {
-               _ERR("Failed to get root path from [%s]", pkgId);
-               return -1;
-       } else {
-               _DBG("Complete make application to native image");
-       }
-
-       return 0;
-}
-
-int regenerateAppNI()
-{
-       int ret = 0;
-       pkgmgrinfo_appinfo_metadata_filter_h handle;
-
-       ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
-       if (ret != PMINFO_R_OK)
-               return -1;
-
-       ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, "http://tizen.org/metadata/prefer_dotnet_aot", "true");
-       if (ret != PMINFO_R_OK) {
-               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
-       }
-
-       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, NULL);
-       if (ret != PMINFO_R_OK) {
-               _DBG("Failed pkgmgrinfo_appinfo_metadata_filter_foreach");
-               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-               return -1;
-       }
-
-       _DBG("Success pkgmgrinfo_appinfo_metadata_filter_foreach");
-
-       pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-       return 0;
-}
-
-static void createCoreLibNI(bool enableR2R)
-{
-       std::string coreLib = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll");
-       std::string niCoreLib = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.ni.dll");
-       std::string coreLibBackup = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll.Backup");
-
-       if (!niExist(coreLib, niCoreLib)) {
-               crossgen(coreLib.c_str(), nullptr, enableR2R);
-               if (!fileNotExist(niCoreLib)) {
-                       // change owner and groups for generated ni file.
-                       struct stat info;
-                       if (!stat(coreLib.c_str(), &info)) {
-                               if (chown(niCoreLib.c_str(), info.st_uid, info.st_gid) == -1)
-                                       _ERR("Failed to change owner and group name");
-                       }
-                       smack_(niCoreLib.c_str(), "_");
-                       rename(coreLib.c_str(), coreLibBackup.c_str());
-                       rename(niCoreLib.c_str(), coreLib.c_str());
-               }
-       }
-}
-
-void removeNiUnderDirs(const char* rootPaths[], int count)
-{
-       auto convert = [](const char* path, const char* name) {
-               std::string ni;
-               if (isNativeImage(path)) {
-                       remove(path);
-               }
-       };
-
-       for (int i = 0; i < count; i++)
-               scanFilesInDir(rootPaths[i], convert, -1);
-}
-
-void removeNiPlatform()
-{
-       std::string coreLib = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll");
-       std::string coreLibBackup = concatPath(__RUNTIME_DIR, "System.Private.CoreLib.dll.Backup");
-
-       if (fileNotExist(coreLibBackup)) {
-               return;
-       }
-
-       if (remove(coreLib.c_str())) {
-               _ERR("Failed to remove System.Private.CoreLib native image file");
-       }
-
-       rename(coreLibBackup.c_str(), coreLib.c_str());
-
-       const char* platformDirs[] = {__RUNTIME_DIR, __DEVICE_API_DIR, "/usr/bin"};
-
-       removeNiUnderDirs(platformDirs, 3);
-}
-
-void createNiPlatform(bool enableR2R)
-{
-       createCoreLibNI(enableR2R);
-
-       const char* platformDirs[] = {__RUNTIME_DIR, __DEVICE_API_DIR, "/usr/bin"};
-
-       createNiUnderDirs(platformDirs, 3, [](const char* ni) {
-               smack_(ni, "_");
-       }, enableR2R);
-}
-
-void createNiSelect(const char* dllPath, bool enableR2R)
-{
-       createCoreLibNI(enableR2R);
-
-       std::string niPath;
-       if (!fileNotExist(dllPath)) {
-               if (!niExist(dllPath, niPath)) {
-                       crossgen(dllPath, nullptr, enableR2R);
-                       if (niExist(dllPath, niPath)) {
-                               // change owner and groups for generated ni file.
-                               struct stat info;
-                               if (!stat(dllPath, &info)) {
-                                       if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1)
-                                               _ERR("Failed to change owner and group name");
-                               }
-                               smack_(niPath.c_str(), "_");
-                       }
-               } else {
-                       printf("Already [%s] file is exist\n", niPath.c_str());
-               }
-       } else {
-               printf("Failed to find dll : %s", dllPath);
-       }
-}
-
-void createNiUnderDirs(const char* rootPaths[], int count, const char* ignores[], int igcount, afterCreate cb, bool update, bool enableR2R)
-{
-       std::string appPaths;
-       for (int i = 0; i < count; i++) {
-               appPaths += rootPaths[i];
-               appPaths += ':';
-       }
-
-       if (appPaths.back() == ':')
-               appPaths.pop_back();
-
-       auto convert = [&appPaths, ignores, igcount, &cb, update, enableR2R](const char* path, const char* name) {
-               for (int i = 0; i < igcount; i++) {
-                       if (strcmp(path, ignores[i]) == 0)
-                               return;
-               }
-               std::string niPath;
-               if (isManagedAssembly(path) && !isNativeImage(path)) {
-                       if (niExist(path, niPath)) {
-                               if (update && !niPath.empty()) {
-                                       _INFO("override [%s] file", niPath.c_str());
-                               } else {
-                                       _INFO("Already [%s] file is exist", niPath.c_str());
-                                       return;
-                               }
-                       }
-                       crossgen(path, appPaths.c_str(), enableR2R);
-                       if (niExist(path, niPath)) {
-                               // change owner and groups for generated ni file.
-                               struct stat info;
-                               if (!stat(path, &info)) {
-                                       if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1)
-                                               _ERR("Failed to change owner and group name");
-                               }
-
-                               if (cb != nullptr)
-                                       cb(niPath.c_str());
-                       } else {
-                               _INFO("Failed to create native image for %s", path);
-                       }
-               }
-       };
-
-       for (int i = 0; i < count; i++)
-               scanFilesInDir(rootPaths[i], convert, 1);
-}
-void createNiUnderDirs(const char* rootPaths[], int count, afterCreate cb, bool update, bool enableR2R)
-{
-       createNiUnderDirs(rootPaths, count, nullptr, 0, cb, update, enableR2R);
-}
-void createNiUnderDirs(const char* rootPaths[], int count, bool update, bool enableR2R)
-{
-       createNiUnderDirs(rootPaths, count, nullptr, update, enableR2R);
-}
-
-int removeNiUnderPkgRoot(const char* pkgName)
-{
-       std::string pkgRoot;
-       if (getRootPath(pkgName, pkgRoot) < 0)
-               return 1;
-
-       std::string binDir = concatPath(pkgRoot, "bin");
-       std::string libDir = concatPath(pkgRoot, "lib");
-       _INFO("bindir : %s", binDir.c_str());
-       _INFO("libdir : %s", libDir.c_str());
-
-       const char* paths[] = {
-               binDir.c_str(),
-               libDir.c_str()
-       };
-
-       removeNiUnderDirs(paths, 2);
-
-       return 0;
-}
-
-
-int createNiUnderPkgRoot(const char* pkgName, bool enableR2R)
-{
-       std::string pkgRoot;
-       if (getRootPath(pkgName, pkgRoot) < 0)
-               return 1;
-
-       // get interval value
-       const char* intervalFile = "/usr/share/dotnet.tizen/lib/crossgen_interval.txt";
-       int interval = 0;
-       std::ifstream inFile(intervalFile);
-       if (inFile) {
-               _INFO("crossgen_interval.txt is found");
-               inFile >> interval;
-       } else {
-               _INFO("fail to read crossgen_interval.txt file");
-       }
-
-       std::string binDir = concatPath(pkgRoot, "bin");
-       std::string libDir = concatPath(pkgRoot, "lib");
-       _INFO("bindir : %s", binDir.c_str());
-       _INFO("libdir : %s", libDir.c_str());
-
-       const char* paths[] = {
-               binDir.c_str(),
-               libDir.c_str()
-       };
-
-       // change smack label for generated ni file.
-       std::string label = "User::Pkg::" + std::string(pkgName) + "::RO";
-       createNiUnderDirs(paths, 2, [label, interval](const char* ni) {
-                       smack_(ni, label.c_str());
-                       if (interval != 0) {
-                               _INFO("sleep %d usec", interval);
-                               usleep(interval);
-                       }
-       }, true, enableR2R);
-
-       return 0;
-}
diff --git a/NativeLauncher/installer-plugin/common.h b/NativeLauncher/installer-plugin/common.h
deleted file mode 100644 (file)
index 325bb82..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Licensed under the Apache License, Version 2.0 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __INSTALLER_PLUGIN_COMMON_H__
-#define __INSTALLER_PLUGIN_COMMON_H__
-
-#include <functional>
-
-typedef std::function<void (const char*)> afterCreate;
-int regenerateAppNI();
-void createNiUnderDirs(const char* rootPaths[], int count, const char* ignores[], int igcount, afterCreate cb, bool update, bool enableR2R);
-void createNiUnderDirs(const char* rootPaths[], int count, afterCreate cb, bool update, bool enableR2R);
-void createNiUnderDirs(const char* rootPaths[], int count, bool update, bool enableR2R);
-int createNiUnderPkgRoot(const char* pkgName, bool enableR2R);
-void createNiPlatform(bool enableR2R);
-void createNiSelect(const char* dllPath, bool enableR2R);
-void removeNiPlatform();
-int removeNiUnderPkgRoot(const char* pkgName);
-
-#endif /* __INSTALLER_PLUGIN_COMMON_H__ */
diff --git a/NativeLauncher/installer-plugin/ni_common.cc b/NativeLauncher/installer-plugin/ni_common.cc
new file mode 100644 (file)
index 0000000..7bdaa2f
--- /dev/null
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
+#include <aul.h>
+
+#include "log.h"
+#include "utils.h"
+#include "pkgmgr_parser_plugin_interface.h"
+
+#include <wait.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include <algorithm>
+#include <string>
+
+#include <pwd.h>
+#include <grp.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <fstream>
+#include <sys/smack.h>
+
+#include "ni_common.h"
+#include "path_manager.h"
+#include "plugin_manager.h"
+
+#ifdef  LOG_TAG
+#undef  LOG_TAG
+#endif
+#define LOG_TAG "NETCORE_INSTALLER_PLUGIN"
+
+#ifndef CROSSGEN_PATH
+#error "CROSSGEN_PATH is missed"
+#endif
+
+#define __XSTR(x) #x
+#define __STR(x) __XSTR(x)
+static const char* __CROSSGEN_PATH = __STR(CROSSGEN_PATH);
+#undef __STR
+#undef __XSTR
+
+static int __interval = 0;
+
+static void waitInterval()
+{
+       if (__interval > 0) {
+               fprintf(stderr, "sleep %d usec\n", __interval);
+               usleep(__interval);
+       }
+}
+
+static bool niExist(const std::string& path, std::string& ni)
+{
+       static std::string possibleExts[] = {
+               ".ni.dll", ".NI.dll", ".NI.DLL", ".ni.DLL",
+               ".ni.exe", ".NI.exe", ".NI.EXE", ".ni.EXE"
+       };
+       std::string fName = path.substr(0, path.size() - 4);
+
+       struct stat sb;
+
+       for (std::string ext : possibleExts) {
+               std::string f = fName + ext;
+               if (stat(f.c_str(), &sb) == 0) {
+                       ni = f;
+                       return true;
+               }
+       }
+
+       // native image of System.Private.CoreLib.dll should have to overwrite
+       // original file to support new coreclr
+       if (path.find("System.Private.CoreLib.dll") != std::string::npos) {
+               std::string coreLibBackup = path + ".Backup";
+               if (isFileExist(coreLibBackup)) {
+                       ni = path;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static void updateNiFileInfo(const std::string& path)
+{
+       char* label = NULL;
+       std::string niPath;
+
+       if (niExist(path, niPath)) {
+               // change smack label
+               if (smack_getlabel(path.c_str(), &label, SMACK_LABEL_ACCESS) == 0) {
+                       if (smack_setlabel(niPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) {
+                               fprintf(stderr, "Fail to set smack label\n");
+                       }
+                       free(label);
+               }
+
+               // change owner and groups for generated ni file.
+               struct stat info;
+               if (!stat(path.c_str(), &info)) {
+                       if (chown(niPath.c_str(), info.st_uid, info.st_gid) == -1)
+                               fprintf(stderr, "Failed to change owner and group name\n");
+               }
+       }
+}
+
+static void crossgen(const std::string& dllPath, const std::string& appPath, bool enableR2R)
+{
+       std::string absDllPath = absolutePath(dllPath);
+
+       pid_t pid = fork();
+       if (pid == -1)
+               return;
+
+       if (pid > 0) {
+               int status;
+               waitpid(pid, &status, 0);
+               if (WIFEXITED(status)) {
+                       updateNiFileInfo(absDllPath);
+                       return;
+               }
+       } else {
+               std::string tpa = getTPA();
+               std::string jitPath = getRuntimeDir() + "/libclrjit.so";
+               std::vector<const char*> argv = {
+                       __CROSSGEN_PATH,
+                       "/nologo",
+                       "/Trusted_Platform_Assemblies", tpa.c_str(),
+                       "/JITPath", jitPath.c_str()
+               };
+
+               if (!enableR2R) {
+                       argv.push_back("/FragileNonVersionable");
+               }
+
+               argv.push_back("/App_Paths");
+               std::string absAppPath;
+               if (!appPath.empty()) {
+                       absAppPath = appPath;
+               } else {
+                       absAppPath = baseName(absDllPath);
+               }
+               argv.push_back(absAppPath.c_str());
+
+               argv.push_back(absDllPath.c_str());
+               argv.push_back(nullptr);
+
+               fprintf(stderr, "+ %s (%s)\n", absDllPath.c_str(), enableR2R ? "R2R" : "FNV");
+
+               execv(__CROSSGEN_PATH, const_cast<char* const*>(argv.data()));
+               exit(0);
+       }
+}
+
+static int getRootPath(std::string pkgId, std::string& rootPath)
+{
+       int ret = 0;
+       char *path = 0;
+
+       uid_t uid = 0;
+
+       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
+               _ERR("Failed to get UID");
+               return -1;
+       }
+
+       pkgmgrinfo_pkginfo_h handle;
+       if (uid == 0) {
+               ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle);
+               if (ret != PMINFO_R_OK)
+                       return -1;
+       } else {
+               ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
+               if (ret != PMINFO_R_OK)
+                       return -1;
+       }
+
+       ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path);
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return -1;
+       }
+       rootPath = path;
+       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+
+       return 0;
+}
+
+
+static int appAotCb(pkgmgrinfo_appinfo_h handle, void *userData)
+{
+       char *pkgId = NULL;
+       int ret = 0;
+
+       ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
+       if (ret != PMINFO_R_OK) {
+               fprintf(stderr, "Failed to get pkgid\n");
+               return -1;
+       }
+
+       if (removeNiUnderPkgRoot(pkgId) != 0) {
+               fprintf(stderr, "Failed to remove previous dlls from [%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, true) != 0) {
+               fprintf(stderr, "Failed to get root path from [%s]\n", pkgId);
+               return -1;
+       } else {
+               fprintf(stderr, "Complete make application to native image\n");
+       }
+
+       return 0;
+}
+
+static void createCoreLibNI(bool enableR2R)
+{
+       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");
+
+       if (!niExist(coreLib, niCoreLib)) {
+               crossgen(coreLib, std::string(), enableR2R);
+               if (isFileExist(niCoreLib)) {
+                       if (rename(coreLib.c_str(), coreLibBackup.c_str())) {
+                               fprintf(stderr, "Failed to rename System.Private.CoreLib.dll\n");
+                       }
+                       if (rename(niCoreLib.c_str(), coreLib.c_str())) {
+                               fprintf(stderr, "Failed to rename System.Private.CoreLib.ni.dll\n");
+                       }
+               } else {
+                       fprintf(stderr, "Failed to create native image for %s\n", coreLib.c_str());
+               }
+       }
+}
+
+int initNICommon(NiCommonOption* option)
+{
+       // get interval value
+       const char* intervalFile = "/usr/share/dotnet.tizen/lib/crossgen_interval.txt";
+       std::ifstream inFile(intervalFile);
+       if (inFile) {
+               fprintf(stderr, "crossgen_interval.txt is found\n");
+               inFile >> __interval;
+       }
+
+       if (initializePluginManager("normal")) {
+               fprintf(stderr, "Fail to initialize plugin manager\n");
+               return -1;
+       }
+       if (initializePathManager(option->runtimeDir, option->tizenFXDir, option->extraDirs)) {
+               fprintf(stderr, "Fail to initialize path manager\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+void finalizeNICommon()
+{
+       __interval = 0;
+
+       finalizePluginManager();
+       finalizePathManager();
+}
+
+
+void createNiPlatform(bool enableR2R)
+{
+       const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
+
+       createNiUnderDirs(platformDirs, 2, enableR2R);
+}
+
+void createNiDll(const std::string& dllPath, bool enableR2R)
+{
+       createCoreLibNI(enableR2R);
+
+       if (!isFileExist(dllPath)) {
+               fprintf(stderr, "Failed to find dll : %s\n", dllPath.c_str());
+               return;
+       }
+
+       std::string niPath;
+       if (niExist(dllPath, niPath)) {
+               fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str());
+               return;
+       }
+
+       crossgen(dllPath, std::string(), enableR2R);
+       if (!niExist(dllPath, niPath)) {
+               fprintf(stderr, "Failed to create native image for %s\n", dllPath.c_str());
+       }
+}
+
+void createNiUnderDirs(const std::string rootPaths[], int count, const std::string ignores[], int igcount, afterCreate cb, bool enableR2R)
+{
+       createCoreLibNI(enableR2R);
+
+       std::string appPaths;
+       for (int i = 0; i < count; i++) {
+               appPaths += rootPaths[i];
+               appPaths += ':';
+       }
+
+       if (appPaths.back() == ':')
+               appPaths.pop_back();
+
+       auto convert = [&appPaths, ignores, igcount, &cb, enableR2R](const std::string& path, const char* name) {
+               for (int i = 0; i < igcount; i++) {
+                       if (path == ignores[i])
+                               return;
+               }
+               std::string niPath;
+               if (isManagedAssembly(path)) {
+                       if (niExist(path, niPath)) {
+                               fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str());
+                               return;
+                       }
+                       fprintf(stderr, "path [%s], appPath[%s]\n", path.c_str(), appPaths.c_str());
+                       crossgen(path, appPaths.c_str(), enableR2R);
+                       if (niExist(path, niPath)) {
+                               if (cb != nullptr)
+                                       cb(niPath.c_str());
+                       } else {
+                               fprintf(stderr, "Failed to create native image for %s\n", path.c_str());
+                       }
+                       waitInterval();
+               }
+       };
+
+       for (int i = 0; i < count; i++)
+               scanFilesInDir(rootPaths[i], convert, 1);
+}
+void createNiUnderDirs(const std::string rootPaths[], int count, afterCreate cb, bool enableR2R)
+{
+       createNiUnderDirs(rootPaths, count, nullptr, 0, cb, enableR2R);
+}
+void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R)
+{
+       createNiUnderDirs(rootPaths, count, nullptr, enableR2R);
+}
+
+int createNiUnderPkgRoot(const std::string& pkgName, bool enableR2R)
+{
+       std::string pkgRoot;
+       if (getRootPath(pkgName, pkgRoot) < 0)
+               return -1;
+
+       std::string binDir = concatPath(pkgRoot, "bin");
+       std::string libDir = concatPath(pkgRoot, "lib");
+       std::string paths[] = {binDir, libDir};
+
+       createNiUnderDirs(paths, 2, enableR2R);
+
+       return 0;
+}
+
+int createNiDllUnderPkgRoot(const std::string& pkgName, const std::string& dllPath, bool enableR2R)
+{
+       std::string pkgRoot;
+       if (getRootPath(pkgName, pkgRoot) < 0)
+               return -1;
+
+       std::string binDir = concatPath(pkgRoot, "bin");
+       std::string libDir = concatPath(pkgRoot, "lib");
+       std::string appPaths = binDir + ":" + libDir;
+
+       if (!isFileExist(dllPath)) {
+               fprintf(stderr, "Failed to find dll : %s\n", dllPath.c_str());
+               return -1;
+       }
+
+       std::string niPath;
+       if (niExist(dllPath, niPath)) {
+               fprintf(stderr, "Already [%s] file is exist\n", niPath.c_str());
+               return -1;
+       }
+
+       crossgen(dllPath, appPaths, enableR2R);
+       if (!niExist(dllPath, niPath)) {
+               fprintf(stderr, "Failed to create native image for %s\n", dllPath.c_str());
+               return -1;
+       }
+
+       return 0;
+}
+
+void removeNiPlatform()
+{
+       std::string coreLib = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll");
+       std::string coreLibBackup = concatPath(getRuntimeDir(), "System.Private.CoreLib.dll.Backup");
+
+       if (!isFileExist(coreLibBackup)) {
+               return;
+       }
+
+       if (remove(coreLib.c_str())) {
+               fprintf(stderr, "Failed to remove System.Private.CoreLib native image file\n");
+       }
+
+       if (rename(coreLibBackup.c_str(), coreLib.c_str())) {
+               fprintf(stderr, "Failed to rename System.Private.CoreLib.Backup to origin\n");
+       }
+
+       const std::string platformDirs[] = {getRuntimeDir(), getTizenFXDir()};
+
+       removeNiUnderDirs(platformDirs, 2);
+}
+
+void removeNiUnderDirs(const std::string rootPaths[], int count)
+{
+       auto convert = [](const std::string& path, std::string name) {
+               std::string ni;
+               if (isNativeImage(path)) {
+                       if (remove(path.c_str())) {
+                               fprintf(stderr, "Failed to remove %s\n", path.c_str());
+                       }
+               }
+       };
+
+       for (int i = 0; i < count; i++)
+               scanFilesInDir(rootPaths[i], convert, -1);
+}
+
+int removeNiUnderPkgRoot(const std::string& pkgName)
+{
+       std::string pkgRoot;
+       if (getRootPath(pkgName, pkgRoot) < 0)
+               return -1;
+
+       std::string binDir = concatPath(pkgRoot, "bin");
+       std::string libDir = concatPath(pkgRoot, "lib");
+       std::string paths[] = {binDir, libDir};
+
+       removeNiUnderDirs(paths, 2);
+
+       return 0;
+}
+
+int regenerateAppNI()
+{
+       int ret = 0;
+       pkgmgrinfo_appinfo_metadata_filter_h handle;
+
+       ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
+       if (ret != PMINFO_R_OK)
+               return -1;
+
+       ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, "http://tizen.org/metadata/prefer_dotnet_aot", "true");
+       if (ret != PMINFO_R_OK) {
+               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+               return -1;
+       }
+
+       ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, appAotCb, NULL);
+       if (ret != PMINFO_R_OK) {
+               fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
+               pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+               return -1;
+       }
+
+       fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
+
+       pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
+       return 0;
+}
+
diff --git a/NativeLauncher/installer-plugin/ni_common.h b/NativeLauncher/installer-plugin/ni_common.h
new file mode 100644 (file)
index 0000000..d142f7d
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NI_COMMON_H__
+#define __NI_COMMON_H__
+
+#include <functional>
+
+typedef std::function<void (std::string)> afterCreate;
+
+/**
+ * @brief : structure which contains 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[in] options to initialize path
+ * @return 0 on success, otherwise a negative error value
+ */
+int initNICommon(NiCommonOption* option);
+
+/**
+ * @brief finalize NICommon
+ * @details Before re-initialize NICommon, you have to finalize current NICommon first.
+ */
+void finalizeNICommon();
+
+/**
+ * @brief create native images (NI file) for Platform DLLs (.NETCore + TizenFX)
+ */
+void createNiPlatform(bool enableR2R);
+
+/**
+ * @brief create native image for specific dll with file path.
+ * @param[i] dllPath file path to generate native image
+ * @param[i] enableR2R enable ready-to-run mode
+ */
+void createNiDll(const std::string& dllPath, bool enableR2R);
+
+/**
+ * @brief create native images with files under specific directory.
+ * @param[i] rootPaths directories whicn contains DLLs
+ * @param[i] count number of rootPath
+ * @param[i] ignores DLL list which should be ignored
+ * @param[i] igcount number of ignores
+ * @param[i] cb callback function whicn will be called after generating native image
+ * @param[i] enableR2R enable ready-to-run mode
+ */
+void createNiUnderDirs(const std::string rootPaths[], int count, const std::string ignores[], int igcount, afterCreate cb, bool enableR2R);
+
+/**
+ * @brief create native images with files under specific directory.
+ * @param[i] rootPaths directories whicn contains DLLs
+ * @param[i] count number of rootPath
+ * @param[i] cb callback function whicn will be called after generating native image
+ * @param[i] enableR2R enable ready-to-run mode
+ */
+void createNiUnderDirs(const std::string rootPaths[], int count, afterCreate cb, bool enableR2R);
+
+/**
+ * @brief create native images with files under specific directory.
+ * @param[i] rootPaths directories whicn contains DLLs
+ * @param[i] count number of rootPath
+ * @param[i] enableR2R enable ready-to-run mode
+ */
+void createNiUnderDirs(const std::string rootPaths[], int count, bool enableR2R);
+
+/**
+ * @brief create native images for specific package. (All DLLs)
+ * @param[i] pkgId package ID
+ * @param[i] enableR2R enable ready-to-run mode
+ * @return 0 on success, otherwise a negative error value
+ */
+int createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R);
+
+/**
+ * @brief create native image for specific dll in the package.
+ * @Details All dlls in the package are added for reference when create native image.
+ * @param[i] pkgId package ID
+ * @param[i] enableR2R enable ready-to-run mode
+ * @return 0 on success, otherwise a negative error value
+ */
+int createNiDllUnderPkgRoot(const std::string& pkgId, const std::string& dllPath, bool enableR2R);
+
+/**
+ * @brief remove native images (NI file) for Platform DLLs (.NETCore + TizenFX)
+ */
+void removeNiPlatform();
+
+/**
+ * @brief remove native images under specific directory.
+ * @param[i] rootPaths directories whicn contains native image
+ * @param[i] count number of rootPath
+ */
+void removeNiUnderDirs(const std::string rootPaths[], int count);
+
+/**
+ * @brief remove native images for specific package.
+ * @param[i] pkgId package ID
+ * @return 0 on success, otherwise a negative error value
+ */
+int removeNiUnderPkgRoot(const std::string& pkgId);
+
+/**
+ * @brief regenerate native image for all installed application
+ */
+int regenerateAppNI();
+
+#endif /* __NI_COMMON_H__ */
index bb996afcb0c83c7d1f296e854f01b189974b3396..5d7edcce464207a32d4a8d86f9209396c2896e5e 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "common.h"
+#include "ni_common.h"
 
 #include <cstdio>
 #include <cstring>
@@ -22,9 +22,9 @@
 #include <algorithm>
 #include <vector>
 
-std::vector<const char*> getCmdArgs(char** begin, char** end)
+std::vector<std::string> getCmdArgs(char** begin, char** end)
 {
-       std::vector<const char*> list;
+       std::vector<std::string> list;
        for (char** itr = begin+1; itr != end; itr++) {
                if (strncmp(*itr, "--", 2) != 0)
                        list.push_back(*itr);
@@ -68,6 +68,13 @@ int main(int argc, char* argv[])
        bool dirMode = false;
        bool rmPkgMode = false;
        bool enableR2R = false;
+       bool pkgDllMode = false;
+
+       NiCommonOption option = {std::string(), std::string(), std::string()};
+       if (initNICommon(&option) < 0) {
+               fprintf(stderr, "Fail to initialize NI Common\n");
+               return -1;
+       }
 
        if (cmdOptionExists(argv, argv+argc, "--r2r")) {
                enableR2R = true;
@@ -93,12 +100,14 @@ int main(int argc, char* argv[])
        } else if (cmdOptionExists(argv, argv+argc, "--regen-all-app")) {
                regenerateAppNI();
                return 0;
+       } else if (cmdOptionExists(argv, argv+argc, "--pkg-dll")) {
+               pkgDllMode = true;
        } else {
                help(argv[0]);
-               return 1;
+               return 0;
        }
 
-       std::vector<const char*> args = getCmdArgs(argv, argv+argc);
+       std::vector<std::string> args = getCmdArgs(argv, argv+argc);
 
        if (args.size() < 1) {
                if (pkgMode)
@@ -110,24 +119,29 @@ int main(int argc, char* argv[])
        }
 
        if (pkgMode) {
-               for (const char* pkg : args) {
+               for (const std::string pkg : args) {
                        if (createNiUnderPkgRoot(pkg, enableR2R) != 0) {
-                               fprintf(stderr, "Failed to get root path from [%s]\n", pkg);
-                               return 1;
+                               fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+                               return -1;
                        }
                }
+       } if (pkgDllMode) {
+               if (createNiDllUnderPkgRoot(args[0], args[1], enableR2R) != 0) {
+                       fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
+                       return -1;
+               }
        } else if (rmPkgMode) {
-               for (const char* pkg : args) {
+               for (const std::string pkg : args) {
                        if (removeNiUnderPkgRoot(pkg) != 0) {
-                               fprintf(stderr, "Failed to get root path from [%s]\n", pkg);
-                               return 1;
+                               fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+                               return -1;
                        }
                }
        } else if (dllMode) {
-               for (const char* dll : args)
-                       createNiSelect(dll, enableR2R);
+               for (const std::string dll : args)
+                       createNiDll(dll, enableR2R);
        } else if (dirMode) {
-               createNiUnderDirs(args.data(), args.size(), false, enableR2R);
+               createNiUnderDirs(args.data(), args.size(), enableR2R);
        }
 
        return 0;
index d7fd274499b82853bcbe11be171f65190dade285..24a618ac9010855ae828890680530f6d174f829b 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "common.h"
+#include "ni_common.h"
 #include "log.h"
 #include "utils.h"
 
@@ -51,6 +51,12 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
        }
 
        if (mdValue) {
+               NiCommonOption option = {std::string(), std::string(), std::string()};
+               if (initNICommon(&option) < 0) {
+                       _ERR("Fail to initialize NI Common");
+                       return -1;
+               }
+
                if (createNiUnderPkgRoot(pkgId, false) != 0) {
                        _ERR("Failed to get root path from [%s]", pkgId);
                        return -1;
index e626265868ea79a02c9bec7038e94f82e82daeb5..8f1bca717aef9295b4a54d49459f49310ab059c7 100644 (file)
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "common.h"
+#include "ni_common.h"
 #include "log.h"
 
 #ifdef  LOG_TAG
index f3a1056add774d4eab4cb9d8bbc5c5739b05058f..6ae5ad54aa4d7172c83d65fdd73e413ac5ac5862 100644 (file)
@@ -31,6 +31,8 @@
 #include "log.h"
 #include "launcher.h"
 #include "dotnet_launcher.h"
+#include "plugin_manager.h"
+#include "path_manager.h"
 
 #define PLUGIN_PATH "/usr/share/dotnet.tizen/lib/libdotnet_plugin.so"
 
@@ -88,53 +90,14 @@ CoreRuntime::CoreRuntime(const char* mode) :
        __coreclrLib(nullptr),
        __hostHandle(nullptr),
        __domainId(-1),
-       preparedFunction(nullptr),
-       launchFunction(nullptr),
-       __pluginLib(nullptr),
-       pluginInitialize(nullptr),
-       pluginPreload(nullptr),
-       pluginSetAppInfo(nullptr),
-       pluginSetCoreclrInfo(nullptr),
-       pluginGetDllPath(nullptr),
-       pluginBeforeExecute(nullptr),
-       pluginFinalize(nullptr),
        fd(0),
        __mode(mode)
 {
-#define __XSTR(x) #x
-#define __STR(x) __XSTR(x)
-
-#ifdef DEVICE_API_DIR
-       __deviceAPIDirectory = __STR(DEVICE_API_DIR);
-#endif
-#ifdef RUNTIME_DIR
-       __runtimeDirectory = __STR(RUNTIME_DIR);
-#endif
-#ifdef NATIVE_LIB_DIR
-       __nativeLibDirectory = __STR(NATIVE_LIB_DIR);
-#endif
-
-#undef __STR
-#undef __XSTR
+       _DBG("Constructor called!!");
 
-       // support launcher plugin
-       if (!fileNotExist(PLUGIN_PATH)) {
-               __pluginLib = dlopen(PLUGIN_PATH, RTLD_NOW | RTLD_LOCAL);
-               if (__pluginLib) {
-                       pluginInitialize  = (plugin_initialize_ptr)dlsym(__pluginLib, "plugin_initialize");
-                       pluginPreload  = (plugin_preload_ptr)dlsym(__pluginLib, "plugin_preload");
-                       pluginSetAppInfo  = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info");
-                       pluginSetCoreclrInfo = (plugin_set_coreclr_info_ptr)dlsym(__pluginLib, "plugin_set_coreclr_info");
-                       pluginGetDllPath  = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path");
-                       pluginBeforeExecute  = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute");
-                       pluginFinalize  = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize");
-               }
+       if (runLoggingThread() < 0) {
+               _ERR("Failed to create logging thread");
        }
-
-       if (pluginInitialize)
-               pluginInitialize(mode);
-
-       _DBG("Constructor called!!");
 }
 
 CoreRuntime::~CoreRuntime()
@@ -144,6 +107,16 @@ CoreRuntime::~CoreRuntime()
 
 int CoreRuntime::initialize(bool standalone)
 {
+#define __XSTR(x) #x
+#define __STR(x) __XSTR(x)
+
+#ifdef NATIVE_LIB_DIR
+       __nativeLibDirectory = __STR(NATIVE_LIB_DIR);
+#endif
+
+#undef __STR
+#undef __XSTR
+
 #ifdef __arm__
        // libunwind library is used to unwind stack frame, but libunwind for ARM
        // does not support ARM vfpv3/NEON registers in DWARF format correctly.
@@ -158,32 +131,23 @@ int CoreRuntime::initialize(bool standalone)
        putenv(const_cast<char *>("UNW_ARM_UNWIND_METHOD=6"));
 #endif // __arm__
 
-       if (__deviceAPIDirectory.empty()) {
-               _ERR("Empty Device API Directory");
-               return 1;
-       } else {
-               __deviceAPIDirectory = absolutePath(__deviceAPIDirectory);
+       if (initializePluginManager(__mode) < 0) {
+               _ERR("Failed to initialize PluginManager");
+               return -1;
        }
 
-       if (__runtimeDirectory.empty()) {
-               _ERR("Empty Runtime Directory");
-               return 1;
-       } else {
-               __runtimeDirectory = absolutePath(__runtimeDirectory);
+       if (initializePathManager(std::string(), std::string(), std::string()) < 0) {
+               _ERR("Failed to initialize PathManager");
+               return -1;
        }
 
-       // set Reference API directory
-       __refAPIDirectory = __deviceAPIDirectory + "/ref";
-
-       std::string libCoreclr(concatPath(__runtimeDirectory, "libcoreclr.so"));
-
-       _DBG("libcoreclr : %s", libCoreclr.c_str());
+       std::string libCoreclr(concatPath(getRuntimeDir(), "libcoreclr.so"));
 
        __coreclrLib = dlopen(libCoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
        if (__coreclrLib == nullptr) {
                char *err = dlerror();
                _ERR("dlopen failed to open libcoreclr.so with error %s", err);
-               return 1;
+               return -1;
        }
 
 #define CORELIB_RETURN_IF_NOSYM(type, variable, name) \
@@ -191,7 +155,7 @@ int CoreRuntime::initialize(bool standalone)
                variable = (type)dlsym(__coreclrLib, name); \
                if (variable == nullptr) { \
                        _ERR(name " is not found in the libcoreclr.so"); \
-                       return 1; \
+                       return -1; \
                } \
        } while (0)
 
@@ -204,39 +168,21 @@ int CoreRuntime::initialize(bool standalone)
 
        _DBG("libcoreclr dlopen and dlsym success");
 
-       if (!standalone && pluginPreload)
+       if (!standalone)
                pluginPreload();
 
        fd = open("/proc/self", O_DIRECTORY);
-       std::string path_tmp = std::string("/proc/self/fd/") + std::to_string(fd);
-
-       std::string appRoot = path_tmp;
+       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 probePath = appBin + ":" + appLib;
-
-       std::string tpa;
-       std::vector<std::string> searchDirectories;
-       searchDirectories.push_back(__runtimeDirectory);
-       searchDirectories.push_back(__deviceAPIDirectory);
-       searchDirectories.push_back(__refAPIDirectory);
-
-       if (pluginGetDllPath) {
-               std::string pluginPath = pluginGetDllPath();
-               if (!pluginPath.empty()) {
-                       splitPath(pluginPath, searchDirectories);
-               }
-       }
-
-       assembliesInDirectory(searchDirectories, tpa);
-
-       std::string nativeLibPath;
-       nativeLibPath = getExtraNativeLibDirs(appRoot) + ":" + appBin + ":" + appLib + ":" + __nativeLibDirectory;
-
+       std::string tpa = getTPA();
+       std::string nativeLibPath = getExtraNativeLibDirs(appRoot) + ":" + appBin + ":" + appLib + ":" + __nativeLibDirectory;
        std::string appName = std::string("dotnet-launcher-") + std::to_string(getpid());
+
        if (!initializeCoreClr(appName.c_str(), probePath.c_str(), nativeLibPath.c_str(), tpa.c_str())) {
                _ERR("Failed to initialize coreclr");
-               return 1;
+               return -1;
        }
 
        return 0;
@@ -278,8 +224,7 @@ bool CoreRuntime::initializeCoreClr(const char* appId,
                return false;
        }
 
-       if (pluginSetCoreclrInfo)
-               pluginSetCoreclrInfo(__hostHandle, __domainId, createDelegate);
+       pluginSetCoreclrInfo(__hostHandle, __domainId, createDelegate);
 
        _DBG("Initialize core clr success");
        return true;
@@ -291,63 +236,43 @@ void CoreRuntime::dispose()
                int st = shutdown(__hostHandle, __domainId);
                if (st < 0)
                        _ERR("shutdown core clr fail! (0x%08x)", st);
+               __hostHandle = nullptr;
        }
 
-       if (dlclose(__coreclrLib) != 0)
-               _ERR("libcoreclr.so close failed");
-
-       __coreclrLib = nullptr;
-
-       if (pluginFinalize)
-               pluginFinalize();
-
-       if (__pluginLib != nullptr) {
-               if (dlclose(__pluginLib) != 0)
-                       _ERR("libdotnet_plugin.so close failed");
+       if (__coreclrLib != nullptr) {
+               if (dlclose(__coreclrLib) != 0) {
+                       _ERR("libcoreclr.so close failed");
+               }
 
-               __pluginLib = nullptr;
-               pluginInitialize = nullptr;
-               pluginPreload = nullptr;
-               pluginSetAppInfo = nullptr;
-               pluginSetCoreclrInfo = nullptr;
-               pluginGetDllPath = nullptr;
-               pluginBeforeExecute = nullptr;
-               pluginFinalize = nullptr;
+               __coreclrLib = nullptr;
        }
 
+       finalizePluginManager();
+       finalizePathManager();
+
        _DBG("Dotnet runtime disposed");
 }
 
 int CoreRuntime::launch(const char* appId, const char* root, const char* path, int argc, char* argv[])
 {
-       if (runLoggingThread() < 0) {
-               _ERR("Failed to create logging thread");
-       }
-
        if (path == nullptr) {
                _ERR("executable path is null");
-               return 1;
+               return -11;
        }
 
-       if (fileNotExist(path)) {
+       if (!isFileExist(path)) {
                _ERR("File not exist : %s", path);
-               return 1;
+               return -1;
        }
 
-       if (pluginSetAppInfo)
-               pluginSetAppInfo(appId, path);
+       pluginSetAppInfo(appId, path);
 
        int fd2 = open(root, O_DIRECTORY);
        dup3(fd2, fd, O_CLOEXEC);
        if (fd2 >= 0)
                close(fd2);
 
-       if (pluginBeforeExecute)
-               pluginBeforeExecute();
-
-       if (runLoggingThread() < 0) {
-               _ERR("Failed to create logging thread");
-       }
+       pluginBeforeExecute();
 
        unsigned int ret = 0;
        int st = executeAssembly(__hostHandle, __domainId, argc, (const char**)argv, path, &ret);
index 37b029642edd4a031d0603c17d810198391e0c56..82052f28902538596930266e3145710ee7b25e3e 100644 (file)
 #define __DOTNET_LAUNCHER_H__
 
 #include "launcher.h"
-
-extern "C"
-{
-       typedef int (*coreclr_initialize_ptr)(
-                       const char* exePath,
-                       const char* appDomainFriendlyName,
-                       int propertyCount,
-                       const char** propertyKeys,
-                       const char** propertyValues,
-                       void** hostHandle,
-                       unsigned int* domainId);
-
-       typedef int (*coreclr_execute_assembly_ptr)(
-                       void* hostHandle,
-                       unsigned int domainId,
-                       int argc,
-                       const char** argv,
-                       const char* managedAssemblyPath,
-                       unsigned int* exitCode);
-
-       typedef int (*coreclr_shutdown_ptr)(
-                       void* hostHandle,
-                       unsigned int domainId);
-
-       typedef int (*coreclr_create_delegate_ptr)(
-                       void* hostHandle,
-                       unsigned int domainId,
-                       const char* entryPointAssemblyName,
-                       const char* entryPointTypeName,
-                       const char* entryPointMethodName,
-                       void** delegate);
-
-       typedef void (*plugin_initialize_ptr)(const char* mode);
-
-       typedef void (*plugin_preload_ptr)();
-
-       typedef void (*plugin_set_app_info_ptr)(
-                       const char* appId,
-                       const char* managedAssemblyPath);
-
-       typedef void (*plugin_set_coreclr_info_ptr)(
-                       void* hostHandle,
-                       unsigned int domainId,
-                       coreclr_create_delegate_ptr delegateFunc);
-
-       typedef char* (*plugin_get_dll_path_ptr)();
-
-       typedef void (*plugin_before_execute_ptr)();
-
-       typedef void (*plugin_finalize_ptr)();
-}
+#include "coreclr_host.h"
+#include "plugin_manager.h"
 
 namespace tizen {
 namespace runtime {
 namespace dotnetcore {
 
-typedef void (*PreparedFunctionPtr)();
-typedef bool (*LaunchFunctionPtr)(const char* root, const char* path, int argc, char* argv[]);
-
-class CoreRuntime : public tizen::runtime::LauncherInterface
+class CoreRuntime
 {
        public:
                CoreRuntime(const char* mode);
                ~CoreRuntime();
-               int initialize(bool standalone) override;
-               void dispose() override;
-               int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]) override;
+               int initialize(bool standalone);
+               void dispose();
+               int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]);
 
        private:
                bool initializeCoreClr(const char* appId, const char* assemblyProbePaths, const char* pinvokeProbePaths, const char* tpaList);
@@ -92,24 +40,10 @@ class CoreRuntime : public tizen::runtime::LauncherInterface
                coreclr_execute_assembly_ptr executeAssembly;
                coreclr_shutdown_ptr shutdown;
                coreclr_create_delegate_ptr createDelegate;
-               std::string __deviceAPIDirectory;
-               std::string __runtimeDirectory;
                std::string __nativeLibDirectory;
-               std::string __refAPIDirectory;
                void* __coreclrLib;
                void* __hostHandle;
                unsigned int __domainId;
-               PreparedFunctionPtr preparedFunction;
-               LaunchFunctionPtr launchFunction;
-               // plugin function pointer
-               void* __pluginLib;
-               plugin_initialize_ptr pluginInitialize;
-               plugin_preload_ptr      pluginPreload;
-               plugin_set_app_info_ptr pluginSetAppInfo;
-               plugin_set_coreclr_info_ptr     pluginSetCoreclrInfo;
-               plugin_get_dll_path_ptr pluginGetDllPath;
-               plugin_before_execute_ptr pluginBeforeExecute;
-               plugin_finalize_ptr     pluginFinalize;
                int fd;
                const char* __mode;
 };
index e0b5ed027c79fe66c9ad2d2d261160c41e69bfad..b0f3e1bd0c62fb0e06bd1f45eb4eab0b9aec6f00 100644 (file)
@@ -50,7 +50,6 @@ class LaunchpadAdapterImpl : public LaunchpadAdapter
                LaunchpadAdapterImpl() :
                        callbacks(),
                        adapter(),
-                       launcher(nullptr),
                        __isLaunched(false)
                { }
                int loaderMain(int argc, char* argv[]) override;
@@ -61,7 +60,6 @@ class LaunchpadAdapterImpl : public LaunchpadAdapter
                AppInfo appInfo;
                loader_lifecycle_callback_s callbacks;
                loader_adapter_s adapter;
-               LauncherInterface* launcher;
                bool __isLaunched;
                std::string __launchPath;
 };
@@ -122,29 +120,9 @@ static void fdRemove(void *data, int fd)
        }
 }
 
-static void preloadLibsAndWindow(bundle *extra, int type, void *userData)
+static void preCreateWindow(bundle *extra, int type, void *userData)
 {
        int elmInitCnt = 0;
-       const char **soArray;
-       int len = 0;
-       int i;
-       void *handle = NULL;
-
-       // Preload native libraries
-       if (extra == NULL) {
-               _DBG("No extra data");
-               return;
-       }
-
-       soArray = bundle_get_str_array(extra, "preload", &len);
-
-       if (!soArray)
-               return;
-
-       for (i = 0; i < len; i++) {
-               handle = dlopen(soArray[i], RTLD_NOW);
-               _DBG("preload %s#", soArray[i]);
-       }
 
        // Precreate window
        elmInitCnt = elm_init(__argc, __argv);
@@ -167,7 +145,7 @@ int LaunchpadAdapterImpl::loaderMain(int argc, char* argv[])
        __argv = argv;
        callbacks.create = [](bundle *extra, int type, void *userData) {
                ecore_init();
-               preloadLibsAndWindow(extra, type, userData);
+               preCreateWindow(extra, type, userData);
                WITH_SELF(userData) {
                        if (self->onCreate != nullptr)
                                self->onCreate();
index 38934b43f0667f2d39d52062ba2d28f9f2eebe20..e48f318f8023f7b555d26817eac3f4b0d212236e 100644 (file)
 namespace tizen {
 namespace runtime {
 
-class LauncherInterface
-{
-       public:
-               virtual int initialize(bool standalone) = 0;
-               virtual void dispose() = 0;
-               virtual int launch(const char* appId, const char* root, const char* path, int argc, char* argv[]) = 0;
-};
-
 struct AppInfo {
        std::string root;
        std::string path;
index e49010e203d6154fd19cef2cbc0b46555b11ad74..952249664c51372ab8ced206d24d8ba3b9123fc6 100644 (file)
 #include <sys/types.h>
 #include <unistd.h>
 
-#define __XSTR(x) #x
-#define __STR(x) __XSTR(x)
-
-#ifndef VERSION
-#define LAUNCHER_VERSION_STR "-Unknown-"
-#else
-#define LAUNCHER_VERSION_STR __STR(VERSION)
-#endif
-
 #define CMD_LINE_SIZE  24      // sizeof("/usr/bin/dotnet-launcher")
 
-static std::string VersionOption("--version");
 static std::string StandaloneOption("--standalone");
 
 extern "C" int realMain(int argc, char *argv[], const char* mode)
@@ -52,10 +42,7 @@ extern "C" int realMain(int argc, char *argv[], const char* mode)
 
        // start index 1 to avoid passing executable name "dotnet-launcher" as a parameter
        for (i = 1; i < argc; i++) {
-               if (VersionOption.compare(argv[i]) == 0) {
-                       printf("Dotnet launcher Version %s\n", LAUNCHER_VERSION_STR);
-                       return 0;
-               } else if (StandaloneOption.compare(argv[i]) == 0) {
+               if (StandaloneOption.compare(argv[i]) == 0) {
                        standalone = true;
 
                        if (i > argc-1) {
@@ -69,14 +56,11 @@ extern "C" int realMain(int argc, char *argv[], const char* mode)
                }
        }
 
-       using tizen::runtime::LauncherInterface;
        using tizen::runtime::Launchpad;
        using tizen::runtime::AppInfo;
-       std::unique_ptr<LauncherInterface> runtime;
-
        using tizen::runtime::dotnetcore::CoreRuntime;
-       std::unique_ptr<LauncherInterface> coreRuntime(new CoreRuntime(mode));
-       runtime = std::move(coreRuntime);
+
+       std::unique_ptr<CoreRuntime> runtime(new CoreRuntime(mode));
 
        if (standalone) {
                _DBG("##### Run it standalone #########");
@@ -140,7 +124,6 @@ extern "C" int realMain(int argc, char *argv[], const char* mode)
                }
        }
 
-       runtime->dispose();
        return 0;
 }
 
diff --git a/NativeLauncher/util/path_manager.cc b/NativeLauncher/util/path_manager.cc
new file mode 100644 (file)
index 0000000..7ca1e3e
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vector>
+#include <iterator>
+#include <sstream>
+#include <vconf.h>
+
+#include "utils.h"
+#include "plugin_manager.h"
+#include "log.h"
+
+static const char* __TIZEN_API_PATH_KEY = "db/dotnet/tizen_api_path";
+
+#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);
+#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;
+} DllPath;
+
+static DllPath* __dllPath = NULL;
+static std::string __tpa;
+
+// on success, return 0. otherwise return -1.
+int initializePathManager(const std::string& runtimeDir, const std::string& tizenFXDir, const std::string& extraDir)
+{
+
+       __dllPath = (DllPath*)calloc(sizeof(DllPath), 1);
+       if (!__dllPath) {
+               fprintf(stderr, "fail to allocate memory for dll path structure\n");
+               return -1;
+       }
+
+       if (!runtimeDir.empty()) {
+               __dllPath->runtime_dir = absolutePath(runtimeDir);
+       } else {
+               __dllPath->runtime_dir = absolutePath(__RUNTIME_DIR);
+       }
+
+       if (!tizenFXDir.empty()) {
+               __dllPath->tizenfx_dir = absolutePath(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);
+               } else {
+                       __dllPath->tizenfx_dir = absolutePath(__DEVICE_API_DIR);
+               }
+       }
+
+       __dllPath->tizenfx_ref_dir = __dllPath->tizenfx_dir + "/ref";
+
+       // ":" seperated extra directories
+       if (!extraDir.empty()) {
+               splitPath(extraDir, __dllPath->extra_dirs);
+       } else {
+               if (pluginGetDllPath()) {
+                       std::string pluginPath(pluginGetDllPath());
+                       if (!pluginPath.empty()) {
+                               splitPath(pluginPath, __dllPath->extra_dirs);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+void finalizePathManager()
+{
+       if (__dllPath) {
+               free(__dllPath);
+               __dllPath = NULL;
+       }
+}
+
+std::string getRuntimeDir()
+{
+       return __dllPath->runtime_dir;
+}
+
+std::string getTizenFXDir()
+{
+       return __dllPath->tizenfx_dir;
+}
+
+std::string getTizenFXRefDir()
+{
+       return __dllPath->tizenfx_ref_dir;
+}
+
+std::vector <std::string> getExtraDirs()
+{
+       return __dllPath->extra_dirs;
+}
+
+std::string getTPA()
+{
+       if (!__tpa.empty()) {
+               return __tpa;
+       }
+
+       std::vector<std::string> tpaDir;
+
+       if (__dllPath == NULL) {
+               return std::string("");
+       }
+
+       tpaDir.push_back(getRuntimeDir());
+       tpaDir.push_back(getTizenFXDir());
+       tpaDir.push_back(getTizenFXRefDir());
+       tpaDir.insert(tpaDir.end(), getExtraDirs().begin(), getExtraDirs().end());
+       assembliesInDirectory(tpaDir, __tpa);
+
+       return __tpa;
+}
+
diff --git a/NativeLauncher/util/path_manager.h b/NativeLauncher/util/path_manager.h
new file mode 100644 (file)
index 0000000..72dc042
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#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();
+
+std::string getRuntimeDir();
+std::string getTizenFXDir();
+std::string getTizenFXRefDir();
+std::string getExtraDirs();
+
+std::string getTPA();
+
+#endif /* __DLL_PATH_MANAGER_H__ */
\ No newline at end of file
diff --git a/NativeLauncher/util/plugin_manager.cc b/NativeLauncher/util/plugin_manager.cc
new file mode 100644 (file)
index 0000000..563eaa3
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <dlfcn.h>
+
+#include "plugin_manager.h"
+#include "utils.h"
+#include "log.h"
+
+static PluginFunc* __pluginFunc = NULL;
+static void* __pluginLib;
+
+#define PLUGIN_PATH "/usr/share/dotnet.tizen/lib/libdotnet_plugin.so"
+
+int initializePluginManager(const char* mode)
+{
+       if (isFileExist(PLUGIN_PATH)) {
+               __pluginLib = dlopen(PLUGIN_PATH, RTLD_NOW | RTLD_LOCAL);
+               if (__pluginLib) {
+                       __pluginFunc = (PluginFunc*)calloc(sizeof(PluginFunc), 1);
+                       if (!__pluginFunc) {
+                               fprintf(stderr, "fail to allocate memory for plugin function structure\n");
+                               return -1;
+                       }
+                       __pluginFunc->initialize = (plugin_initialize_ptr)dlsym(__pluginLib, "plugin_initialize");
+                       __pluginFunc->preload = (plugin_preload_ptr)dlsym(__pluginLib, "plugin_preload");
+                       __pluginFunc->set_app_info = (plugin_set_app_info_ptr)dlsym(__pluginLib, "plugin_set_app_info");
+                       __pluginFunc->set_coreclr_info = (plugin_set_coreclr_info_ptr)dlsym(__pluginLib, "plugin_set_coreclr_info");
+                       __pluginFunc->get_dll_path = (plugin_get_dll_path_ptr)dlsym(__pluginLib, "plugin_get_dll_path");
+                       __pluginFunc->before_execute = (plugin_before_execute_ptr)dlsym(__pluginLib, "plugin_before_execute");
+                       __pluginFunc->finalize  = (plugin_finalize_ptr)dlsym(__pluginLib, "plugin_finalize");
+               }
+
+               if (__pluginFunc->initialize)
+                       __pluginFunc->initialize(mode);
+       }
+
+       return 0;
+}
+
+void finalizePluginManager()
+{
+       if (__pluginFunc) {
+               if (__pluginFunc->finalize) {
+                       __pluginFunc->finalize();
+               }
+               free(__pluginFunc);
+               __pluginFunc = NULL;
+       }
+
+       if (__pluginLib) {
+               dlclose(__pluginLib);
+               __pluginLib = NULL;
+       }
+}
+
+void pluginPreload()
+{
+       if (__pluginFunc && __pluginFunc->preload) {
+               __pluginFunc->preload();
+       }
+}
+
+void pluginSetAppInfo(const char* appId, const char* managedAssemblyPath)
+{
+       if (__pluginFunc && __pluginFunc->set_app_info) {
+               __pluginFunc->set_app_info(appId, managedAssemblyPath);
+       }
+}
+
+void pluginSetCoreclrInfo(void* hostHandle, unsigned int domainId, coreclr_create_delegate_ptr delegateFunc)
+{
+       if (__pluginFunc && __pluginFunc->set_coreclr_info) {
+               __pluginFunc->set_coreclr_info(hostHandle, domainId, delegateFunc);
+       }
+}
+
+char* pluginGetDllPath()
+{
+       if (__pluginFunc && __pluginFunc->get_dll_path) {
+               return __pluginFunc->get_dll_path();
+       } else {
+               return NULL;
+       }
+}
+
+void pluginBeforeExecute()
+{
+       if (__pluginFunc && __pluginFunc->before_execute) {
+               __pluginFunc->before_execute();
+       }
+}
+
index 4016ac59d4461ee41211fcd3bc4ad902547cd2b8..76ac83190a2eb0ad49316e5203e784ad1cb04c1b 100644 (file)
 #include <sstream>
 
 #include "utils.h"
+#include "path_manager.h"
 #include "log.h"
 
 static pthread_t loggingThread;
 
-bool iCompare(const std::string& a, const std::string& b)
-{
-       return a.length() == b.length() &&
-               std::equal(b.begin(), b.end(), a.begin(),
-                       [](unsigned char a, unsigned char b)
-                       { return std::tolower(a) == std::tolower(b); });
-}
-
-bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
+static bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length)
 {
        return static_cast<int>(a.length()) - length >= aOffset &&
                static_cast<int>(b.length()) - length >= bOffset &&
@@ -54,8 +47,9 @@ bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffs
 
 bool isManagedAssembly(const std::string& fileName)
 {
-       return iCompare(fileName, fileName.size()-4, ".dll", 0, 4) ||
-               iCompare(fileName, fileName.size()-4, ".exe", 0, 4);
+       return (iCompare(fileName, fileName.size()-4, ".dll", 0, 4) ||
+                       iCompare(fileName, fileName.size()-4, ".exe", 0, 4)) &&
+                       !isNativeImage(fileName);
 }
 
 bool isNativeImage(const std::string& fileName)
@@ -98,16 +92,6 @@ void splitPath(const std::string& path, std::vector<std::string>& out)
        }
 }
 
-void appendPath(std::string& path1, const std::string& path2)
-{
-       if (path1.back() == PATH_SEPARATOR) {
-               path1.append(path2);
-       } else {
-               path1 += PATH_SEPARATOR;
-               path1.append(path2);
-       }
-}
-
 std::string absolutePath(const std::string& path)
 {
        std::string absPath;
@@ -128,56 +112,12 @@ std::string baseName(const std::string& path)
        return path;
 }
 
-bool endWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& fileName)
-{
-       std::string::size_type len1 = str1.length();
-       std::string::size_type len2 = str2.length();
-       if (len2 > len1)
-               return false;
-
-       int i = 0;
-       bool result = std::all_of(str1.cend() - len2, str1.end(),
-                               [&i, &str2] (char x) {
-                                       return std::tolower(x) == std::tolower(str2[i++]);
-                               });
-       if (result)
-               fileName = str1.substr(0, len1 - len2);
-
-       return result;
-}
-
-bool fileNotExist(const std::string& path)
+bool isFileExist(const std::string& path)
 {
        struct stat sb;
-       return stat(path.c_str(), &sb) != 0;
+       return stat(path.c_str(), &sb) == 0;
 }
 
-#ifdef NOT_USE_FUNCTION
-static bool extCheckAndGetFileNameIfExist(const std::string& dir, const std::string& ext, struct dirent* entry, std::string& fileName)
-{
-       std::string fName(entry->d_name);
-       if (fName.length() < ext.length() ||
-                       fHame.compare(fName.length() - ext.length(), ext.length(), ext) != 0) {
-               return false;
-       }
-
-       std::string fullName = concatPath(dir, entry->d_name);
-       switch (entry->d_type) {
-               case DT_REG: break;
-               case DT_LNK:
-               case DT_UNKNOWN:
-                       if (fileNotExist(fullName))
-                               return false;
-               default:
-                       return false;
-       }
-
-       fileName = fullName;
-
-       return true;
-}
-#endif
-
 std::string stripNiDLL(const std::string& path)
 {
        std::string niPath(path);
@@ -193,57 +133,19 @@ std::string stripNiDLL(const std::string& path)
        return niPath;
 }
 
-std::string joinStrings(const std::vector<std::string>& strings, const char* const delimeter)
-{
-       switch (strings.size()) {
-               case 0:
-                       return "";
-               case 1:
-                       return strings[0];
-               default:
-                       std::ostringstream os;
-                       std::copy(strings.begin(), strings.end()-1, std::ostream_iterator<std::string>(os, delimeter));
-                       os << *strings.rbegin();
-                       return os.str();
-       }
-}
-
-struct AssemblyFile {
-       std::string noExt;
-       std::string ext;
-};
-
-bool operator == (const AssemblyFile& lhs, const AssemblyFile& rhs)
-{
-       return lhs.noExt == rhs.noExt && lhs.ext == rhs.ext;
-}
-
-namespace std {
-       template<>
-       struct hash<AssemblyFile> {
-               std::size_t operator () (const AssemblyFile& f) const {
-                       const std::size_t h1 = std::hash<std::string>{}(f.noExt);
-                       const std::size_t h2 = std::hash<std::string>{}(f.ext);
-
-                       return h1 ^ (h2 << 1);
-               }
-       };
-}
-
 void assembliesInDirectory(const std::vector<std::string>& directories, std::string& tpaList)
 {
        std::map<std::string, std::string> assemblyList;
        std::map<std::string, std::string> tmpList;
 
-       auto reader = [&assemblyList, &tmpList] (const char* path, const char* name) {
-               std::string pathStr(path);
-               if (isManagedAssembly(pathStr)) {
+       auto reader = [&assemblyList, &tmpList] (const std::string& path, const char* name) {
+               if (isManagedAssembly(path) || isNativeImage(path)) {
                        std::string dllName = stripNiDLL(name);
                        std::pair<std::map<std::string, std::string>::iterator, bool> ret;
-                       ret = tmpList.insert(std::pair<std::string, std::string>(dllName, pathStr));
+                       ret = tmpList.insert(std::pair<std::string, std::string>(dllName, path));
                        if (ret.second == false) {
-                               if (isNativeImage(pathStr))
-                                       tmpList[dllName] = pathStr;
+                               if (isNativeImage(path))
+                                       tmpList[dllName] = path;
                        }
                }
        };
@@ -263,13 +165,13 @@ void assembliesInDirectory(const std::vector<std::string>& directories, std::str
                tpaList.pop_back();
 }
 
-void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth)
+void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth)
 {
        DIR *dir;
        struct dirent* entry;
        bool isDir;
 
-       dir = opendir(directory);
+       dir = opendir(directory.c_str());
 
        if (dir == nullptr)
                return;
@@ -296,7 +198,7 @@ void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth
                                continue;
                }
                if (!isDir)
-                       reader(path.c_str(), entry->d_name);
+                       reader(path, entry->d_name);
                else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, ".."))
                        innerDirectories.push_back(path);
        }
@@ -308,12 +210,30 @@ void scanFilesInDir(const char* directory, FileReader reader, unsigned int depth
        closedir(dir);
 }
 
+static int __pfd[2];
+
 static void *stdlog(void*)
 {
-       int pfd[2];
     ssize_t readSize;
     char buf[1024];
 
+    while ((readSize = read(__pfd[0], buf, sizeof buf - 1)) > 0) {
+        if (buf[readSize - 1] == '\n') {
+            --readSize;
+        }
+
+        buf[readSize] = 0;
+
+        _LOGX("%s", buf);
+    }
+
+       close(__pfd[0]);
+
+    return 0;
+}
+
+int runLoggingThread()
+{
     if (setvbuf(stdout, NULL, _IOLBF, 0) < 0) {
                _DBG("fail to make stdout line-buffered");
                return 0;
@@ -325,39 +245,25 @@ static void *stdlog(void*)
        }
 
     /* create the pipe and redirect stdout and stderr */
-    if (pipe(pfd) < 0) {
+    if (pipe(__pfd) < 0) {
                _DBG("fail to create pipe for logging");
                return 0;
     }
 
-    if (dup2(pfd[1], fileno(stdout)) == -1) {
+    // stdout
+    if (dup2(__pfd[1], 1) == -1) {
                _DBG("fail to duplicate fd to stdout");
                return 0;
     }
 
-    if (dup2(pfd[1], fileno(stderr)) == -1) {
+    // stderr
+    if (dup2(__pfd[1], 2) == -1) {
                _DBG("fail to duplicate fd to stderr");
                return 0;
        }
 
-       close(pfd[1]);
-
-    while ((readSize = read(pfd[0], buf, sizeof buf - 1)) > 0) {
-        if (buf[readSize - 1] == '\n') {
-            --readSize;
-        }
-
-        buf[readSize] = 0;
-
-        _LOGX("%s", buf);
-    }
-
-       close(pfd[0]);
-
-    return 0;
-}
+       close(__pfd[1]);
 
-int runLoggingThread() {
     /* spawn the logging thread */
     if (pthread_create(&loggingThread, 0, stdlog, 0) != 0) {
                _DBG("fail to create pthread");
index 19c42ff0b901ad76ff041b6d0900084067c6f911..9f3e611174f310e604f7120337fbabaef1bf3e77 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dotnet-launcher
 Summary:    Launchpad plugin for dotnet apps
-Version:    1.1.0
+Version:    2.1.0
 Release:    1
 Group:      Application Framework/Application State Management
 License:    Apache-2.0
@@ -17,6 +17,7 @@ BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(pkgmgr-installer)
 BuildRequires: pkgconfig(elementary)
 BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(libsmack)
 BuildRequires: aul-devel
 BuildRequires: dotnet-build-tools
 
@@ -35,10 +36,8 @@ Requires(postun): /usr/bin/systemctl
 Requires(preun): /usr/bin/systemctl
 
 %define _loaderdir %{_prefix}/share/aul
-%define _configdir /etc
 %define _device_api_dir %{dotnet_assembly_path}
 %define _runtime_dir /usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0
-%define _install_plugin_dir /usr/etc/package-manager/parserlib
 %define _install_mdplugin_dir /etc/package-manager/parserlib/metadata
 %define _native_lib_dir /usr/share/dotnet.tizen/lib
 
@@ -47,6 +46,13 @@ ExcludeArch: aarch64
 %description
 Launchpad plugin for launching dotnet apps
 
+%package devel
+Summary: Libraries and Header Files for dotnet-launcher plugins and AOTC tools
+Requires: %{name} = %{version}
+
+%description devel
+This package contains library and header files needed to develop plugins for dotnet-launcher
+and AOTC tools.
 
 %prep
 %setup -q
@@ -70,16 +76,14 @@ cmake \
        -DCMAKE_CXX_COMPILER=clang++ \
        -DASAN_ENABLED=TRUE \
 %endif
-       -DPACKAGE_NAME=%{name} \
        -DLIBDIR=%{_libdir} \
        -DBINDIR=%{_bindir} \
+       -DINCLUDEDIR=%{_includedir} \
        -DLOADERDIR=%{_loaderdir} \
-       -DCONFIGDIR=%{_configdir} \
        -DCMAKE_BUILD_TYPE=%{_dotnet_build_conf} \
        -DDEVICE_API_DIR=%{_device_api_dir} \
        -DRUNTIME_DIR=%{_runtime_dir} \
        -DCROSSGEN_PATH=%{_device_api_dir}/crossgen \
-       -DINSTALL_PLUGIN_DIR=%{_install_plugin_dir} \
        -DINSTALL_MDPLUGIN_DIR=%{_install_mdplugin_dir} \
        -DVERSION=%{version} \
        -DNATIVE_LIB_DIR=%{_native_lib_dir} \
@@ -101,7 +105,18 @@ ln -sf %{_libdir}/libsqlite3.so.0 %{buildroot}%{_native_lib_dir}/libsqlite3.so
 %{_loaderdir}/dotnet.debugger
 %{_native_lib_dir}/libsqlite3.so
 %{_bindir}/nitool
-#%{_install_plugin_dir}/libui-application.so
 %{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so
 %{_bindir}/dotnet-launcher
+%{_libdir}/libdotnet_launcher_util.so
+%{_libdir}/libni_common.so
+
+%files devel
+%manifest dotnet-launcher.manifest
+%defattr(-,root,root,-)
+%{_includedir}/ni_common.h
+%{_includedir}/dotnet_launcher_plugin.h
+%{_includedir}/coreclr_host.h
+%{_libdir}/libdotnet_launcher_util.so
+%{_libdir}/libni_common.so
+%{_libdir}/pkgconfig/dotnet-launcher.pc