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}")
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
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)
+
--- /dev/null
+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}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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__ */
#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__ */
+++ /dev/null
-/*
- * 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;
-}
+++ /dev/null
-/*
- * 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__ */
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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__ */
* limitations under the License.
*/
-#include "common.h"
+#include "ni_common.h"
#include <cstdio>
#include <cstring>
#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);
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;
} 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)
}
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;
* limitations under the License.
*/
-#include "common.h"
+#include "ni_common.h"
#include "log.h"
#include "utils.h"
}
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;
* limitations under the License.
*/
-#include "common.h"
+#include "ni_common.h"
#include "log.h"
#ifdef LOG_TAG
#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"
__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()
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.
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) \
variable = (type)dlsym(__coreclrLib, name); \
if (variable == nullptr) { \
_ERR(name " is not found in the libcoreclr.so"); \
- return 1; \
+ return -1; \
} \
} while (0)
_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;
return false;
}
- if (pluginSetCoreclrInfo)
- pluginSetCoreclrInfo(__hostHandle, __domainId, createDelegate);
+ pluginSetCoreclrInfo(__hostHandle, __domainId, createDelegate);
_DBG("Initialize core clr success");
return true;
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);
#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);
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;
};
LaunchpadAdapterImpl() :
callbacks(),
adapter(),
- launcher(nullptr),
__isLaunched(false)
{ }
int loaderMain(int argc, char* argv[]) override;
AppInfo appInfo;
loader_lifecycle_callback_s callbacks;
loader_adapter_s adapter;
- LauncherInterface* launcher;
bool __isLaunched;
std::string __launchPath;
};
}
}
-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);
__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();
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;
#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)
// 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) {
}
}
- 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 #########");
}
}
- runtime->dispose();
return 0;
}
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+ }
+}
+
#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 &&
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)
}
}
-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;
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);
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;
}
}
};
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;
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);
}
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;
}
/* 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");
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
BuildRequires: pkgconfig(pkgmgr-installer)
BuildRequires: pkgconfig(elementary)
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(libsmack)
BuildRequires: aul-devel
BuildRequires: dotnet-build-tools
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
%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
-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} \
%{_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