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