Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: tools/gn/xcode_writer.cc

Issue 2063243002: [GN] Add deployment target in generated project. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@{1}
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/xcode_writer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/xcode_writer.h" 5 #include "tools/gn/xcode_writer.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 #include <map> 8 #include <map>
9 #include <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
11 #include <string> 11 #include <string>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/environment.h" 14 #include "base/environment.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/sha1.h" 16 #include "base/sha1.h"
17 #include "base/strings/string_number_conversions.h" 17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
19 #include "tools/gn/args.h" 19 #include "tools/gn/args.h"
20 #include "tools/gn/build_settings.h" 20 #include "tools/gn/build_settings.h"
21 #include "tools/gn/builder.h" 21 #include "tools/gn/builder.h"
22 #include "tools/gn/commands.h" 22 #include "tools/gn/commands.h"
23 #include "tools/gn/deps_iterator.h" 23 #include "tools/gn/deps_iterator.h"
24 #include "tools/gn/filesystem_utils.h" 24 #include "tools/gn/filesystem_utils.h"
25 #include "tools/gn/scope.h"
25 #include "tools/gn/settings.h" 26 #include "tools/gn/settings.h"
26 #include "tools/gn/source_file.h" 27 #include "tools/gn/source_file.h"
27 #include "tools/gn/target.h" 28 #include "tools/gn/target.h"
28 #include "tools/gn/value.h" 29 #include "tools/gn/value.h"
29 #include "tools/gn/variables.h" 30 #include "tools/gn/variables.h"
30 #include "tools/gn/xcode_object.h" 31 #include "tools/gn/xcode_object.h"
31 32
32 namespace { 33 namespace {
33 34
34 XcodeWriter::TargetOsType GetTargetOs(const Args& args) { 35 bool GetTargetOs(const Scope* scope, std::string* target_os, Err* err) {
35 const Value* target_os_value = args.GetArgOverride(variables::kTargetOs); 36 const char* variable_names[] = {variables::kTargetOs, variables::kHostOs};
36 if (target_os_value) { 37 for (size_t i = 0; i < arraysize(variable_names); ++i) {
37 if (target_os_value->type() == Value::STRING) { 38 const Value* value = scope->GetValue(variable_names[i]);
38 if (target_os_value->string_value() == "ios") 39 if (value && value->type() == Value::STRING &&
39 return XcodeWriter::WRITER_TARGET_OS_IOS; 40 !value->string_value().empty()) {
41 target_os->assign(value->string_value());
42 return true;
40 } 43 }
41 } 44 }
42 return XcodeWriter::WRITER_TARGET_OS_MACOS; 45 *err = Err(nullptr, "cannot determine target_os");
46 return false;
43 } 47 }
44 48
45 std::string GetArchs(const Args& args) { 49 bool GetTargetCpu(const Scope* scope, std::string* target_cpu, Err* err) {
46 const Value* target_cpu_value = args.GetArgOverride(variables::kTargetCpu); 50 const char* variable_names[] = {variables::kTargetCpu, variables::kHostCpu};
47 if (target_cpu_value) { 51 for (size_t i = 0; i < arraysize(variable_names); ++i) {
48 if (target_cpu_value->type() == Value::STRING) { 52 const Value* value = scope->GetValue(variable_names[i]);
49 if (target_cpu_value->string_value() == "x86") 53 if (value && value->type() == Value::STRING &&
50 return "i386"; 54 !value->string_value().empty()) {
51 if (target_cpu_value->string_value() == "x64") 55 if (value->string_value() == "x86") {
52 return "x86_64"; 56 target_cpu->assign("i386");
53 if (target_cpu_value->string_value() == "arm") 57 return true;
54 return "armv7"; 58 }
55 if (target_cpu_value->string_value() == "armv7") 59 if (value->string_value() == "x64") {
56 return "armv7"; 60 target_cpu->assign("x86_64");
57 if (target_cpu_value->string_value() == "arm64") 61 return true;
58 return "armv64"; 62 }
63 if (value->string_value() == "arm") {
64 target_cpu->assign("armv7");
65 return true;
66 }
67 if (value->string_value() == "arm64") {
68 target_cpu->assign("arm64");
69 return true;
70 }
59 } 71 }
60 } 72 }
61 return "x86_64"; 73 *err = Err(nullptr, "cannot determine target_cpu");
74 return false;
75 }
76
77 bool GetDeploymentTarget(const Scope* scope,
78 const char* variable,
79 std::string* deployment_target,
80 Err* err) {
81 const Value* value = scope->GetValue(variable);
82 if (!value || value->type() != Value::STRING) {
83 *err = Err(nullptr, "cannot determine deployment target");
84 return false;
85 }
86
87 deployment_target->assign(value->string_value());
88 return true;
62 } 89 }
63 90
64 std::string GetBuildScript(const std::string& target_name, 91 std::string GetBuildScript(const std::string& target_name,
65 const std::string& build_path, 92 const std::string& build_path,
66 const std::string& ninja_extra_args) { 93 const std::string& ninja_extra_args) {
67 std::stringstream script; 94 std::stringstream script;
68 script << "echo note: \"Compile and copy " << target_name << " via ninja\"\n" 95 script << "echo note: \"Compile and copy " << target_name << " via ninja\"\n"
69 << "exec "; 96 << "exec ";
70 if (!build_path.empty()) 97 if (!build_path.empty())
71 script << "env PATH=\"" << build_path << "\" "; 98 script << "env PATH=\"" << build_path << "\" ";
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } // namespace 167 } // namespace
141 168
142 // static 169 // static
143 bool XcodeWriter::RunAndWriteFiles(const std::string& workspace_name, 170 bool XcodeWriter::RunAndWriteFiles(const std::string& workspace_name,
144 const std::string& root_target_name, 171 const std::string& root_target_name,
145 const std::string& ninja_extra_args, 172 const std::string& ninja_extra_args,
146 const std::string& dir_filters_string, 173 const std::string& dir_filters_string,
147 const BuildSettings* build_settings, 174 const BuildSettings* build_settings,
148 Builder* builder, 175 Builder* builder,
149 Err* err) { 176 Err* err) {
150 const XcodeWriter::TargetOsType target_os =
151 GetTargetOs(build_settings->build_args());
152
153 PBXAttributes attributes; 177 PBXAttributes attributes;
154 switch (target_os) { 178 if (!GetProjectsAttributes(build_settings, &attributes, err))
155 case XcodeWriter::WRITER_TARGET_OS_IOS: 179 return false;
156 attributes["SDKROOT"] = "iphoneos";
157 attributes["TARGETED_DEVICE_FAMILY"] = "1,2";
158 break;
159 case XcodeWriter::WRITER_TARGET_OS_MACOS:
160 attributes["ARCHS"] = GetArchs(build_settings->build_args());
161 attributes["SDKROOT"] = "macosx10.11";
162 break;
163 }
164 180
165 const std::string source_path = 181 const std::string source_path =
166 base::FilePath::FromUTF8Unsafe( 182 base::FilePath::FromUTF8Unsafe(
167 RebasePath("//", build_settings->build_dir())) 183 RebasePath("//", build_settings->build_dir()))
168 .StripTrailingSeparators() 184 .StripTrailingSeparators()
169 .AsUTF8Unsafe(); 185 .AsUTF8Unsafe();
170 186
171 std::string config_name = build_settings->build_dir() 187 std::string config_name = build_settings->build_dir()
172 .Resolve(base::FilePath()) 188 .Resolve(base::FilePath())
173 .StripTrailingSeparators() 189 .StripTrailingSeparators()
174 .BaseName() 190 .BaseName()
175 .AsUTF8Unsafe(); 191 .AsUTF8Unsafe();
176 DCHECK(!config_name.empty()); 192 DCHECK(!config_name.empty());
177 193
178 std::string::size_type separator = config_name.find('-'); 194 std::string::size_type separator = config_name.find('-');
179 if (separator != std::string::npos) 195 if (separator != std::string::npos)
180 config_name = config_name.substr(0, separator); 196 config_name = config_name.substr(0, separator);
181 197
182 std::vector<const Target*> targets; 198 std::vector<const Target*> targets;
183 std::vector<const Target*> all_targets = builder->GetAllResolvedTargets(); 199 std::vector<const Target*> all_targets = builder->GetAllResolvedTargets();
184 if (!XcodeWriter::FilterTargets(build_settings, all_targets, 200 if (!XcodeWriter::FilterTargets(build_settings, all_targets,
185 dir_filters_string, &targets, err)) { 201 dir_filters_string, &targets, err)) {
186 return false; 202 return false;
187 } 203 }
188 204
189 XcodeWriter workspace(workspace_name); 205 XcodeWriter workspace(workspace_name);
190 workspace.CreateProductsProject(targets, attributes, source_path, config_name, 206 workspace.CreateProductsProject(targets, attributes, source_path, config_name,
191 root_target_name, ninja_extra_args, 207 root_target_name, ninja_extra_args,
192 build_settings, target_os); 208 build_settings);
193 209
194 workspace.CreateSourcesProject(all_targets, build_settings->build_dir(), 210 workspace.CreateSourcesProject(all_targets, build_settings->build_dir(),
195 attributes, source_path, config_name, 211 attributes, source_path, config_name);
196 target_os);
197 212
198 return workspace.WriteFiles(build_settings, err); 213 return workspace.WriteFiles(build_settings, err);
199 } 214 }
200 215
201 XcodeWriter::XcodeWriter(const std::string& name) : name_(name) { 216 XcodeWriter::XcodeWriter(const std::string& name) : name_(name) {
202 if (name_.empty()) 217 if (name_.empty())
203 name_.assign("all"); 218 name_.assign("all");
204 } 219 }
205 220
206 XcodeWriter::~XcodeWriter() {} 221 XcodeWriter::~XcodeWriter() {}
207 222
208 // static 223 // static
224 bool XcodeWriter::GetProjectsAttributes(const BuildSettings* build_settings,
225 PBXAttributes* attributes,
226 Err* err) {
227 Settings* null_settings = nullptr;
sdefresne 2016/06/14 17:45:10 I'm not sure about this code. Previously the code
228 Scope global_scope(null_settings);
229 Scope::KeyValueMap declared_arguments;
230 build_settings->build_args().MergeDeclaredArguments(&declared_arguments);
231 for (const auto& pair : declared_arguments) {
232 global_scope.SetValue(pair.first, pair.second, nullptr);
233 }
234 build_settings->build_args().SetupRootScope(&global_scope,
235 Scope::KeyValueMap());
236
237 std::string target_os;
238 if (!GetTargetOs(&global_scope, &target_os, err))
239 return false;
240
241 std::string target_cpu;
242 if (!GetTargetCpu(&global_scope, &target_cpu, err))
243 return false;
244
245 if (target_os == "ios") {
246 std::string deployment_target;
247 if (!GetDeploymentTarget(&global_scope, "ios_deployment_target",
248 &deployment_target, err))
249 return false;
250
251 attributes->insert(std::make_pair("SDKROOT", "iphoneos"));
252 attributes->insert(std::make_pair("TARGETED_DEVICE_FAMILY", "1,2"));
253 attributes->insert(
254 std::make_pair("IPHONEOS_DEPLOYMENT_TARGET", deployment_target));
255 } else {
256 std::string deployment_target;
257 if (!GetDeploymentTarget(&global_scope, "mac_deployment_target",
258 &deployment_target, err))
259 return false;
260
261 attributes->insert(std::make_pair("ARCHS", target_cpu));
262 attributes->insert(std::make_pair("SDKROOT", "macosx"));
263 attributes->insert(
264 std::make_pair("MACOSX_DEPLOYMENT_TARGET", deployment_target));
265 }
266
267 return true;
268 }
269
270 // static
209 bool XcodeWriter::FilterTargets(const BuildSettings* build_settings, 271 bool XcodeWriter::FilterTargets(const BuildSettings* build_settings,
210 const std::vector<const Target*>& all_targets, 272 const std::vector<const Target*>& all_targets,
211 const std::string& dir_filters_string, 273 const std::string& dir_filters_string,
212 std::vector<const Target*>* targets, 274 std::vector<const Target*>* targets,
213 Err* err) { 275 Err* err) {
214 // Filter targets according to the semicolon-delimited list of label patterns, 276 // Filter targets according to the semicolon-delimited list of label patterns,
215 // if defined, first. 277 // if defined, first.
216 targets->reserve(all_targets.size()); 278 targets->reserve(all_targets.size());
217 if (dir_filters_string.empty()) { 279 if (dir_filters_string.empty()) {
218 *targets = all_targets; 280 *targets = all_targets;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 return true; 321 return true;
260 } 322 }
261 323
262 void XcodeWriter::CreateProductsProject( 324 void XcodeWriter::CreateProductsProject(
263 const std::vector<const Target*>& targets, 325 const std::vector<const Target*>& targets,
264 const PBXAttributes& attributes, 326 const PBXAttributes& attributes,
265 const std::string& source_path, 327 const std::string& source_path,
266 const std::string& config_name, 328 const std::string& config_name,
267 const std::string& root_target, 329 const std::string& root_target,
268 const std::string& ninja_extra_args, 330 const std::string& ninja_extra_args,
269 const BuildSettings* build_settings, 331 const BuildSettings* build_settings) {
270 TargetOsType target_os) {
271 std::unique_ptr<PBXProject> main_project( 332 std::unique_ptr<PBXProject> main_project(
272 new PBXProject("products", config_name, source_path, attributes)); 333 new PBXProject("products", config_name, source_path, attributes));
273 334
274 std::string build_path; 335 std::string build_path;
275 std::unique_ptr<base::Environment> env(base::Environment::Create()); 336 std::unique_ptr<base::Environment> env(base::Environment::Create());
276 env->GetVar("PATH", &build_path); 337 env->GetVar("PATH", &build_path);
277 338
278 main_project->AddAggregateTarget( 339 main_project->AddAggregateTarget(
279 "All", GetBuildScript(root_target, build_path, ninja_extra_args)); 340 "All", GetBuildScript(root_target, build_path, ninja_extra_args));
280 341
342 const auto iter = attributes.find("SDKROOT");
343 const bool skip_executable_targets =
344 iter != attributes.end() && iter->second == "iphoneos";
345
281 for (const Target* target : targets) { 346 for (const Target* target : targets) {
282 switch (target->output_type()) { 347 switch (target->output_type()) {
283 case Target::EXECUTABLE: 348 case Target::EXECUTABLE:
284 if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS) 349 if (skip_executable_targets)
285 continue; 350 continue;
286 351
287 main_project->AddNativeTarget( 352 main_project->AddNativeTarget(
288 target->label().name(), "compiled.mach-o.executable", 353 target->label().name(), "compiled.mach-o.executable",
289 target->output_name().empty() ? target->label().name() 354 target->output_name().empty() ? target->label().name()
290 : target->output_name(), 355 : target->output_name(),
291 "com.apple.product-type.tool", 356 "com.apple.product-type.tool",
292 GetBuildScript(target->label().name(), build_path, 357 GetBuildScript(target->label().name(), build_path,
293 ninja_extra_args)); 358 ninja_extra_args));
294 break; 359 break;
(...skipping 19 matching lines...) Expand all
314 } 379 }
315 380
316 projects_.push_back(std::move(main_project)); 381 projects_.push_back(std::move(main_project));
317 } 382 }
318 383
319 void XcodeWriter::CreateSourcesProject( 384 void XcodeWriter::CreateSourcesProject(
320 const std::vector<const Target*>& targets, 385 const std::vector<const Target*>& targets,
321 const SourceDir& root_build_dir, 386 const SourceDir& root_build_dir,
322 const PBXAttributes& attributes, 387 const PBXAttributes& attributes,
323 const std::string& source_path, 388 const std::string& source_path,
324 const std::string& config_name, 389 const std::string& config_name) {
325 TargetOsType target_os) {
326 std::vector<SourceFile> sources; 390 std::vector<SourceFile> sources;
327 for (const Target* target : targets) { 391 for (const Target* target : targets) {
328 if (!target->settings()->is_default()) 392 if (!target->settings()->is_default())
329 continue; 393 continue;
330 394
331 for (const SourceFile& source : target->sources()) { 395 for (const SourceFile& source : target->sources()) {
332 if (source.is_system_absolute()) 396 if (source.is_system_absolute())
333 continue; 397 continue;
334 398
335 if (IsStringInOutputDir(root_build_dir, source.value())) 399 if (IsStringInOutputDir(root_build_dir, source.value()))
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 for (const auto& object : pair.second) { 489 for (const auto& object : pair.second) {
426 object->Print(out, 2); 490 object->Print(out, 2);
427 } 491 }
428 out << "/* End " << ToString(pair.first) << " section */\n"; 492 out << "/* End " << ToString(pair.first) << " section */\n";
429 } 493 }
430 494
431 out << "\t};\n" 495 out << "\t};\n"
432 << "\trootObject = " << project->Reference() << ";\n" 496 << "\trootObject = " << project->Reference() << ";\n"
433 << "}\n"; 497 << "}\n";
434 } 498 }
OLDNEW
« no previous file with comments | « tools/gn/xcode_writer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698