2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <pkgmgr-info.h>
24 #include "multi_target_resolver.h"
26 static const char* __TIZEN_RID_VERSION_KEY = "db/dotnet/tizen_rid_version";
27 static const char* __TIZEN_TFM_SUPPORT_KEY = "db/dotnet/tizen_tfm_support";
28 static const char* __DOTNET_RUNTIME_VERSION_KEY = "db/dotnet/runtime_version";
29 static std::vector<std::string> platform_version_list;
32 ---------|---------------------|-----------------------
33 1 | tizen.X.Y.Z-{arch} | netX.Y-tizenX.Y ~ 6.5
34 2 | tizen.X.Y.Z | netX.Y-tizen
35 3 | tizen-{arch}, tizen | netX.Y
36 4 | linux-{arch}, linux | tizen90 ~ 40
37 5 | unix-{arch}, unix | net5.0
38 6 | any | netcoreapp3.1 ~ 1.0
39 7 | base | netstandard2.1 ~ 1.0
42 static int convertStrVersionToInt(const std::string& version)
45 for (unsigned int i = 0; i < version.length(); i++) {
46 if (std::isdigit(int(version[i]))) {
47 ret = ret * 10 + (int(version[i]) - '0');
53 static std::vector<std::string> getRidFallbackGraph()
55 std::vector<std::string> RID_FALLBACK_GRAPH;
56 char* tizen_rid_version = vconf_get_str(__TIZEN_RID_VERSION_KEY);
57 if (tizen_rid_version) {
58 std::vector<std::string> rid_version;
59 splitPath(tizen_rid_version, rid_version);
60 std::reverse(std::begin(rid_version), std::end(rid_version));
61 for (auto& ridVersion : rid_version) {
62 //.NET 6.0 is supported from Tizen 6.5.0
63 if (convertStrVersionToInt(ridVersion) >= 650) {
64 platform_version_list.push_back(ridVersion.substr(0, ridVersion.rfind('.')));
66 RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion + "-" + ARCHITECTURE_IDENTIFIER));
67 RID_FALLBACK_GRAPH.push_back(std::string("tizen." + ridVersion));
69 free(tizen_rid_version);
72 std::vector<std::string> RID_FALLBACK_OS = {"tizen", "linux", "unix"};
73 for (auto& os : RID_FALLBACK_OS) {
74 RID_FALLBACK_GRAPH.push_back(std::string(os + "-" + ARCHITECTURE_IDENTIFIER));
75 RID_FALLBACK_GRAPH.push_back(std::string(os));
77 RID_FALLBACK_GRAPH.push_back("any");
78 RID_FALLBACK_GRAPH.push_back("base");
80 return RID_FALLBACK_GRAPH;
83 static std::vector<std::string> getTfmFallbackGraph()
85 std::vector<std::string> tfm_list;
86 char* dotnet_runtime_version = vconf_get_str(__DOTNET_RUNTIME_VERSION_KEY);
87 if (dotnet_runtime_version) {
88 std::vector<std::string> dotnet_version;
89 splitPath(dotnet_runtime_version, dotnet_version);
90 for (auto& dotnetVersion : dotnet_version) {
91 dotnetVersion = dotnetVersion.substr(0, dotnetVersion.rfind('.'));
92 for (auto& platformVersion : platform_version_list) {
93 tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen" + platformVersion));
95 tfm_list.push_back(std::string("net" + dotnetVersion + "-tizen"));
96 tfm_list.push_back(std::string("net" + dotnetVersion));
98 free(dotnet_runtime_version);
101 char* tizen_tfm = vconf_get_str(__TIZEN_TFM_SUPPORT_KEY);
103 splitPath(tizen_tfm, tfm_list);
106 tfm_list.push_back("net5.0");
108 std::vector<std::string> netcoreapp_version = {"3.1", "3.0", "2.2", "2.1", "2.0", "1.1", "1.0"};
109 for (auto& version : netcoreapp_version) {
110 tfm_list.push_back(std::string("netcoreapp" + version));
112 std::vector<std::string> netstandard_version = {"2.1", "2.0", "1.6", "1.5", "1.4", "1.3", "1.2", "1.1", "1.0"};
113 for (auto& version : netstandard_version) {
114 tfm_list.push_back(std::string("netstandard" + version));
120 // move all files under a certain directory to another directory
121 // ownership / permission / smack label are not changed
122 static bool moveAllFilesTo(const std::string& from, const std::string& to)
124 std::vector<std::string> files;
126 // make file list to move
127 for (auto& path : bf::recursive_directory_iterator(from)) {
128 std::string filePath = path.path().string();
129 if (isFile(filePath)) {
130 files.push_back(filePath);
134 // move files to target directory
135 for (auto& f : files) {
136 bf::rename(f, concatPath(to, getFileName(f)));
138 } catch (const bf::filesystem_error& error) {
139 _ERR("Failed to iterate directory: %s", error.what());
146 int resolvePlatformSpecificFiles(const std::string& rootPath)
148 std::string appBinPath = concatPath(rootPath, "bin");
149 std::string runtimesPath = concatPath(appBinPath, "runtimes");
151 // if runtimes directory doesnot exist, return 0
152 if (!isDirectory(runtimesPath)) {
156 // found best matched rid and tfm directory and copy all files to bin directory
157 std::vector<std::string> ridFallbackGraph = getRidFallbackGraph();
158 for (auto& rid : ridFallbackGraph) {
159 std::string ridPath = concatPath(runtimesPath, rid);
160 if (isDirectory(ridPath)) {
161 _INFO("Found best matched rid (%s)", rid.c_str());
162 // copy all files from /runtimes/${rid}/native to appBintPath if exist
163 std::string nativePath = concatPath(ridPath, "native");
164 if (isDirectory(nativePath)) {
165 _INFO("Found best matched native path");
166 if (!moveAllFilesTo(nativePath, appBinPath)) {
167 _ERR("Failed to copy files from native path");
172 // found best matched tfm folder in the found rid folder
173 std::string libPath = concatPath(ridPath, "lib");
174 std::vector<std::string> tfmFallbackGraph = getTfmFallbackGraph();
175 for (auto& tfm : tfmFallbackGraph) {
176 std::string tfmPath = concatPath(libPath, tfm);
177 if (isDirectory(tfmPath)) {
178 _INFO("Found best matched tfm (%s)", tfm .c_str());
179 // copy all files from tfmPath to appBintPath
180 if (!moveAllFilesTo(tfmPath, appBinPath)) {
181 _ERR("Failed to copy files from tfm path");
191 // remove runtimes directory
192 if (!removeAll(runtimesPath)) {
193 _ERR("Failed to remove bin/runtimes directory");
200 // callback function of "pkgmgrinfo_appinfo_filter_foreach_appinfo"
201 static int appResolveCb(pkgmgrinfo_appinfo_h handle, void *user_data)
206 ret = pkgmgrinfo_appinfo_get_root_path(handle, &rootPath);
207 if (ret != PMINFO_R_OK) {
208 _SERR("Failed to get root path");
212 if (resolvePlatformSpecificFiles(rootPath) != 0) {
213 _SERR("Failed to resolve platform specific resources (%s)", rootPath);
224 pkgmgrinfo_appinfo_filter_h handle;
225 ret = pkgmgrinfo_appinfo_filter_create(&handle);
226 if (ret != PMINFO_R_OK) {
230 ret = pkgmgrinfo_appinfo_filter_add_string(handle, PMINFO_APPINFO_PROP_APP_TYPE, "dotnet");
231 if (ret != PMINFO_R_OK) {
232 pkgmgrinfo_appinfo_filter_destroy(handle);
236 ret = pkgmgrinfo_appinfo_filter_foreach_appinfo(handle, appResolveCb, NULL);
237 if (ret != PMINFO_R_OK) {
238 pkgmgrinfo_appinfo_filter_destroy(handle);
241 pkgmgrinfo_appinfo_filter_destroy(handle);