Change update size for PBA (#419)
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / dotnettool.cc
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "utils.h"
18 #include "ni_common.h"
19 #include "tac_common.h"
20 #include "multi_target_resolver.h"
21 #include "log.h"
22
23 #include <vector>
24 #include <cstring>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <sys/time.h>
28 #include <app_common.h>
29
30 void DisplayUsage() {
31         _SOUT(
32                 "\n"
33                 "Dotnet Tool Version: 1.0\n"
34                 "\n"
35                 "Commands:\n"
36                 "       -h, --help                - Show this help message\n"
37                 "       --ni-system               - Create NI under System DLLs\n"
38                 "       --ni-dll                  - Create NI for DLL\n"
39                 "       --ni-pkg                  - Create NI for package\n"
40                 "                                   (If package is installed under RO area, NI files are generated under RW area)\n"
41                 "       --ni-dir                  - Create NI for directory\n"
42                 "       --ni-reset-system         - Remove System NI files\n"
43                 "       --ni-reset-pkg            - Remove App NI files\n"
44                 "       --ni-reset-dir            - Remove NI for directory\n"
45                 "       --ni-regen-all-app        - Re-generate All App NI files\n"
46                 "       --tac-regen-all           - Re-generate All TAC files\n"
47                 "       --tac-restore-db          - Restore TAC Database\n"
48                 "       --tac-disable-pkg         - Disable TAC for package\n"
49                 "       --tac-enable-pkg          - Enable TAC for package\n"
50                 "       --resolve-all-app         - Remove unused multi-targeting files of all apps\n"
51                 "                                   (this option is used for FOTA script or test)\n"
52                 "       --rm-app-profile          - Remove application profile of given packages for all users\n"
53                 "                                   (this option should be run as root)\n"
54                 "       --rm-all-app-profile      - Remove application profile of all packages for all users\n"
55                 "                                   (this option should be run as root)\n"
56                 "\n"
57                 "Options:\n"
58                 "       --mibc                    - Specify Mibc files. Sepatated with ':'.\n"
59                 "       --verbose                 - Display verbose information\n"
60                 "       --inputbubble             - Use inputbubble\n"
61                 "       --inputbubbleref          - Path of references for inputbubble (used with --inputbubble option)\n"
62                 "                                   (If not set, all references are included to inputbubble.)\n"
63                 "       --ref                     - Path of references\n"
64                 "                                   (If not set, default system paths are used.)\n"
65                 "       --no-pipeline             - Compile the dlls individually\n"
66                 "       --print-cmd               - Print command and options\n"
67                 "       --skip-ro-app             - Skip re-generate NI for apps installed RO area\n"
68                 "                                   (This option works with --ni-regen-all-app only)\n"
69                 "\n"
70                 "Usage: dotnettool [options] [command] [arguments]\n"
71                 "\n"
72                 "Example:\n"
73                 "1. Create native image for dlls and exes under platform directories\n"
74                 "   # dotnettool --ni-system\n"
75                 "2. Create native image for dll\n"
76                 "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
77                 "3. Create native image under the package's bin and lib directory\n"
78                 "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
79                 "4. Regenerate native images for all installed .net packages\n"
80                 "   # dotnettool --ni-regen-all-app\n"
81                 "5. Create native image for dll based on the Mibc data\n"
82                 "   # dotnettool --mibc /tmp/ibcdata/in.mibc --ni-dll /usr/bin/Tizen.Runtime.dll\n"
83                 "6. Remove profile for package\n"
84                 "   # dotnettool --rm-app-profile org.tizen.FormsGallery\n"
85                 "\n");
86 }
87
88 int main(int argc, char* argv[])
89 {
90         argc--;
91         argv++;
92
93         long starttime;
94         long endtime;
95         struct timeval tv;
96         gettimeofday(&tv, NULL);
97         starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
98
99         if (argc <= 0) {
100                 DisplayUsage();
101                 return -1;
102         }
103
104         NIOption* opt = getNIOption();
105         if (opt == nullptr) {
106                 _SERR("Fail to create option structure.");
107                 return -1;
108         }
109
110         std::vector<std::string> args;
111         for (int i = 0; i < argc; ++i) {
112                 std::string arg = argv[i];
113
114                 if ((arg == "-?") || (arg == "-h") || (arg == "--h")) {
115                         DisplayUsage();
116                         return 0;
117                 } else if (arg == "--verbose") {
118                         opt->flags |= NI_FLAGS_VERBOSE;
119                 } else if (arg == "--inputbubble") {
120                         opt->flags |= NI_FLAGS_INPUT_BUBBLE;
121                 } else if (arg == "--no-pipeline") {
122                         opt->flags |= NI_FLAGS_NO_PIPELINE;
123                 } else if (arg == "--print-cmd") {
124                         opt->flags |= NI_FLAGS_PRINT_CMD;
125                 } else if (arg == "--skip-ro-app") {
126                         opt->flags |= NI_FLAGS_SKIP_RO_APP;
127                 } else if (arg == "--mibc") {
128                         ++i;
129                         if (i >= argc) {
130                                 _SOUT("File path containing Mibc files should be followed for --mibc option");
131                                 DisplayUsage();
132                                 return 0;
133                         }
134
135                         opt->flags |= NI_FLAGS_MIBC;
136
137                         std::vector<std::string> paths;
138                         splitPath(std::string(argv[i]), paths);
139                         for (const auto &path : paths) {
140                                 if (!isFile(path) || isDirectory(path)) {
141                                         _SERR("Mibc file path is missing or does not exist");
142                                         return -1;
143                                 }
144                                 opt->mibcPath.push_back(path);
145                         }
146                 } else if (arg == "--inputbubbleref") {
147                         ++i;
148                         if (i >= argc) {
149                                 _SOUT("Path for references should be followed for --inputbubbleref option");
150                                 DisplayUsage();
151                                 return 0;
152                         }
153
154                         opt->flags |= NI_FLAGS_INPUT_BUBBLE_REF;
155
156                         std::vector<std::string> paths;
157                         splitPath(std::string(argv[i]), paths);
158                         for (const auto &path : paths) {
159                                 if (!isDirectory(path)) {
160                                         _SERR("intpubbubbleref path is missing or not exist");
161                                         return -1;
162                                 }
163                                 opt->inputBubbleRefPath.push_back(path);
164                         }
165                 } else if (arg == "--ref") {
166                         ++i;
167                         if (i >= argc) {
168                                 _SOUT("Path for references should be followed for --ref option");
169                                 DisplayUsage();
170                                 return 0;
171                         }
172
173                         opt->flags |= NI_FLAGS_REF;
174
175                         std::vector<std::string> paths;
176                         splitPath(std::string(argv[i]), paths);
177                         for (const auto &path : paths) {
178                                 if (!isDirectory(path)) {
179                                         _SERR("ref path is missing or not exist");
180                                         return -1;
181                                 }
182                                 opt->refPath.push_back(path);
183                         }
184                 } else {
185                         args.push_back(arg);
186                 }
187         }
188
189         if (opt->flags & NI_FLAGS_INPUT_BUBBLE_REF && !(opt->flags & NI_FLAGS_INPUT_BUBBLE)) {
190                 _SERR("--inputbubbleref option should be used with --inputbubble option");
191                 DisplayUsage();
192                 return -1;
193         }
194
195         if (initNICommon() != NI_ERROR_NONE) {
196                 return -1;
197         }
198
199         std::vector<std::string>::iterator it = args.begin();
200         std::string cmd = std::string(*it);
201         it = args.erase(it);
202
203         //sh-3.2# dotnettool --ni-system
204         if (cmd == "--ni-system") {
205                 int ret = createNIPlatform(opt);
206                 if (ret != NI_ERROR_NONE) {
207                         _SERR("Failed to generate system NI");
208                 }
209         }
210         //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
211         else if (cmd == "--ni-dll") {
212                 if (args.size() < 1) {
213                         _SERR("DLL path is missing");
214                 }
215                 while (it != args.end()) {
216                         std::string dll = std::string(*it);
217                         int ret = createNIDll(dll, opt);
218                         if (ret != NI_ERROR_NONE && ret != NI_ERROR_ALREADY_EXIST) {
219                                 _SERR("Failed to generate NI file [%s]", dll.c_str());
220                                 break;
221                         }
222                         it = args.erase(it);
223                 }
224         }
225         //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
226         else if (cmd == "--ni-pkg") {
227                 if (args.size() < 1) {
228                         _SERR("Package name is missing");
229                 }
230                 while (it != args.end()) {
231                         std::string pkg = std::string(*it);
232                         int ret = createNIUnderPkgRoot(pkg, opt);
233                         if (ret != NI_ERROR_NONE) {
234                                 _SERR("Failed to generate app NI [%s]", pkg.c_str());
235                                 break;
236                         }
237                         it = args.erase(it);
238                 }
239         }
240         //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
241         else if (cmd == "--ni-dir") {
242                 if (args.size() < 1) {
243                         _SERR("Directory path is missing");
244                 }
245                 while (it != args.end()) {
246                         const std::string dir = std::string(*it);
247                         int ret = createNIUnderDirs(dir, opt);
248                         if (ret != NI_ERROR_NONE) {
249                                 _SERR("Failed to generate NI directory");
250                                 break;
251                         }
252                         it = args.erase(it);
253                 }
254         }
255         //sh-3.2# dotnettool --ni-reset-system
256         else if (cmd == "--ni-reset-system") {
257                 removeNIPlatform();
258         }
259         //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
260         else if (cmd == "--ni-reset-pkg") {
261                 if (args.size() < 1) {
262                         _SERR("Package name is missing");
263                 }
264                 while (it != args.end()) {
265                         std::string pkg = std::string(*it);
266                         int ret = removeNIUnderPkgRoot(pkg);
267                         if (ret != NI_ERROR_NONE) {
268                                 _SERR("Failed to remove dlls for given package [%s]", pkg.c_str());
269                                 break;
270                         }
271                         it = args.erase(it);
272                 }
273         }
274         //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
275         else if (cmd == "--ni-reset-dir") {
276                 if (args.size() < 1) {
277                         _SERR("Directory path is missing");
278                 }
279                 while (it != args.end()) {
280                         const std::string dir = std::string(*it);
281                         removeNIUnderDirs(dir);
282                         it = args.erase(it);
283                 }
284         }
285         //sh-3.2# dotnettool --ni-regen-all-app
286         else if (cmd == "--ni-regen-all-app") {
287                 int ret = regenerateAppNI(opt);
288                 if (ret != NI_ERROR_NONE) {
289                         _SERR("Failed to regenerate all app NI");
290                 }
291         }
292         //sh-3.2# dotnettool --tac-regen-all
293         else if (cmd == "--tac-regen-all") {
294                 int ret = regenerateTACNI(opt);
295                 if (ret != NI_ERROR_NONE) {
296                         _SERR("Failed to regenerate all TAC");
297                 }
298         }
299         //sh-3.2# dotnettool --tac-restore-db
300         else if (cmd == "--tac-restore-db") {
301                 int ret = tac_restoreDB();
302                 if (ret != TAC_ERROR_NONE) {
303                         _SERR("Failed to restore TAC db");
304                 }
305                 ret = tlc_restoreDB();
306                 if (ret != TAC_ERROR_NONE) {
307                         _SERR("Failed to restore TLC db");
308                 }
309         }
310         //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
311         else if (cmd == "--tac-enable-pkg") {
312                 if (args.size() < 1) {
313                         _SERR("Package name is missing");
314                 }
315                 while (it != args.end()) {
316                         std::string pkg = std::string(*it);
317                         int ret = enableTACPackage(pkg);
318                         if (ret != TAC_ERROR_NONE) {
319                                 _SERR("Failed to enable tac [%s]", pkg.c_str());
320                                 break;
321                         }
322                         it = args.erase(it);
323                 }
324         }
325         //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
326         else if (cmd == "--tac-disable-pkg") {
327                 if (args.size() < 1) {
328                         _SERR("Package name is missing");
329                 }
330                 while (it != args.end()) {
331                         std::string pkg = std::string(*it);
332                         int ret = disableTACPackage(pkg);
333                         if (ret != TAC_ERROR_NONE) {
334                                 _SERR("Failed to disable tac [%s]", pkg.c_str());
335                                 break;
336                         }
337                         it = args.erase(it);
338                 }
339         }
340         //sh-3.2# dotnettool --resolve-all-app
341         else if (cmd == "--resolve-all-app") {
342                 int ret = resolveAllApps();
343                 if (ret != 0) {
344                         _SERR("Failed to remove unused multi-targeting files");
345                 }
346         }
347         //sh-3.2# dotnettool --rm-app-profile [pkgId] [pkgId] ...
348         else if (cmd == "--rm-app-profile") {
349                 if (args.size() < 1) {
350                         _SERR("Package name is missing");
351                 }
352                 while (it != args.end()) {
353                         std::string pkg = std::string(*it);
354                         if (removeAppProfileData(pkg) != NI_ERROR_NONE) {
355                                 _SERR("Failed to remove [%s] profile data", pkg.c_str());
356                         }
357                         it = args.erase(it);
358                 }
359         }
360         //sh-3.2# dotnettool --rm-all-app-profile
361         else if (cmd == "--rm-all-app-profile") {
362                 removeAllAppProfileData();
363         }
364         else {
365                 _SERR("Unknown option [%s]", cmd.c_str());
366                 DisplayUsage();
367         }
368
369         finalizeNICommon();
370
371         gettimeofday(&tv, NULL);
372         endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
373         _SOUT("\nSpend time for dotnettool is [%d]ms", (int)(endtime - starttime));
374
375         return 0;
376 }