Add nitool option to compile system libs with unique default base address
[platform/core/dotnet/launcher.git] / NativeLauncher / tool / nitool.cc
1 /*
2  * Copyright (c) 2016 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
20 #include <cstdio>
21 #include <cstring>
22
23 #include <algorithm>
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         return list;
34 }
35
36 static void help(const char *argv0)
37 {
38         const char* helpDesc =
39                 "Usage: %s [args] <root paths or pkg name>\n"
40                 "       --help              - Display this screen\n"
41                 "       --system            - Create NI under System DLLs\n"
42                 "       --dll               - Create NI for DLL\n"
43                 "       --pkg               - Create NI for package\n"
44                 "       --dir               - Create NI for directory\n"
45                 "       --r2r               - Use ready-to-run option (default: FNV)\n"
46                 "                             (This option should be used with other options)\n"
47                 "       --reset-system      - Remove System NI files\n"
48                 "       --reset-pkg         - Remove App NI files\n"
49                 "       --regen-all-app     - Re-generate All App NI files\n"
50 #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
51                 "       --gen-unique-baddr-system - Generate unique base addr for dll\n"
52 #endif
53                 "\n"
54                 "Example:\n"
55                 "1. Create native image for dlls and exes under platform directories\n"
56                 "   # %s --system\n"
57                 "2. Create native image for dll\n"
58                 "   # %s --dll /usr/bin/Tizen.Runtime.dll\n"
59                 "3. Create native image under the package's bin and lib directory\n"
60                 "   # %s --pkg org.tizen.FormsGallery\n"
61                 "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
62                 "   # %s --r2r --regen-all-app\n\n"
63 #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
64                 "5. Generate unique base addr for system dll\n"
65                 "   # %s --gen-unique-baddr-system --dll /usr/bin/Tizen.Runtime.dll\n\n"
66 #endif
67                 ;
68         printf(helpDesc, argv0, argv0, argv0, argv0, argv0, argv0);
69 }
70
71 int main(int argc, char* argv[])
72 {
73         bool pkgMode = false;
74         bool dllMode = false;
75         bool dirMode = false;
76         bool rmPkgMode = false;
77         bool enableR2R = false;
78         bool pkgDllMode = false;
79
80         bool doGenUniqueBaseSystem = false;
81
82         NiCommonOption option = {std::string(), std::string(), std::string()};
83         if (initNICommon(&option) != NI_ERROR_NONE) {
84                 fprintf(stderr, "Fail to initialize NI Common\n");
85                 return -1;
86         }
87
88         if (cmdOptionExists(argv, argv+argc, "--r2r")) {
89                 enableR2R = true;
90         }
91
92         if (cmdOptionExists(argv, argv+argc, "--gen-unique-baddr-system")) {
93 #ifdef UNIQUE_DEFAULT_BASE_ADDR_SUPPORT
94                 doGenUniqueBaseSystem = true;
95 #else
96                 fprintf(stderr, "--gen-unique-baddr-system is not supported\n");
97 #endif
98         }
99
100         if (cmdOptionExists(argv, argv+argc, "--help")) {
101                 help(argv[0]);
102                 return 0;
103         } else if (cmdOptionExists(argv, argv+argc, "--system")) {
104                 createNiPlatform(enableR2R, doGenUniqueBaseSystem);
105                 return 0;
106         } else if (cmdOptionExists(argv, argv+argc, "--dll")) {
107                 dllMode = true;
108         } else if (cmdOptionExists(argv, argv+argc, "--pkg")) {
109                 pkgMode = true;
110         } else if (cmdOptionExists(argv, argv+argc, "--dir")) {
111                 dirMode = true;
112         } else if (cmdOptionExists(argv, argv+argc, "--reset-system")) {
113                 removeNiPlatform();
114                 return 0;
115         } else if (cmdOptionExists(argv, argv+argc, "--reset-pkg")) {
116                 rmPkgMode = true;
117         } else if (cmdOptionExists(argv, argv+argc, "--regen-all-app")) {
118                 regenerateAppNI(enableR2R);
119                 return 0;
120         } else if (cmdOptionExists(argv, argv+argc, "--pkg-dll")) {
121                 pkgDllMode = true;
122         } else {
123                 help(argv[0]);
124                 return 0;
125         }
126
127         std::vector<std::string> args = getCmdArgs(argv, argv+argc);
128
129         if (args.size() < 1) {
130                 if (pkgMode)
131                         fprintf(stderr, "Package name is missed\n");
132                 else if (dllMode)
133                         fprintf(stderr, "DLL path is missed\n");
134                 help(argv[0]);
135                 return 1;
136         }
137
138         if (pkgMode) {
139                 for (const std::string pkg : args) {
140                         // if there is AOTed dlls under package root, that is skiped.
141                         int ret = createNiUnderPkgRoot(pkg, enableR2R);
142                         if (ret == NI_ERROR_INVALID_PACKAGE) {
143                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
144                                 return -1;
145                         } else if (ret != NI_ERROR_NONE) {
146                                 fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
147                                 return -1;
148                         }
149                 }
150         } else if (pkgDllMode) {
151                 int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
152                 if (ret == NI_ERROR_INVALID_PACKAGE) {
153                         fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
154                         return -1;
155                 } else if (ret == NI_ERROR_ALREADY_EXIST) {
156                         // skip for already exist case
157                         return -1;
158                 } else if (ret != NI_ERROR_NONE) {
159                         fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
160                         return -1;
161                 }
162         } else if (rmPkgMode) {
163                 for (const std::string pkg : args) {
164                         int ret = removeNiUnderPkgRoot(pkg);
165                         if (ret == NI_ERROR_INVALID_PACKAGE) {
166                                 fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
167                                 return -1;
168                         } else if (ret != NI_ERROR_NONE) {
169                                 fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
170                                 return -1;
171                         }
172                 }
173         } else if (dllMode) {
174                 // donot return error code for generation failure.
175                 // we have to run crossgen for all input dlls.
176                 for (const std::string dll : args) {
177                         int ret = createNiDll(dll, enableR2R, doGenUniqueBaseSystem);
178                         if (ret == NI_ERROR_ALREADY_EXIST) {
179                                 // skip for already exist case
180                         } else if (ret != NI_ERROR_NONE) {
181                                 fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
182                         }
183                 }
184         } else if (dirMode) {
185                 createNiUnderDirs(args.data(), args.size(), enableR2R, doGenUniqueBaseSystem);
186         }
187
188         return 0;
189 }