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::string>()
97 .IntoKey(M::OatFile)
98 .Define("--oat-symbols=_")
99 .WithType<std::string>()
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::string>()
115 .IntoKey(M::ImageFilename)
116 .Define("--image-fd=_")
117 .WithType<int>()
118 .IntoKey(M::ImageFd)
119 .Define("--base=_")
120 .WithType<std::string>()
121 .IntoKey(M::Base)
122 .Define("--app-image-file=_")
123 .WithType<std::string>()
124 .IntoKey(M::AppImageFile)
125 .Define("--app-image-fd=_")
126 .WithType<int>()
127 .IntoKey(M::AppImageFileFd)
128 .Define({"--multi-image", "--single-image"})
129 .WithValues({true, false})
130 .IntoKey(M::MultiImage)
131 .Define("--dirty-image-objects=_")
132 .WithType<std::string>()
133 .IntoKey(M::DirtyImageObjects)
134 .Define("--updatable-bcp-packages-file=_")
135 .WithType<std::string>()
136 .IntoKey(M::UpdatableBcpPackagesFile)
137 .Define("--image-format=_")
138 .WithType<ImageHeader::StorageMode>()
139 .WithValueMap({{"lz4", ImageHeader::kStorageModeLZ4},
140 {"lz4hc", ImageHeader::kStorageModeLZ4HC},
141 {"uncompressed", ImageHeader::kStorageModeUncompressed}})
142 .IntoKey(M::ImageFormat);
143 }
144
AddSwapMappings(Builder & builder)145 static void AddSwapMappings(Builder& builder) {
146 builder.
147 Define("--swap-file=_")
148 .WithType<std::string>()
149 .IntoKey(M::SwapFile)
150 .Define("--swap-fd=_")
151 .WithType<int>()
152 .IntoKey(M::SwapFileFd)
153 .Define("--swap-dex-size-threshold=_")
154 .WithType<unsigned int>()
155 .IntoKey(M::SwapDexSizeThreshold)
156 .Define("--swap-dex-count-threshold=_")
157 .WithType<unsigned int>()
158 .IntoKey(M::SwapDexCountThreshold);
159 }
160
AddCompilerMappings(Builder & builder)161 static void AddCompilerMappings(Builder& builder) {
162 builder.
163 Define("--run-passes=_")
164 .WithType<std::string>()
165 .IntoKey(M::Passes)
166 .Define("--profile-file=_")
167 .WithType<std::string>()
168 .IntoKey(M::Profile)
169 .Define("--profile-file-fd=_")
170 .WithType<int>()
171 .IntoKey(M::ProfileFd)
172 .Define("--no-inline-from=_")
173 .WithType<std::string>()
174 .IntoKey(M::NoInlineFrom);
175 }
176
AddTargetMappings(Builder & builder)177 static void AddTargetMappings(Builder& builder) {
178 builder.
179 Define("--instruction-set=_")
180 .WithType<InstructionSet>()
181 .IntoKey(M::TargetInstructionSet)
182 .Define("--instruction-set-variant=_")
183 .WithType<std::string>()
184 .IntoKey(M::TargetInstructionSetVariant)
185 .Define("--instruction-set-features=_")
186 .WithType<std::string>()
187 .IntoKey(M::TargetInstructionSetFeatures);
188 }
189
CreateArgumentParser()190 static Parser CreateArgumentParser() {
191 std::unique_ptr<Builder> parser_builder = std::make_unique<Builder>();
192
193 AddInputMappings(*parser_builder);
194 AddGeneratedArtifactMappings(*parser_builder);
195 AddImageMappings(*parser_builder);
196 AddSwapMappings(*parser_builder);
197 AddCompilerMappings(*parser_builder);
198 AddTargetMappings(*parser_builder);
199
200 parser_builder->
201 Define({"--watch-dog", "--no-watch-dog"})
202 .WithValues({true, false})
203 .IntoKey(M::Watchdog)
204 .Define("--watchdog-timeout=_")
205 .WithType<int>()
206 .IntoKey(M::WatchdogTimeout)
207 .Define("-j_")
208 .WithType<unsigned int>()
209 .IntoKey(M::Threads)
210 .Define("--cpu-set=_")
211 .WithType<std::vector<int32_t>>()
212 .IntoKey(M::CpuSet)
213 .Define("--android-root=_")
214 .WithType<std::string>()
215 .IntoKey(M::AndroidRoot)
216 .Define("--compiler-backend=_")
217 .WithType<Compiler::Kind>()
218 .WithValueMap({{"Quick", Compiler::Kind::kQuick},
219 {"Optimizing", Compiler::Kind::kOptimizing}})
220 .IntoKey(M::Backend)
221 .Define("--host")
222 .IntoKey(M::Host)
223 .Define("--avoid-storing-invocation")
224 .IntoKey(M::AvoidStoringInvocation)
225 .Define("--very-large-app-threshold=_")
226 .WithType<unsigned int>()
227 .IntoKey(M::VeryLargeAppThreshold)
228 .Define("--force-determinism")
229 .IntoKey(M::ForceDeterminism)
230 .Define("--copy-dex-files=_")
231 .WithType<linker::CopyOption>()
232 .WithValueMap({{"true", linker::CopyOption::kOnlyIfCompressed},
233 {"false", linker::CopyOption::kNever},
234 {"always", linker::CopyOption::kAlways}})
235 .IntoKey(M::CopyDexFiles)
236 .Define("--write-invocation-to=_")
237 .WithType<std::string>()
238 .IntoKey(M::InvocationFile)
239 .Define("--classpath-dir=_")
240 .WithType<std::string>()
241 .IntoKey(M::ClasspathDir)
242 .Define("--class-loader-context=_")
243 .WithType<std::string>()
244 .IntoKey(M::ClassLoaderContext)
245 .Define("--class-loader-context-fds=_")
246 .WithType<std::string>()
247 .IntoKey(M::ClassLoaderContextFds)
248 .Define("--stored-class-loader-context=_")
249 .WithType<std::string>()
250 .IntoKey(M::StoredClassLoaderContext)
251 .Define("--compact-dex-level=_")
252 .WithType<CompactDexLevel>()
253 .WithValueMap({{"none", CompactDexLevel::kCompactDexLevelNone},
254 {"fast", CompactDexLevel::kCompactDexLevelFast}})
255 .IntoKey(M::CompactDexLevel)
256 .Define("--runtime-arg _")
257 .WithType<std::vector<std::string>>().AppendValues()
258 .IntoKey(M::RuntimeOptions)
259 .Define("--compilation-reason=_")
260 .WithType<std::string>()
261 .IntoKey(M::CompilationReason);
262
263 AddCompilerOptionsArgumentParserOptions<Dex2oatArgumentMap>(*parser_builder);
264
265 parser_builder->IgnoreUnrecognized(false);
266
267 return parser_builder->Build();
268 }
269
Parse(int argc,const char ** argv,std::string * error_msg)270 std::unique_ptr<Dex2oatArgumentMap> Dex2oatArgumentMap::Parse(int argc,
271 const char** argv,
272 std::string* error_msg) {
273 Parser parser = CreateArgumentParser();
274 CmdlineResult parse_result = parser.Parse(argv, argc);
275 if (!parse_result.IsSuccess()) {
276 *error_msg = parse_result.GetMessage();
277 return nullptr;
278 }
279
280 return std::make_unique<Dex2oatArgumentMap>(parser.ReleaseArgumentsMap());
281 }
282
283 #pragma GCC diagnostic pop
284 } // namespace art
285