2 * Copyright (c) 2019 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.
18 #include "ni_common.h"
19 #include "tac_common.h"
20 #include "profile_common.h"
21 #include "privilege_common.h"
22 #include "multi_target_resolver.h"
30 #include <app_common.h>
35 "Dotnet Tool Version: 1.0\n"
38 " -h, --help - Show this help message\n"
39 " --ni-system - Create NI under System DLLs\n"
40 " --ni-dll - Create NI for DLL\n"
41 " --ni-pkg - Create NI for package\n"
42 " (If package is installed under RO area, NI files are generated under RW area)\n"
43 " --ni-dir - Create NI for directory\n"
44 " --ni-reset-system - Remove System NI files\n"
45 " --ni-reset-pkg - Remove App NI files\n"
46 " --ni-reset-dir - Remove NI for directory\n"
47 " --ni-regen-all-app - Re-generate All App NI files\n"
48 " --tac-regen-all - Re-generate All TAC files\n"
49 " --tac-restore-db - Restore TAC Database\n"
50 " --tac-disable-pkg - Disable TAC for package\n"
51 " --tac-enable-pkg - Enable TAC for package\n"
52 " --resolve-all-app - Remove unused multi-targeting files of all apps\n"
53 " (this option is used for FOTA script or test)\n"
54 " --rm-app-profile - Remove application profile of given packages for all users\n"
55 " (this option should be run as root)\n"
56 " --rm-all-app-profile - Remove application profile of all packages for all users\n"
57 " (this option should be run as root)\n"
58 " --check-all-app-privilege - Chcek application privilege of all package\n"
59 " (this option should be run as root)\n"
62 " --mibc - Specify Mibc files. Sepatated with ':'.\n"
63 " --verbose - Display verbose information\n"
64 " --inputbubble - Compile input assemblies into one bubble with the assemblies described at --inputbubbleref option\n"
65 " Note!: If you do not have an accurate understanding of Bubble, do not use this option.\n"
66 " All assemblies in the bubble must be guaranteed to be compiled to the native image before execution.\n"
67 " If an uncompiled assembly is included in the bubble during execution, an unknown error may occur.\n"
68 " If --inputbubbleref option doesnot be set, only input files are included to bubble. \n"
69 " --inputbubbleref - Input bubble reference file(s) to be added to bubble (used with --inputbubble option)\n"
70 " --ref - Reference file(s) for compilation\n"
71 " (system paths are set automatically.)\n"
72 " --no-pipeline - Compile the dlls individually\n"
73 " --print-cmd - Print command and options\n"
74 " --skip-ro-app - Skip re-generate NI for apps installed RO area\n"
75 " (This option works with --ni-regen-all-app only)\n"
76 " --rm-origin-after-ni - Remove original dll after creating native image\n"
77 " Note!: App ATOC options(--ni-pkg, --ni-regen-all-app, --tac-regen-all) cannot be used with --rm-origin-after-ni option.\n"
78 " (Use only for assemblies that will not be AOTed again afterward.)\n"
79 " --set-priority - Sets the priority of the process to the specified values from -20(highest priority) to 19(lowest priority).(default : 0)\n"
82 "Usage: dotnettool [options] [command] [arguments]\n"
85 "1. Create native image for dlls and exes under platform directories\n"
86 " # dotnettool --ni-system\n"
87 "2. Create native image for dll\n"
88 " # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
89 "3. Create native image under the package's bin and lib directory\n"
90 " # dotnettool --ni-pkg org.tizen.FormsGallery\n"
91 "4. Regenerate native images for all installed .net packages\n"
92 " # dotnettool --ni-regen-all-app\n"
93 "5. Create native image for dll based on the Mibc data\n"
94 " # dotnettool --mibc /tmp/ibcdata/in.mibc --ni-dll /usr/bin/Tizen.Runtime.dll\n"
95 "6. Remove profile for package\n"
96 " # dotnettool --rm-app-profile org.tizen.FormsGallery\n"
100 int main(int argc, char* argv[])
108 gettimeofday(&tv, NULL);
109 starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
116 NIOption* opt = getNIOption();
117 if (opt == nullptr) {
118 _SERR("Fail to create option structure.");
122 std::vector<std::string> args;
123 for (int i = 0; i < argc; ++i) {
124 std::string arg = argv[i];
126 if ((arg == "-?") || (arg == "-h") || (arg == "--h")) {
129 } else if (arg == "--verbose") {
130 opt->flags |= NI_FLAGS_VERBOSE;
131 } else if (arg == "--inputbubble") {
132 opt->flags |= NI_FLAGS_INPUT_BUBBLE;
133 } else if (arg == "--no-pipeline") {
134 opt->flags |= NI_FLAGS_NO_PIPELINE;
135 } else if (arg == "--print-cmd") {
136 opt->flags |= NI_FLAGS_PRINT_CMD;
137 } else if (arg == "--skip-ro-app") {
138 opt->flags |= NI_FLAGS_SKIP_RO_APP;
139 } else if (arg == "--rm-origin-after-ni") {
140 opt->flags |= NI_FLAGS_RM_ORIGIN_AFTER_NI;
141 } else if (arg == "--set-priority") {
144 _SOUT("Priority value(-20 ~ 19) should be followed for --set-priority option");
149 opt->flags |= NI_FLAGS_SET_PRIORITY;
151 opt->priority = std::stoi(argv[i]);
154 _SERR("Invalid argument: %s", argv[i]);
158 } else if (arg == "--mibc") {
161 _SOUT("File path containing Mibc files should be followed for --mibc option");
166 opt->flags |= NI_FLAGS_MIBC;
168 std::vector<std::string> paths;
169 splitPath(std::string(argv[i]), paths);
170 for (const auto &path : paths) {
171 if (!isFile(path) || isDirectory(path)) {
172 _SERR("Mibc file path is missing or does not exist");
175 opt->mibcPath.push_back(path);
177 } else if (arg == "--inputbubbleref") {
180 _SOUT("Path for references should be followed for --inputbubbleref option");
185 opt->flags |= NI_FLAGS_INPUT_BUBBLE_REF;
187 std::vector<std::string> files;
188 splitPath(std::string(argv[i]), files);
189 for (const auto &f : files) {
190 opt->inputBubbleRefFiles.push_back(f);
192 } else if (arg == "--ref") {
195 _SOUT("Path for references should be followed for --ref option");
200 std::vector<std::string> files;
201 splitPath(std::string(argv[i]), files);
202 for (const auto &f : files) {
203 opt->refFiles.push_back(f);
210 if (args.size() == 0) {
211 _SERR("The command is missing");
216 if (opt->flags & NI_FLAGS_INPUT_BUBBLE_REF && !(opt->flags & NI_FLAGS_INPUT_BUBBLE)) {
217 _SERR("--inputbubbleref option should be used with --inputbubble option");
222 if (initNICommon() != NI_ERROR_NONE) {
226 std::vector<std::string>::iterator it = args.begin();
227 std::string cmd = std::string(*it);
230 //sh-3.2# dotnettool --ni-system [AssemblyDirectory] [AssemblyDirectory] ...
231 if (cmd == "--ni-system") {
233 while (it != args.end()) {
234 const std::string dir = std::string(*it);
235 inputs = inputs + ":" + dir;
238 int ret = createNIPlatform(inputs, opt);
239 if (ret != NI_ERROR_NONE) {
240 _SERR("Failed to generate system NI");
243 //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
244 else if (cmd == "--ni-dll") {
245 if (args.size() < 1) {
246 _SERR("DLL path is missing");
248 std::vector<std::string> inputs;
249 while (it != args.end()) {
250 std::string dll = std::string(*it);
251 inputs.push_back(dll);
252 opt->refFiles.push_back(dll);
253 if (opt->flags & NI_FLAGS_INPUT_BUBBLE) {
254 opt->inputBubbleRefFiles.push_back(dll);
259 for (auto &dll : inputs) {
260 int ret = createNIDll(dll, opt);
261 if (ret != NI_ERROR_NONE && ret != NI_ERROR_ALREADY_EXIST) {
262 _SERR("Failed to generate NI file [%s]", dll.c_str());
267 //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
268 else if (cmd == "--ni-pkg") {
269 if (opt->flags & NI_FLAGS_RM_ORIGIN_AFTER_NI) {
270 _SERR("App AOTC options cannot be used with --rm-origin-after-ni option");
275 if (args.size() < 1) {
276 _SERR("Package name is missing");
278 while (it != args.end()) {
279 std::string pkg = std::string(*it);
280 int ret = createNIUnderPkgRoot(pkg, opt);
281 if (ret != NI_ERROR_NONE) {
282 _SERR("Failed to generate app NI [%s]", pkg.c_str());
288 //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
289 else if (cmd == "--ni-dir") {
290 if (args.size() < 1) {
291 _SERR("Directory path is missing");
294 while (it != args.end()) {
296 dir += std::string(":");
298 dir += std::string(*it);
301 if (createNIUnderDirs(dir, opt) != NI_ERROR_NONE) {
302 _SERR("Failed to generate NI directory");
305 //sh-3.2# dotnettool --ni-reset-system
306 else if (cmd == "--ni-reset-system") {
309 //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
310 else if (cmd == "--ni-reset-pkg") {
311 if (args.size() < 1) {
312 _SERR("Package name is missing");
314 while (it != args.end()) {
315 std::string pkg = std::string(*it);
316 int ret = removeNIUnderPkgRoot(pkg);
317 if (ret != NI_ERROR_NONE) {
318 _SERR("Failed to remove dlls for given package [%s]", pkg.c_str());
324 //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
325 else if (cmd == "--ni-reset-dir") {
326 if (args.size() < 1) {
327 _SERR("Directory path is missing");
329 while (it != args.end()) {
330 const std::string dir = std::string(*it);
331 removeNIUnderDirs(dir);
335 //sh-3.2# dotnettool --ni-regen-all-app
336 else if (cmd == "--ni-regen-all-app") {
337 if (opt->flags & NI_FLAGS_RM_ORIGIN_AFTER_NI) {
338 _SERR("App AOTC options cannot be used with --rm-origin-after-ni option");
343 int ret = regeneratePkgNI(opt);
344 if (ret != NI_ERROR_NONE) {
345 _SERR("Failed to regenerate all app NI");
348 //sh-3.2# dotnettool --tac-regen-all
349 else if (cmd == "--tac-regen-all") {
350 if (opt->flags & NI_FLAGS_RM_ORIGIN_AFTER_NI) {
351 _SERR("App AOTC options cannot be used with --rm-origin-after-ni option");
356 int ret = regenerateTACNI(opt);
357 if (ret != NI_ERROR_NONE) {
358 _SERR("Failed to regenerate all TAC");
361 //sh-3.2# dotnettool --tac-restore-db
362 else if (cmd == "--tac-restore-db") {
363 int ret = tac_restoreDB();
364 if (ret != TAC_ERROR_NONE) {
365 _SERR("Failed to restore TAC db");
367 ret = tlc_restoreDB();
368 if (ret != TAC_ERROR_NONE) {
369 _SERR("Failed to restore TLC db");
372 //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
373 else if (cmd == "--tac-enable-pkg") {
374 if (args.size() < 1) {
375 _SERR("Package name is missing");
377 while (it != args.end()) {
378 std::string pkg = std::string(*it);
379 int ret = enableTACPackage(pkg);
380 if (ret != TAC_ERROR_NONE) {
381 _SERR("Failed to enable tac [%s]", pkg.c_str());
387 //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
388 else if (cmd == "--tac-disable-pkg") {
389 if (args.size() < 1) {
390 _SERR("Package name is missing");
392 while (it != args.end()) {
393 std::string pkg = std::string(*it);
394 int ret = disableTACPackage(pkg);
395 if (ret != TAC_ERROR_NONE) {
396 _SERR("Failed to disable tac [%s]", pkg.c_str());
402 //sh-3.2# dotnettool --resolve-all-app
403 else if (cmd == "--resolve-all-app") {
406 //sh-3.2# dotnettool --rm-app-profile [pkgId] [pkgId] ...
407 else if (cmd == "--rm-app-profile") {
408 if (args.size() < 1) {
409 _SERR("Package name is missing");
411 while (it != args.end()) {
412 std::string pkg = std::string(*it);
413 if (removeAppProfileData(pkg) != PROFILE_ERROR_NONE) {
414 _SERR("Failed to remove [%s] profile data", pkg.c_str());
419 //sh-3.2# dotnettool --rm-all-app-profile
420 else if (cmd == "--rm-all-app-profile") {
421 removeAllAppProfileData();
423 //sh-3.2# dotnettool --check-all-app-privilege
424 else if (cmd == "--check-all-app-privilege") {
425 checkAllAppPrivilege();
428 _SERR("Unknown option [%s]", cmd.c_str());
434 gettimeofday(&tv, NULL);
435 endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
436 int ms = (int)(endtime - starttime);
437 float sec = (float)(ms/1000);
438 _SOUT("\nSpend time for dotnettool is [%d]ms, [%.3f]sec", ms, sec);