Add missing header
[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 <vector>
22 #include <cstring>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <sys/time.h>
26
27 void DisplayUsage() {
28         fprintf(stdout,
29                 "\n"
30                 "Dotnet Tool Version: 1.0\n"
31                 "\n"
32                 "Commands:\n"
33                 "       -h, --help                - Show this help message\n"
34                 "       --ni-system               - Create NI under System DLLs\n"
35                 "       --ni-dll                  - Create NI for DLL\n"
36                 "       --ni-pkg                  - Create NI for package\n"
37                 "       --ni-dir                  - Create NI for directory\n"
38                 "       --ni-reset-system         - Remove System NI files\n"
39                 "       --ni-reset-pkg            - Remove App NI files\n"
40                 "       --ni-reset-dir            - Remove NI for directory\n"
41                 "       --ni-regen-all-app        - Re-generate All App NI files\n"
42                 "       --tac-regen-all           - Re-generate All TAC files\n"
43                 "       --tac-restore-db          - Restore TAC Database\n"
44                 "       --tac-disable-pkg         - Disable TAC for package\n"
45                 "       --tac-enable-pkg          - Enable TAC for package\n"
46                 "       --ibc-dir                 - Specify a directory containing IBC files\n"
47                 "\n"
48                 "Options:\n"
49                 "       --r2r                     - Generate a Ready-To-Run image (disable: /FragileNonVersionable)\n"
50                 "       --compatibility           - Compatibility mode for older versions of crossgen\n"
51                 "                                   (replaces /r with /Trusted_Platform_Assemblies)\n"
52                 "       --verbose                 - Display verbose information\n"
53                 "       --instrument              - Generate an instrumented image for profiling (enable: /Tuning)\n"
54                 "\n"
55                 "Usage: dotnettool [options] [command] [arguments]\n"
56                 "\n"
57                 "Example:\n"
58                 "1. Create native image for dlls and exes under platform directories\n"
59                 "   # dotnettool --ni-system\n"
60                 "2. Create native image for dll\n"
61                 "   # dotnettool --ni-dll /usr/bin/Tizen.Runtime.dll\n"
62                 "3. Create native image under the package's bin and lib directory\n"
63                 "   # dotnettool --ni-pkg org.tizen.FormsGallery\n"
64                 "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
65                 "   # dotnettool --r2r --ni-regen-all-app\n"
66                 "5. Create native image for dll based on the IBC data\n"
67                 "   # dotnettool --ibc-dir /tmp/ibcdata/ --ni-dll /usr/bin/Tizen.Runtime.dll\n"
68                 "\n");
69 }
70
71 int main(int argc, char* argv[])
72 {
73         argc--;
74         argv++;
75
76         long starttime;
77         long endtime;
78         struct timeval tv;
79         gettimeofday(&tv, NULL);
80         starttime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
81
82         if (argc <= 0) {
83                 DisplayUsage();
84                 return -1;
85         }
86
87         //sh-3.2# dotnettool --[r2r|compatibility|instrument|verbose]
88         DWORD flags = 0;
89         std::vector<std::string> args;
90         for (char** it = argv; it != argv+argc; it++) {
91                 if (!strncmp(*it, "-?", 2) || !strncmp(*it, "-h", 2) || !strncmp(*it, "--help", 6)) {
92                         DisplayUsage();
93                         return 0;
94                 } else if (!strncmp(*it, "--r2r", 5)) {
95                         flags |= NI_FLAGS_ENABLER2R;
96                 } else if (!strncmp(*it, "--compatibility", 15)) {
97                         flags |= NI_FLAGS_COMPATIBILITY;
98                 } else if (!strncmp(*it, "--instrument", 12)) {
99                         flags |= NI_FLAGS_INSTRUMENT;
100                 } else if (!strncmp(*it, "--verbose", 9)) {
101                         flags |= NI_FLAGS_VERBOSE;
102                 } else {
103                         args.push_back(*it);
104                 }
105         }
106
107         //sh-3.2# dotnettool --ibc-dir [ibcDirectory]
108         for (auto it = args.begin(); it != args.end(); ) {
109                 if (*it == "--ibc-dir") {
110                         it = args.erase(it);
111
112                         std::string ibcFilePath = std::string(*it);
113                         if (!isDirectory(ibcFilePath)) {
114                                 fprintf(stderr, "IBC path is missing or not exist\n");
115                                 return -1;
116                         }
117
118                         setenv("COMPlus_IBCFileDir", const_cast<char *>(ibcFilePath.c_str()), 1);
119                         setenv("COMPlus_UseIBCFile", const_cast<char *>("1"), 1);
120                         it = args.erase(it);
121                 } else {
122                         ++it;
123                 }
124         }
125
126         if (initNICommon() != NI_ERROR_NONE) {
127                 return -1;
128         }
129
130         std::vector<std::string>::iterator it = args.begin();
131         std::string cmd = std::string(*it);
132         it = args.erase(it);
133
134         //sh-3.2# dotnettool --ni-system
135         if (cmd == "--ni-system") {
136                 int ret = createNIPlatform(flags);
137                 if (ret != NI_ERROR_NONE) {
138                         fprintf(stderr, "Failed to generate system NI\n");
139                 }
140         }
141         //sh-3.2# dotnettool --ni-dll [assemblyPath] [assemblyPath] ...
142         else if (cmd == "--ni-dll") {
143                 if (args.size() < 1) {
144                         fprintf(stderr, "DLL path is missing\n");
145                 }
146                 while (it != args.end()) {
147                         std::string dll = std::string(*it);
148                         int ret = createNIDll(dll, flags);
149                         if (ret != NI_ERROR_NONE) {
150                                 fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
151                                 break;
152                         }
153                         it = args.erase(it);
154                 }
155         }
156         //sh-3.2# dotnettool --ni-pkg [pkgId] [pkgId] ...
157         else if (cmd == "--ni-pkg") {
158                 if (args.size() < 1) {
159                         fprintf(stderr, "Package name is missing\n");
160                 }
161                 while (it != args.end()) {
162                         std::string pkg = std::string(*it);
163                         // if there is AOTed dlls under package root, that is skiped.
164                         int ret = createNIUnderPkgRoot(pkg, flags);
165                         if (ret != NI_ERROR_NONE) {
166                                 fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
167                                 break;
168                         }
169                         it = args.erase(it);
170                 }
171         }
172         //sh-3.2# dotnettool --ni-dir [AssemblyDirectory] [AssemblyDirectory] ...
173         else if (cmd == "--ni-dir") {
174                 if (args.size() < 1) {
175                         fprintf(stderr, "Directory path is missing\n");
176                 }
177                 while (it != args.end()) {
178                         const std::string dir = std::string(*it);
179                         int ret = createNIUnderDirs(dir, flags);
180                         if (ret != NI_ERROR_NONE) {
181                                 fprintf(stderr, "Failed to generate NI directory\n");
182                                 break;
183                         }
184                         it = args.erase(it);
185                 }
186         }
187         //sh-3.2# dotnettool --ni-reset-system
188         else if (cmd == "--ni-reset-system") {
189                 removeNIPlatform();
190         }
191         //sh-3.2# dotnettool --ni-reset-pkg [pkgId] [pkgId] ...
192         else if (cmd == "--ni-reset-pkg") {
193                 if (args.size() < 1) {
194                         fprintf(stderr, "Package name is missing\n");
195                 }
196                 while (it != args.end()) {
197                         std::string pkg = std::string(*it);
198                         int ret = removeNIUnderPkgRoot(pkg);
199                         if (ret != NI_ERROR_NONE) {
200                                 fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
201                                 break;
202                         }
203                         it = args.erase(it);
204                 }
205         }
206         //sh-3.2# dotnettool --ni-reset-dir [AssemblyDirectory] [AssemblyDirectory] ...
207         else if (cmd == "--ni-reset-dir") {
208                 if (args.size() < 1) {
209                         fprintf(stderr, "Directory path is missing\n");
210                 }
211                 while (it != args.end()) {
212                         const std::string dir = std::string(*it);
213                         removeNIUnderDirs(dir);
214                         it = args.erase(it);
215                 }
216         }
217         //sh-3.2# dotnettool --ni-regen-all-app
218         else if (cmd == "--ni-regen-all-app") {
219                 int ret = regenerateAppNI(flags);
220                 if (ret != NI_ERROR_NONE) {
221                         fprintf(stderr, "Failed to regenerate all app NI\n");
222                 }
223         }
224         //sh-3.2# dotnettool --tac-regen-all
225         else if (cmd == "--tac-regen-all") {
226                 int ret = regenerateTACNI(flags);
227                 if (ret != NI_ERROR_NONE) {
228                         fprintf(stderr, "Failed to regenerate all TAC\n");
229                 }
230         }
231         //sh-3.2# dotnettool --tac-restore-db
232         else if (cmd == "--tac-restore-db") {
233                 int ret = tac_restoreDB();
234                 if (ret != TAC_ERROR_NONE) {
235                         fprintf(stderr, "Failed to restore TAC db\n");
236                 }
237                 ret = tlc_restoreDB();
238                 if (ret != TAC_ERROR_NONE) {
239                         fprintf(stderr, "Failed to restore TLC db\n");
240                 }
241         }
242         //sh-3.2# dotnettool --tac-enable-pkg [pkgId] [pkgId] ...
243         else if (cmd == "--tac-enable-pkg") {
244                 if (args.size() < 1) {
245                         fprintf(stderr, "Package name is missing\n");
246                 }
247                 while (it != args.end()) {
248                         std::string pkg = std::string(*it);
249                         int ret = enableTACPackage(pkg);
250                         if (ret != TAC_ERROR_NONE) {
251                                 fprintf(stderr, "Failed to enable tac [%s]\n", pkg.c_str());
252                                 break;
253                         }
254                         it = args.erase(it);
255                 }
256         }
257         //sh-3.2# dotnettool --tac-disable-pkg [pkgId] [pkgId] ...
258         else if (cmd == "--tac-disable-pkg") {
259                 if (args.size() < 1) {
260                         fprintf(stderr, "Package name is missing\n");
261                 }
262                 while (it != args.end()) {
263                         std::string pkg = std::string(*it);
264                         int ret = disableTACPackage(pkg);
265                         if (ret != TAC_ERROR_NONE) {
266                                 fprintf(stderr, "Failed to disable tac [%s]\n", pkg.c_str());
267                                 break;
268                         }
269                         it = args.erase(it);
270                 }
271         }
272         else {
273                 fprintf(stderr, "Unknown option [%s]\n", cmd.c_str());
274                 DisplayUsage();
275         }
276
277         finalizeNICommon();
278
279         gettimeofday(&tv, NULL);
280         endtime = tv.tv_sec * 1000l + tv.tv_usec / 1000l;
281         fprintf(stdout, "\nSpend time for dotnettool is [%d]ms\n", (int)(endtime - starttime));
282
283         return 0;
284 }