SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DLAUNCHER_ASSEMBLY_PATH=${LAUNCHER_ASSEMBLY_PATH}")
ENDIF(DEFINED LAUNCHER_ASSEMBLY_PATH)
+IF(DEFINED DEVICE_API_DIR)
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DDEVICE_API_DIR=${DEVICE_API_DIR}")
+ENDIF(DEFINED DEVICE_API_DIR)
+
+IF(DEFINED RUNTIME_DIR)
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -DRUNTIME_DIR=${RUNTIME_DIR}")
+ENDIF(DEFINED RUNTIME_DIR)
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -std=c++11")
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" )
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR})
INSTALL(TARGETS ${LAUNCHER_LIB} DESTINATION ${LIBDIR})
INSTALL(FILES dotnet.loader DESTINATION ${LOADERDIR})
- INSTALL(FILES dotnet-launcher.ini DESTINATION ${CONFIGDIR})
ENDIF(NOT DEFINED NO_TIZEN)
+++ /dev/null
-[dotnet]
-libcoreclr = /opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0/libcoreclr.so
-coreclr_dir = /opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0
-tpa_dirs = /opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0:/usr/share/assembly
-native_so_search_dirs = /opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0:/usr/share/assembly
-launcher_assembly = /usr/bin/Tizen.Runtime.exe
#include "tini.hpp"
-#define __STR(x) #x
-#define __XSTR(x) __STR(x)
+#define __XSTR(x) #x
+#define __STR(x) __XSTR(x)
-#ifdef LAUNCHER_CONFIG_PATH
-#define LAUNCHER_CONFIG __XSTR(LAUNCHER_CONFIG_PATH)
+#ifndef NO_TIZEN
+
+#ifndef DEVICE_API_DIR
+ #error "DEVICE_API_DIR must be exist."
+#endif
+
+#ifndef RUNTIME_DIR
+ #error "RUNTIME_DIR must be exist."
+#endif
+
+#ifndef LAUNCHER_ASSEMBLY_PATH
+ #error "LAUNCHER_ASSEMBLY_PATH must be exist."
+#endif
+
+#define CONST const
+#else
+
+#define CONST
+#include <stdlib.h>
+#endif
+
+#ifdef DEVICE_API_DIR
+static CONST std::string DeviceAPIDirectory(__STR(DEVICE_API_DIR));
+#else
+static std::string DeviceAPIDirectory;
+#endif
+#ifdef RUNTIME_DIR
+static CONST std::string RuntimeDirectory(__STR(RUNTIME_DIR));
#else
-#define LAUNCHER_CONFIG "/etc/dotnet-launcher.ini"
+static std::string RuntimeDirectory;
#endif
-static const std::string LauncherConfig(LAUNCHER_CONFIG);
-#ifdef LAUNCHER_CONFIG_PATH
-#undef LAUNCHER_CONFIG
-#undef LAUNCHER_CONFIG_PATH
+#ifdef LAUNCHER_ASSEMBLY_PATH
+static CONST std::string LauncherAssembly(__STR(LAUNCHER_ASSEMBLY_PATH));
+#else
+static std::string LauncherAssembly;
#endif
+
#undef __STR
#undef __XSTR
return "";
}
-/*
static std::string ConcatPath(const std::string& path1, const std::string& path2)
{
std::string path(path1);
return path;
}
+/*
static void AppendPath(std::string& path1, const std::string& path2)
{
if (path1.back() == PATH_SEPARATOR)
{
return path.substr(0, pos);
}
+ else
+ {
+ return std::string(".");
+ }
return path;
}
if (dir == nullptr)
{
- _ERR("can not open directory : %s", directory);
+ _ERR("can not open directory : [%s]", directory);
return std::string();
}
assembly.append(directory);
assembly += PATH_SEPARATOR;
assembly.append(filename);
- _DBG("TPA : %s", assembly.c_str());
+ //_DBG("TPA : %s", assembly.c_str());
tpaList += assembly + ':';
}
}
static int RunLauncherDll(int argc, char* argv[])
{
- std::ifstream iniStream(LauncherConfig);
- std::stringstream iniString;
- iniString << iniStream.rdbuf();
- tini::ini launcherIni(iniString);
+ std::string coreclr_dir(RuntimeDirectory);
+ std::string libcoreclr(ConcatPath(coreclr_dir, "libcoreclr.so"));
+ std::string tpa_dirs(coreclr_dir + ":" + DeviceAPIDirectory);
+ std::string native_so_search_dirs(tpa_dirs);
+ std::string launcher_assembly(AbsolutePath(LauncherAssembly));
- _DBG("config file [%s]", LauncherConfig.c_str());
- _DBG("%s", launcherIni.to_string().c_str());
-
- auto &dotnet = launcherIni["dotnet"];
-
-#define DOTNET_FIND(key, defaultValue) \
- ((dotnet.find(key) == dotnet.end()) ? defaultValue : dotnet[key])
- std::string libcoreclr = DOTNET_FIND("libcoreclr", "libcoreclr.so");
- std::string coreclr_dir = DOTNET_FIND("coreclr_dir", "/opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0/");
- std::string tpa_dirs = DOTNET_FIND("tpa_dirs", coreclr_dir + ":" + "/usr/share/assembly");
- std::string native_so_search_dirs = DOTNET_FIND("native_so_search_dirs", tpa_dirs);
- std::string launcher_assembly = AbsolutePath(DOTNET_FIND("launcher_assembly", "/usr/bin/Tizen.Runtime.dll"));
-#undef DOTNET_FIND
+ if (launcher_assembly.empty())
+ {
+ _ERR("Invalid Launcher assembly path.");
+ return 1;
+ }
std::string launcher_dir = Basename(launcher_assembly);
std::string trusted_assemblies = launcher_assembly + ":";
_DBG("native_so_search_dir : %s", native_so_search_dirs.c_str());
_DBG("launcher_assembly : %s", launcher_assembly.c_str());
_DBG("launcher_dir : %s", launcher_dir.c_str());
- _DBG("-------------------------------------------------");
void *coreclrLib = dlopen(libcoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
if (coreclrLib == nullptr)
"UseLatestBehaviorWhenTFMNotSpecified"
};
- _DBG("trusted platform assemblies : %s", propertyValues[0]);
+ //_DBG("trusted platform assemblies : %s", propertyValues[0]);
_DBG("app_path : %s", propertyValues[1]);
_DBG("app_ni_path : %s", propertyValues[2]);
_DBG("native dll search path : %s", propertyValues[3]);
int main(int argc, char *argv[])
{
+#ifdef NO_TIZEN
+ const char *_deviceapi_directory = getenv("DeviceAPIDirectory");
+ const char *_runtime_directory = getenv("RuntimeDirectory");
+ const char *_launcher_assembly = getenv("LauncherAssembly");
+ if (_deviceapi_directory != nullptr)
+ DeviceAPIDirectory = _deviceapi_directory;
+ if (_runtime_directory != nullptr)
+ RuntimeDirectory = _runtime_directory;
+ if (_launcher_assembly != nullptr)
+ LauncherAssembly = _launcher_assembly;
+#endif
_DBG("launcher started");
return RunLauncherDll(argc, argv);
}
bool WaiterContext::Execute(const char *path, const char *app_root, int argc, char *argv[])
{
if (Step == Status::Requested && Executed != nullptr &&
- Executed(path, app_root, argc, argv, Data))
+ Executed(path, app_root, argc, argv, Data) == 0)
{
Step = Status::Executed;
return true;
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <OutputType>exe</OutputType>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <OutputType>exe</OutputType>
<AssemblyName>Tizen.Runtime</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug'">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
<OutputPath>bin/</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release'">
<Target Name="CheckConfig">
<Message Text="MSBuildProjectDirectory = $(MSBuildProjectDirectory)"/>
+ </Target>
+
+ <Import Project="$(MSBuildProjectDirectory)/Tizen.CoreFX.Ref.Targets" />
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Target Name="BeforeCompile">
<ItemGroup>
- <AssemblyAttributes Include="DefaultConfigAttribute" Condition=" $(LauncherConfigPath) != '' ">
- <_Parameter1>ConfigPath=$(LauncherConfigPath)</_Parameter1>
+ <AssemblyAttributes Include="DefaultConfigAttribute" Condition=" $(PreloadPath) != '' ">
+ <_Parameter1>PreloadPath=$(PreloadPath)</_Parameter1>
</AssemblyAttributes>
</ItemGroup>
<WriteCodeFragment AssemblyAttributes="@(AssemblyAttributes)"
Language="C#"
OutputDirectory="$(IntermediateOutputPath)"
- OutputFile="ConfigPath.cs">
+ OutputFile="Config.cs">
<Output TaskParameter="OutputFile" ItemName="Compile" />
</WriteCodeFragment>
</Target>
-
- <Import Project="$(MSBuildProjectDirectory)/Tizen.CoreFX.Ref.Targets" />
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
protected override Assembly Load(AssemblyName assemblyName)
{
- ALog.Debug($"Load DLL : {assemblyName.Name}");
Assembly asm = null;
try
{
- asm = Assembly.Load(assemblyName);
+ //asm = AssemblyLoadContext.Default.Load(assemblyName);
+ asm = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName);
}
catch (Exception ex)
when (ex is FileNotFoundException ||
ex is BadImageFormatException ||
ex is FileLoadException)
{
- ALog.Debug("Search DLL in added directories");
foreach (string dir in DllDirectories)
{
FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll"));
protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
{
- ALog.Debug($"Load Native : {unmanagedDllName}");
IntPtr native = base.LoadUnmanagedDll(unmanagedDllName);
if (native == IntPtr.Zero)
{
- ALog.Debug("Search native lib in added directories");
foreach (string dir in NativeDirectories)
{
FileInfo f = new FileInfo(Path.Combine(dir, unmanagedDllName));
{
try
{
- string configPath = "file:///etc/dotnet-launcher.ini";
+ string preloadPath = "";
ICustomAttributeProvider assembly = typeof(AssemblyManager).GetTypeInfo().Assembly;
var attributes = assembly.GetCustomAttributes(typeof(DefaultConfigAttribute), false);
- if (attributes.Length > 0 && attributes[0] is DefaultConfigAttribute)
+ foreach (DefaultConfigAttribute dca in attributes)
{
- DefaultConfigAttribute dca = (DefaultConfigAttribute)attributes[0];
- FileInfo f = new FileInfo(dca.Config["ConfigPath"]);
- if (File.Exists(f.FullName))
+ ALog.Debug($"{dca.Key} = {dca.Value}");
+ if (dca.Key == "PreloadPath")
{
- configPath = "file://"+f.FullName;
+ preloadPath = dca.Value;
}
}
- Ini ini = new Ini(new Uri(configPath));
- var dotnet = ini["dotnet"];
- foreach(var kv in dotnet)
- {
- ALog.Debug(kv.Key + " = " + kv.Value);
- }
-
- string preloadDlls = "";
- string preloadDllDirs = "";
- var preloads = ini["preloads"];
- if (preloads != null)
- {
- foreach (string key in preloads.Keys)
- {
- FileInfo f = new FileInfo(key);
- if (File.Exists(f.FullName))
- {
- preloadDlls += f.FullName + ":";
- preloadDllDirs += f.Directory + ":";
- }
- }
- }
-
- if (!Initialize(preloadDllDirs, preloadDlls))
+ if (!Initialize(preloadPath))
{
return 1;
}
{
try
{
- FileInfo f = new FileInfo(path);
- CurrentAssemblyLoaderContext.AddSearchableDirectory(f.Directory.FullName);
- DirectoryInfo d = new DirectoryInfo(app_root);
- CurrentAssemblyLoaderContext.AddSearchableDirectory(d.FullName);
- Execute(path);
+ DirectoryInfo libdir = new DirectoryInfo(Path.Combine(app_root, "lib"));
+ if (Directory.Exists(libdir.FullName))
+ {
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
+ }
+ Execute(path, argv);
}
catch(Exception e)
{
}
}
- public static bool Initialize(string searchableDirectories, string preloadDllPaths)
+ public static bool Initialize(string preloadDirectory)
{
try
{
CurrentAssemblyLoaderContext = new AssemblyLoader();
- if (searchableDirectories != null)
+ if (!string.IsNullOrEmpty(preloadDirectory))
{
- string[] dirs = searchableDirectories.Split(new char[]{':'}, StringSplitOptions.None);
- foreach (string dir in dirs)
+ Console.WriteLine($"[{preloadDirectory}]");
+ DirectoryInfo d = new DirectoryInfo(preloadDirectory);
+ if (Directory.Exists(d.FullName))
{
- CurrentAssemblyLoaderContext.AddSearchableDirectory(dir);
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(d.FullName);
+ string[] dlls = Directory.GetFiles(d.FullName, "*.dll");
+
+ foreach (string dll in dlls)
+ {
+ ALog.Debug($"preload dll : {dll}");
+ CurrentAssemblyLoaderContext.LoadFromAssemblyPath(dll);
+ }
}
}
- if (preloadDllPaths != null)
+ /*
+ string LD_LIBRARY_PATH = Environment.GetEnvironmentVariable("LD_LIBRARY_PATH");
+ if (!string.IsNullOrEmpty(LD_LIBRARY_PATH))
{
- string[] dllPaths = preloadDllPaths.Split(new char[]{':'}, StringSplitOptions.None);
- foreach (string dllPath in dllPaths)
+ string[] dirs = LD_LIBRARY_PATH.Split(new char[]{':'}, StringSplitOptions.None);
+ foreach (string dir in dirs)
{
- if (string.IsNullOrWhiteSpace(dllPath)) continue;
- FileInfo f = new FileInfo(dllPath);
- if (File.Exists(f.FullName))
+ DirectoryInfo d = new DirectoryInfo(dir);
+ if (Directory.Exists(d.FullName))
{
- CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName);
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(d.FullName);
}
}
}
+
+ DirectoryInfo libdir = new DirectoryInfo("/lib");
+ if (Directory.Exists(libdir.FullName))
+ {
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(libdir.FullName);
+ }
+
+ DirectoryInfo usrlibdir = new DirectoryInfo("/usr/lib");
+ if (Directory.Exists(usrlibdir.FullName))
+ {
+ CurrentAssemblyLoaderContext.AddSearchableDirectory(usrlibdir.FullName);
+ }
+ */
+
}
catch (Exception e)
{
return true;
}
- public static void Execute(string dllPath)
+ public static void Execute(string dllPath, string[] argv)
{
try
{
Assembly asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName);
if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found");
if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint");
- asm.EntryPoint.Invoke(null, new string[]{null});
+ asm.EntryPoint.Invoke(null, new object[]{argv});
}
}
catch (Exception e)
using System;
using System.Collections.Generic;
-[AttributeUsage(AttributeTargets.Assembly)]
+[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public class DefaultConfigAttribute : Attribute {
public DefaultConfigAttribute() : this(string.Empty) {}
public DefaultConfigAttribute(string txt)
{
- Config = new Dictionary<string, string>();
- string[] keyvalues = txt.Split(new string[] {","}, StringSplitOptions.None);
- foreach (string kvstr in keyvalues)
- {
- int eq_pos = kvstr.IndexOf('=');
- if (eq_pos == -1)
- throw new FormatException("Config must be written like \"Key1=Value1, Key2=Value2\"");
+ int eq_pos = txt.IndexOf('=');
+ if (eq_pos == -1)
+ throw new FormatException("Config must be written like \"Key1=Value1\"");
- string key = kvstr.Substring(0, eq_pos).Trim();
- string value = kvstr.Substring(eq_pos+1).Trim();
- Config[key] = value;
- }
- }
- public Dictionary<string, string> Config
- {
- get;
- set;
+ Key = txt.Substring(0, eq_pos).Trim();
+ Value = txt.Substring(eq_pos+1).Trim();
}
+
+ public string Key { get; private set; }
+ public string Value { get; private set; }
}
internal delegate int PreparedCallback(IntPtr userData);
internal delegate int RequestedCallback(IntPtr userData);
- internal delegate int ExecutedCallback(string path, string app_root, int argc, string[] argv, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate int ExecutedCallback(
+ [In] string path,
+ [In] string app_root,
+ [In] int argc,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)]
+ [In] string[] argv,
+ [In] IntPtr userData);
[DllImport(Launcher)]
internal static extern void register_launching_callback(
+%{!?dotnet_assembly_path: %define dotnet_assembly_path %{_datadir}/assembly}
+
Name: dotnet-launcher
Summary: Launchpad plugin for dotnet apps
Version: 0.0.2
%define _loaderdir %{_prefix}/share/aul
%define _configdir /etc
+%define _device_api_dir %{dotnet_assembly_path}
+%define _runtime_dir /opt/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0
+%define _preload_dir /opt/usr/share/dotnet.tizen/preload
%description
Launchpad plugin for launching dotnet apps
-DLOADERDIR=%{_loaderdir} \
-DCONFIGDIR=%{_configdir} \
-DCMAKE_BUILD_TYPE=%{_buildmode} \
+ -DDEVICE_API_DIR=%{_device_api_dir} \
+ -DRUNTIME_DIR=%{_runtime_dir} \
+ -DLAUNCHER_ASSEMBLY_PATH=%{_bindir}/Tizen.Runtime.exe \
-DVERSION=%{version} \
NativeLauncher
make %{?jobs:-j%jobs}
-xbuild /p:Configuration=%{_buildmode} Tizen.Runtime/Tizen.Runtime.csproj
+xbuild \
+ /p:Configuration=%{_buildmode} \
+ /p:PreloadPath=%{_preload_dir} \
+ Tizen.Runtime/Tizen.Runtime.csproj
%install
rm -rf %{buildroot}
%files
%manifest dotnet-launcher.manifest
-%config /etc/dotnet-launcher.ini
%{_loaderdir}/dotnet.loader
%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/dotnet-launcher
%caps(cap_mac_admin,cap_setgid=ei) %{_libdir}/libdnclauncher.so
#TizenDeviceAPIPath=`readlink -e ../dlls/tizen_deviceapis/`
CoreFXRefPath=`readlink -e ../dlls/desktop/`
TizenDeviceAPIPath=`readlink -e ../dlls/tizen_deviceapis/`
-LauncherConfigPath=./dotnet-launcher.ini
RoslynCscDir=/home/idkiller/work/runtime/roslyn/Binaries/Debug/csccore
RoslynCscExe=csc
+RuntimeDir=/usr/share/dotnet/shared/Microsoft.NETCore.App/1.0.0
+TizenDeviceAPIDir=`readlink -e ../dlls/tizen_deviceapis/`
+PreloadPath=`readlink -e ./preloads`
+
+
mkdir build
cd build
-cmake -DCMAKE_BUILD_TYPE=Debug -DNO_TIZEN=1 -DLAUNCHER_CONFIG_PATH=$LauncherConfigPath -DLAUNCHER_ASSEMBLY_PATH=Tizen.Runtime.dll ../NativeLauncher/
+cmake -DCMAKE_BUILD_TYPE=Debug -DNO_TIZEN=1 -DLAUNCHER_ASSEMBLY_PATH=Tizen.Runtime.exe -DDEVICE_API_DIR=$TizenDeviceAPIDir -DRUNTIME_DIR=$RuntimeDir ../NativeLauncher/
make
xbuild /t:Clean ../Tizen.Runtime/Tizen.Runtime.csproj
#xbuild /verbosity:diagnostic /p:CLOG=1 /p:ExternalCscPath=/home/idkiller/work/runtime/roslyn/Binaries/Debug/csccore/csc.exe /p:LauncherConfigPath=$LauncherConfigPath /p:CoreFXRefPath=$CoreFXRefPath /p:TizenDeviceAPIPath=$TizenDeviceAPIPath ../Tizen.Runtime/Tizen.Runtime.csproj
-xbuild /p:CLOG=1 /p:ExternalCscDir=$RoslynCscDir /p:ExternalCscExe=$RoslynCscExe /p:LauncherConfigPath=$LauncherConfigPath /p:CoreFXRefPath=$CoreFXRefPath /p:TizenDeviceAPIPath=$TizenDeviceAPIPath ../Tizen.Runtime/Tizen.Runtime.csproj
+xbuild /p:CLOG=1 /p:ExternalCscDir=$RoslynCscDir /p:ExternalCscExe=$RoslynCscExe /p:LauncherConfigPath=$LauncherConfigPath /p:CoreFXRefPath=$CoreFXRefPath /p:TizenDeviceAPIPath=$TizenDeviceAPIPath /p:PreloadPath=$PreloadPath ../Tizen.Runtime/Tizen.Runtime.csproj
cp ../Tizen.Runtime/bin/Tizen.Runtime.* .
-cp ../NativeLauncher/dotnet-launcher.ini .