Add '--ni-reset-dir' option of dotnettool
[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
21 #include <algorithm>
22 #include <cstdio>
23 #include <cstring>
24 #include <vector>
25
26 std::vector<std::string> getCmdArgs(char** begin, char** end)
27 {
28         std::vector<std::string> list;
29         for (char** itr = begin+1; itr != end; itr++) {
30                 if (strncmp(*itr, "--", 2) != 0) {
31                         list.push_back(*itr);
32                 }
33         }
34         return list;
35 }
36
37 static void help(const char *argv0)
38 {
39         const char* helpDesc =
40                 "Usage: %s [OPTIONS] COMMAND <paths or pkg name>\n"
41                 "\n"
42                 "Commands:\n"
43                 "       --help                 - Display this screen\n"
44                 "       --ni-system            - Create NI under System DLLs\n"
45                 "       --ni-dll               - Create NI for DLL\n"
46                 "       --ni-pkg               - Create NI for package\n"
47                 "       --ni-pkg-dll           - Create NI for DLL in package\n"
48                 "       --ni-dir               - Create NI for directory\n"
49                 "       --ni-reset-system      - Remove System NI files\n"
50                 "       --ni-reset-pkg         - Remove App NI files\n"
51                 "       --ni-reset-dir         - Remove NI for directory\n"
52                 "       --ni-regen-all-app     - Re-generate All App NI files\n"
53                 "       --tac-regen-all        - Re-generate All TAC files\n"
54                 "       --tac-restore-db       - Restore TAC Database\n"
55                 "       --tac-disable-pkg      - Disable TAC for package\n"
56                 "       --tac-enable-pkg       - Enable TAC for package\n"
57                 "\n"
58                 "Options:\n"
59                 "       --r2r                  - Generate a Ready-To-Run image (disables /FragileNonVersionable)\n"
60                 "       --compatibility        - Compatibility mode for older versions of crossgen\n"
61                 "                                (replaces /r with /Trusted_Platform_Assemblies)\n"
62                 "       --verbose              - Display verbose information\n"
63                 "       --instrument           - Generate an instrumented image for profiling (enables /Tuning)\n"
64                 "\n"
65                 "Example:\n"
66                 "1. Create native image for dlls and exes under platform directories\n"
67                 "   # %s --ni-system\n"
68                 "2. Create native image for dll\n"
69                 "   # %s --ni-dll /usr/bin/Tizen.Runtime.dll\n"
70                 "3. Create native image under the package's bin and lib directory\n"
71                 "   # %s --ni-pkg org.tizen.FormsGallery\n"
72                 "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
73                 "   # %s --r2r --ni-regen-all-app\n\n";
74         printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
75 }
76
77 int main(int argc, char* argv[])
78 {
79         DWORD flags = 0;
80         bool pkgMode = false;
81         bool dllMode = false;
82         bool dirMode = false;
83         bool rmPkgMode = false;
84         bool rmDirMode = false;
85         bool pkgDllMode = false;
86         bool disableTacMode = false;
87         bool enableTacMode = false;
88
89         NiCommonOption option = {std::string(), std::string(), std::string()};
90         if (initNICommon(&option) != NI_ERROR_NONE) {
91                 return -1;
92         }
93
94         // Parse optional switches first.
95         if (cmdOptionExists(argv, argv+argc, "--r2r")) {
96                 flags |= NI_FLAGS_ENABLER2R;
97         }
98         if (cmdOptionExists(argv, argv+argc, "--compatibility")) {
99                 flags |= NI_FLAGS_COMPATIBILITY;
100         }
101         if (cmdOptionExists(argv, argv+argc, "--instrument")) {
102                 flags |= NI_FLAGS_INSTRUMENT;
103         }
104         if (cmdOptionExists(argv, argv+argc, "--verbose")) {
105                 flags |= NI_FLAGS_VERBOSE;
106         }
107
108         // The following commands are mutually exclusive.
109         if (cmdOptionExists(argv, argv+argc, "--help")) {
110                 help(argv[0]);
111                 return 0;
112         } else if (cmdOptionExists(argv, argv+argc, "--ni-system")) {
113                 createNiPlatform(flags);
114                 return 0;
115         } else if (cmdOptionExists(argv, argv+argc, "--ni-dll")) {
116                 dllMode = true;
117         } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg")) {
118                 pkgMode = true;
119         } else if (cmdOptionExists(argv, argv+argc, "--ni-dir")) {
120                 dirMode = true;
121         } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-system")) {
122                 removeNiPlatform();
123                 return 0;
124         } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-pkg")) {
125                 rmPkgMode = true;
126         } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-dir")) {
127                 rmDirMode = true;
128         } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg-dll")) {
129                 pkgDllMode = true;
130         } else if (cmdOptionExists(argv, argv+argc, "--ni-regen-all-app")) {
131                 regenerateAppNI(flags);
132                 return 0;
133         } else if (cmdOptionExists(argv, argv+argc, "--tac-regen-all")) {
134                 regenerateTACNI(flags);
135                 return 0;
136         } else if (cmdOptionExists(argv, argv+argc, "--tac-restore-db")) {
137                 restoreTACDB();
138                 return 0;
139         } else if (cmdOptionExists(argv, argv+argc, "--tac-disable-pkg")) {
140                 disableTacMode = true;
141         } else if (cmdOptionExists(argv, argv+argc, "--tac-enable-pkg")) {
142                 enableTacMode = true;
143         } else {
144                 help(argv[0]);
145                 return 0;
146         }
147
148         std::vector<std::string> args = getCmdArgs(argv, argv+argc);
149
150         if (args.size() < 1) {
151                 if (pkgMode || rmPkgMode || disableTacMode || enableTacMode) {
152                         fprintf(stderr, "Package name is missed\n");
153                 } else if (dllMode) {
154                         fprintf(stderr, "DLL path is missing.\n");
155                 } else if (rmDirMode) {
156                         fprintf(stderr, "Directory path is missing.\n");
157                 }
158                 help(argv[0]);
159                 return -1;
160         } else if (args.size() < 2) {
161                 if (pkgDllMode) {
162                         fprintf(stderr, "Package name or DLL path is missing.\n");
163                         help(argv[0]);
164                         return -1;
165                 }
166         }
167
168         if (pkgMode) {
169                 for (const std::string pkg : args) {
170                         // if there is AOTed dlls under package root, that is skiped.
171                         int ret = createNiUnderPkgRoot(pkg, flags);
172                         if (ret == NI_ERROR_INVALID_PACKAGE) {
173                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
174                                 return -1;
175                         } else if (ret != NI_ERROR_NONE) {
176                                 fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
177                                 return -1;
178                         }
179                         ret = createTACPkgRoot(pkg, flags);
180                         if (ret == TAC_ERROR_INVALID_PACKAGE) {
181                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
182                                 return -1;
183                         } else if (ret != TAC_ERROR_NONE) {
184                                 fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkg.c_str());
185                                 return -1;
186                         }
187                 }
188         } else if (pkgDllMode) {
189                 int ret = createNiDllUnderPkgRoot(args[0], args[1], flags);
190                 if (ret == NI_ERROR_INVALID_PACKAGE) {
191                         fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
192                         return -1;
193                 } else if (ret == NI_ERROR_ALREADY_EXIST) {
194                         // skip for already exist case
195                         return -1;
196                 } else if (ret != NI_ERROR_NONE) {
197                         fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
198                         return -1;
199                 }
200         } else if (rmPkgMode) {
201                 for (const std::string pkg : args) {
202                         int ret = removeNiUnderPkgRoot(pkg);
203                         if (ret == NI_ERROR_INVALID_PACKAGE) {
204                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
205                                 return -1;
206                         } else if (ret != NI_ERROR_NONE) {
207                                 fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
208                                 return -1;
209                         }
210                         ret = resetTACPackage(pkg);
211                         if (ret == TAC_ERROR_INVALID_PACKAGE) {
212                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
213                                 return -1;
214                         } else if (ret != TAC_ERROR_NONE) {
215                                 fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkg.c_str());
216                                 return -1;
217                         }
218                 }
219         } else if (rmDirMode) {
220                 removeNiUnderDirs(args.data(), args.size());
221         } else if (dllMode) {
222                 // donot return error code for generation failure.
223                 // we have to run crossgen for all input dlls.
224                 for (const std::string dll : args) {
225                         int ret = createNiDll(dll, flags);
226                         if (ret == NI_ERROR_ALREADY_EXIST) {
227                                 // skip for already exist case
228                         } else if (ret != NI_ERROR_NONE) {
229                                 fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
230                         }
231                 }
232         } else if (dirMode) {
233                 createNiUnderDirs(args.data(), args.size(), flags);
234         } else if (disableTacMode) {
235                 for (const std::string pkg : args) {
236                         int ret = disableTACPackage(pkg);
237                         if (ret == TAC_ERROR_INVALID_PACKAGE) {
238                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
239                                 return -1;
240                         } else if (ret != TAC_ERROR_NONE) {
241                                 fprintf(stderr, "Failed to disable tac [%s]\n", pkg.c_str());
242                                 return -1;
243                         }
244                 }
245         } else if (enableTacMode) {
246                 for (const std::string pkg : args) {
247                         int ret = enableTACPackage(pkg);
248                         if (ret == TAC_ERROR_INVALID_PACKAGE) {
249                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
250                                 return -1;
251                         } else if (ret != TAC_ERROR_NONE) {
252                                 fprintf(stderr, "Failed to enable tac [%s]\n", pkg.c_str());
253                                 return -1;
254                         }
255                 }
256         }
257         return 0;
258 }