1 /*
2 * Copyright (C) 2017 The Android Open Source Project
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 "dex2oat_options.h"
18
19 #include <memory>
20
21 #include "cmdline_parser.h"
22 #include "driver/compiler_options_map-inl.h"
23
24 namespace art {
25
26 template<>
27 struct CmdlineType<InstructionSet> : CmdlineTypeParser<InstructionSet> {
Parseart::CmdlineType28 Result Parse(const std::string& option) {
29 InstructionSet set = GetInstructionSetFromString(option.c_str());
30 if (set == InstructionSet::kNone) {
31 return Result::Failure(std::string("Not a valid instruction set: '") + option + "'");
32 }
33 return Result::Success(set);
34 }
35
Nameart::CmdlineType36 static const char* Name() { return "InstructionSet"; }
37 };
38
39 #define COMPILER_OPTIONS_MAP_TYPE Dex2oatArgumentMap
40 #define COMPILER_OPTIONS_MAP_KEY_TYPE Dex2oatArgumentMapKey
41 #include "driver/compiler_options_map-storage.h"
42
43 // Specify storage for the Dex2oatOptions keys.
44
45 #define DEX2OAT_OPTIONS_KEY(Type, Name, ...) \
46 const Dex2oatArgumentMap::Key<Type> Dex2oatArgumentMap::Name {__VA_ARGS__};
47 #include "dex2oat_options.def"
48
49 #pragma GCC diagnostic push
50 #pragma GCC diagnostic ignored "-Wframe-larger-than="
51
52 using M = Dex2oatArgumentMap;
53 using Parser = CmdlineParser<Dex2oatArgumentMap, Dex2oatArgumentMap::Key>;
54 using Builder = Parser::Builder;
55
AddInputMappings(Builder & builder)56 static void AddInputMappings(Builder& builder) {
57 builder.
58 Define("--dex-file=_")
59 .WithType<std::vector<std::string>>().AppendValues()
60 .IntoKey(M::DexFiles)
61 .Define("--dex-location=_")
62 .WithType<std::vector<std::string>>().AppendValues()
63 .IntoKey(M::DexLocations)
64 .Define("--zip-fd=_")
65 .WithType<int>()
66 .IntoKey(M::ZipFd)
67 .Define("--zip-location=_")
68 .WithType<std::string>()
69 .IntoKey(M::ZipLocation)
70 .Define("--boot-image=_")
71 .WithType<std::string>()
72 .IntoKey(M::BootImage);
73 }
74
AddGeneratedArtifactMappings(Builder & builder)75 static void AddGeneratedArtifactMappings(Builder& builder) {
76 builder.
77 Define("--input-vdex-fd=_")
78 .WithType<int>()
79 .IntoKey(M::InputVdexFd)
80 .Define("--input-vdex=_")
81 .WithType<std::string>()
82 .IntoKey(M::InputVdex)
83 .Define("--output-vdex-fd=_")
84 .WithType<int>()
85 .IntoKey(M::OutputVdexFd)
86 .Define("--output-vdex=_")
87 .WithType<std::string>()
88 .IntoKey(M::OutputVdex)
89 .Define("--dm-fd=_")
90 .WithType<int>()
91 .IntoKey(M::DmFd)
92 .Define("--dm-file=_")
93 .WithType<std::string>()
94 .IntoKey(M::DmFile)
95 .Define("--oat-file=_")
96 .WithType<std::vector<std::string>>().AppendValues()
97 .IntoKey(M::OatFiles)
98 .Define("--oat-symbols=_")
99 .WithType<std::vector<std::string>>().AppendValues()
100 .IntoKey(M::OatSymbols)
101 .Define("--strip")
102 .IntoKey(M::Strip)
103 .Define("--oat-fd=_")
104 .WithType<int>()
105 .IntoKey(M::OatFd)
106 .Define("--oat-location=_")
107 .WithType<std::string>()
108 .IntoKey(M::OatLocation);
109 }
110
AddImageMappings(Builder & builder)111 static void AddImageMappings(Builder& builder) {
112 builder.
113 Define("--image=_")
114 .WithType<std::vector<std::string>>().AppendValues()
115 .IntoKey(M::ImageFilenames)
116 .Define("--image-classes=_")
117 .WithType<std::string>()
118 .IntoKey(M::ImageClasses)
119 .Define("--image-classes-zip=_")
120 .WithType<std::string>()
121 .IntoKey(M::ImageClassesZip)
122 .Define("--base=_")
123 .WithType<std::string>()
124 .IntoKey(M::Base)
125 .Define("--app-image-file=_")
126 .WithType<std::string>()
127 .IntoKey(M::AppImageFile)
128 .Define("--app-image-fd=_")
129 .WithType<int>()
130 .IntoKey(M::AppImageFileFd)
131 .Define("--multi-image")
132 .IntoKey(M::MultiImage)
133 .Define("--dirty-image-objects=_")
134 .WithType<std::string>()
135 .IntoKey(M::DirtyImageObjects)
136 .Define("--image-format=_")
137 .WithType<ImageHeader::StorageMode>()
138 .WithValueMap({{"lz4", ImageHeader::kStorageModeLZ4},
139 {"lz4hc", ImageHeader::kStorageModeLZ4HC},
140 {"uncompressed", ImageHeader::kStorageModeUncompressed}})
141 .IntoKey(M::ImageFormat);
142 }
143
AddSwapMappings(Builder & builder)144 static void AddSwapMappings(Builder& builder) {
145 builder.
146 Define("--swap-file=_")
147 .WithType<std::string>()
148 .IntoKey(M::SwapFile)
149 .Define("--swap-fd=_")
150 .WithType<int>()
151 .IntoKey(M::SwapFileFd)
152 .Define("--swap-dex-size-threshold=_")
153 .WithType<unsigned int>()
154 .IntoKey(M::SwapDexSizeThreshold)
155 .Define("--swap-dex-count-threshold=_")
156 .WithType<unsigned int>()
157 .IntoKey(M::SwapDexCountThreshold);
158 }
159
AddCompilerMappings(Builder & builder)160 static void AddCompilerMappings(Builder& builder) {
161 builder.
162 Define("--run-passes=_")
163 .WithType<std::string>()
164 .IntoKey(M::Passes)
165 .Define("--profile-file=_")
166 .WithType<std::string>()
167 .IntoKey(M::Profile)
168 .Define("--profile-file-fd=_")
169 .WithType<int>()
170 .IntoKey(M::ProfileFd)
171 .Define("--no-inline-from=_")
172 .WithType<std::string>()
173 .IntoKey(M::NoInlineFrom);
174 }
175
AddTargetMappings(Builder & builder)176 static void AddTargetMappings(Builder& builder) {
177 builder.
178 Define("--instruction-set=_")
179 .WithType<InstructionSet>()
180 .IntoKey(M::TargetInstructionSet)
181 .Define("--instruction-set-variant=_")
182 .WithType<std::string>()
183 .IntoKey(M::TargetInstructionSetVariant)
184 .Define("--instruction-set-features=_")
185 .WithType<std::string>()
186 .IntoKey(M::TargetInstructionSetFeatures);
187 }
188
CreateArgumentParser()189 static Parser CreateArgumentParser() {
190 std::unique_ptr<Builder> parser_builder = std::make_unique<Builder>();
191
192 AddInputMappings(*parser_builder);
193 AddGeneratedArtifactMappings(*parser_builder);
194 AddImageMappings(*parser_builder);
195 AddSwapMappings(*parser_builder);
196 AddCompilerMappings(*parser_builder);
197 AddTargetMappings(*parser_builder);
198
199 parser_builder->
200 Define({"--watch-dog", "--no-watch-dog"})
201 .WithValues({true, false})
202 .IntoKey(M::Watchdog)
203 .Define("--watchdog-timeout=_")
204 .WithType<int>()
205 .IntoKey(M::WatchdogTimeout)
206 .Define("-j_")
207 .WithType<unsigned int>()
208 .IntoKey(M::Threads)
209 .Define("--android-root=_")
210 .WithType<std::string>()
211 .IntoKey(M::AndroidRoot)
212 .Define("--compiler-backend=_")
213 .WithType<Compiler::Kind>()
214 .WithValueMap({{"Quick", Compiler::Kind::kQuick},
215 {"Optimizing", Compiler::Kind::kOptimizing}})
216 .IntoKey(M::Backend)
217 .Define("--host")
218 .IntoKey(M::Host)
219 .Define("--avoid-storing-invocation")
220 .IntoKey(M::AvoidStoringInvocation)
221 .Define("--very-large-app-threshold=_")
222 .WithType<unsigned int>()
223 .IntoKey(M::VeryLargeAppThreshold)
224 .Define("--force-determinism")
225 .IntoKey(M::ForceDeterminism)
226 .Define("--copy-dex-files=_")
227 .WithType<linker::CopyOption>()
228 .WithValueMap({{"true", linker::CopyOption::kOnlyIfCompressed},
229 {"false", linker::CopyOption::kNever},
230 {"always", linker::CopyOption::kAlways}})
231 .IntoKey(M::CopyDexFiles)
232 .Define("--write-invocation-to=_")
233 .WithType<std::string>()
234 .IntoKey(M::InvocationFile)
235 .Define("--classpath-dir=_")
236 .WithType<std::string>()
237 .IntoKey(M::ClasspathDir)
238 .Define("--class-loader-context=_")
239 .WithType<std::string>()
240 .IntoKey(M::ClassLoaderContext)
241 .Define("--class-loader-context-fds=_")
242 .WithType<std::string>()
243 .IntoKey(M::ClassLoaderContextFds)
244 .Define("--stored-class-loader-context=_")
245 .WithType<std::string>()
246 .IntoKey(M::StoredClassLoaderContext)
247 .Define("--compact-dex-level=_")
248 .WithType<CompactDexLevel>()
249 .WithValueMap({{"none", CompactDexLevel::kCompactDexLevelNone},
250 {"fast", CompactDexLevel::kCompactDexLevelFast}})
251 .IntoKey(M::CompactDexLevel)
252 .Define("--runtime-arg _")
253 .WithType<std::vector<std::string>>().AppendValues()
254 .IntoKey(M::RuntimeOptions)
255 .Define("--compilation-reason=_")
256 .WithType<std::string>()
257 .IntoKey(M::CompilationReason);
258
259 AddCompilerOptionsArgumentParserOptions<Dex2oatArgumentMap>(*parser_builder);
260
261 parser_builder->IgnoreUnrecognized(false);
262
263 return parser_builder->Build();
264 }
265
Parse(int argc,const char ** argv,std::string * error_msg)266 std::unique_ptr<Dex2oatArgumentMap> Dex2oatArgumentMap::Parse(int argc,
267 const char** argv,
268 std::string* error_msg) {
269 Parser parser = CreateArgumentParser();
270 CmdlineResult parse_result = parser.Parse(argv, argc);
271 if (!parse_result.IsSuccess()) {
272 *error_msg = parse_result.GetMessage();
273 return nullptr;
274 }
275
276 return std::make_unique<Dex2oatArgumentMap>(parser.ReleaseArgumentsMap());
277 }
278
279 #pragma GCC diagnostic pop
280 } // namespace art
281