| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "base/atomicops.h" | 5 #include "base/atomicops.h" |
| 6 #include "base/bind.h" | 6 #include "base/bind.h" |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
| 10 #include "base/timer/elapsed_timer.h" | 10 #include "base/timer/elapsed_timer.h" |
| 11 #include "tools/gn/build_settings.h" | 11 #include "tools/gn/build_settings.h" |
| 12 #include "tools/gn/commands.h" | 12 #include "tools/gn/commands.h" |
| 13 #include "tools/gn/eclipse_writer.h" | 13 #include "tools/gn/eclipse_writer.h" |
| 14 #include "tools/gn/json_project_writer.h" | |
| 15 #include "tools/gn/ninja_target_writer.h" | 14 #include "tools/gn/ninja_target_writer.h" |
| 16 #include "tools/gn/ninja_writer.h" | 15 #include "tools/gn/ninja_writer.h" |
| 17 #include "tools/gn/qt_creator_writer.h" | 16 #include "tools/gn/qt_creator_writer.h" |
| 18 #include "tools/gn/runtime_deps.h" | 17 #include "tools/gn/runtime_deps.h" |
| 19 #include "tools/gn/scheduler.h" | 18 #include "tools/gn/scheduler.h" |
| 20 #include "tools/gn/setup.h" | 19 #include "tools/gn/setup.h" |
| 21 #include "tools/gn/standard_out.h" | 20 #include "tools/gn/standard_out.h" |
| 22 #include "tools/gn/switches.h" | 21 #include "tools/gn/switches.h" |
| 23 #include "tools/gn/target.h" | 22 #include "tools/gn/target.h" |
| 24 #include "tools/gn/visual_studio_writer.h" | 23 #include "tools/gn/visual_studio_writer.h" |
| 25 #include "tools/gn/xcode_writer.h" | 24 #include "tools/gn/xcode_writer.h" |
| 26 | 25 |
| 27 namespace commands { | 26 namespace commands { |
| 28 | 27 |
| 29 namespace { | 28 namespace { |
| 30 | 29 |
| 31 const char kSwitchCheck[] = "check"; | 30 const char kSwitchCheck[] = "check"; |
| 32 const char kSwitchFilters[] = "filters"; | 31 const char kSwitchFilters[] = "filters"; |
| 33 const char kSwitchIde[] = "ide"; | 32 const char kSwitchIde[] = "ide"; |
| 34 const char kSwitchIdeValueEclipse[] = "eclipse"; | 33 const char kSwitchIdeValueEclipse[] = "eclipse"; |
| 35 const char kSwitchIdeValueQtCreator[] = "qtcreator"; | 34 const char kSwitchIdeValueQtCreator[] = "qtcreator"; |
| 36 const char kSwitchIdeValueVs[] = "vs"; | 35 const char kSwitchIdeValueVs[] = "vs"; |
| 37 const char kSwitchIdeValueVs2013[] = "vs2013"; | 36 const char kSwitchIdeValueVs2013[] = "vs2013"; |
| 38 const char kSwitchIdeValueVs2015[] = "vs2015"; | 37 const char kSwitchIdeValueVs2015[] = "vs2015"; |
| 39 const char kSwitchIdeValueXcode[] = "xcode"; | 38 const char kSwitchIdeValueXcode[] = "xcode"; |
| 40 const char kSwitchIdeValueJson[] = "json"; | |
| 41 const char kSwitchNinjaExtraArgs[] = "ninja-extra-args"; | 39 const char kSwitchNinjaExtraArgs[] = "ninja-extra-args"; |
| 42 const char kSwitchRootTarget[] = "root-target"; | 40 const char kSwitchRootTarget[] = "root-target"; |
| 43 const char kSwitchSln[] = "sln"; | 41 const char kSwitchSln[] = "sln"; |
| 44 const char kSwitchWorkspace[] = "workspace"; | 42 const char kSwitchWorkspace[] = "workspace"; |
| 45 const char kSwitchJsonFileName[] = "json-file-name"; | |
| 46 const char kSwitchJsonIdeScript[] = "json-ide-script"; | |
| 47 const char kSwitchJsonIdeScriptArgs[] = "json-ide-script-args"; | |
| 48 | 43 |
| 49 // Called on worker thread to write the ninja file. | 44 // Called on worker thread to write the ninja file. |
| 50 void BackgroundDoWrite(const Target* target) { | 45 void BackgroundDoWrite(const Target* target) { |
| 51 NinjaTargetWriter::RunAndWriteFile(target); | 46 NinjaTargetWriter::RunAndWriteFile(target); |
| 52 g_scheduler->DecrementWorkCount(); | 47 g_scheduler->DecrementWorkCount(); |
| 53 } | 48 } |
| 54 | 49 |
| 55 // Called on the main thread. | 50 // Called on the main thread. |
| 56 void ItemResolvedCallback(base::subtle::Atomic32* write_counter, | 51 void ItemResolvedCallback(base::subtle::Atomic32* write_counter, |
| 57 scoped_refptr<Builder> builder, | 52 scoped_refptr<Builder> builder, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 | 106 |
| 112 const std::string target_str = targets.size() > 1 ? "targets" : "target"; | 107 const std::string target_str = targets.size() > 1 ? "targets" : "target"; |
| 113 err += "The file:\n"; | 108 err += "The file:\n"; |
| 114 err += " " + file.value() + "\n"; | 109 err += " " + file.value() + "\n"; |
| 115 err += "is listed as an input or source for the " + target_str + ":\n"; | 110 err += "is listed as an input or source for the " + target_str + ":\n"; |
| 116 for (const Target* target : targets) | 111 for (const Target* target : targets) |
| 117 err += " " + target->label().GetUserVisibleName(show_toolchains) + "\n"; | 112 err += " " + target->label().GetUserVisibleName(show_toolchains) + "\n"; |
| 118 | 113 |
| 119 if (generator) { | 114 if (generator) { |
| 120 err += "but this file was not generated by any dependencies of the " + | 115 err += "but this file was not generated by any dependencies of the " + |
| 121 target_str + ". The target\nthat generates the file is:\n "; | 116 target_str + ". The target\nthat generates the file is:\n "; |
| 122 err += generator->label().GetUserVisibleName(show_toolchains); | 117 err += generator->label().GetUserVisibleName(show_toolchains); |
| 123 } else { | 118 } else { |
| 124 err += "but no targets in the build generate that file."; | 119 err += "but no targets in the build generate that file."; |
| 125 } | 120 } |
| 126 | 121 |
| 127 Err(Location(), "Input to " + target_str + " not generated by a dependency.", | 122 Err(Location(), "Input to " + target_str + " not generated by a dependency.", |
| 128 err).PrintToStdout(); | 123 err).PrintToStdout(); |
| 129 } | 124 } |
| 130 | 125 |
| 131 bool CheckForInvalidGeneratedInputs(Setup* setup) { | 126 bool CheckForInvalidGeneratedInputs(Setup* setup) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 } | 159 } |
| 165 return false; | 160 return false; |
| 166 } | 161 } |
| 167 | 162 |
| 168 bool RunIdeWriter(const std::string& ide, | 163 bool RunIdeWriter(const std::string& ide, |
| 169 const BuildSettings* build_settings, | 164 const BuildSettings* build_settings, |
| 170 Builder* builder, | 165 Builder* builder, |
| 171 Err* err) { | 166 Err* err) { |
| 172 const base::CommandLine* command_line = | 167 const base::CommandLine* command_line = |
| 173 base::CommandLine::ForCurrentProcess(); | 168 base::CommandLine::ForCurrentProcess(); |
| 174 bool quiet = command_line->HasSwitch(switches::kQuiet); | |
| 175 base::ElapsedTimer timer; | 169 base::ElapsedTimer timer; |
| 176 | 170 |
| 177 if (ide == kSwitchIdeValueEclipse) { | 171 if (ide == kSwitchIdeValueEclipse) { |
| 178 bool res = EclipseWriter::RunAndWriteFile(build_settings, builder, err); | 172 bool res = EclipseWriter::RunAndWriteFile(build_settings, builder, err); |
| 179 if (res && !quiet) { | 173 if (res && !command_line->HasSwitch(switches::kQuiet)) { |
| 180 OutputString("Generating Eclipse settings took " + | 174 OutputString("Generating Eclipse settings took " + |
| 181 base::Int64ToString(timer.Elapsed().InMilliseconds()) + | 175 base::Int64ToString(timer.Elapsed().InMilliseconds()) + |
| 182 "ms\n"); | 176 "ms\n"); |
| 183 } | 177 } |
| 184 return res; | 178 return res; |
| 185 } else if (ide == kSwitchIdeValueVs || ide == kSwitchIdeValueVs2013 || | 179 } else if (ide == kSwitchIdeValueVs || ide == kSwitchIdeValueVs2013 || |
| 186 ide == kSwitchIdeValueVs2015) { | 180 ide == kSwitchIdeValueVs2015) { |
| 187 VisualStudioWriter::Version version = | 181 VisualStudioWriter::Version version = |
| 188 ide == kSwitchIdeValueVs2013 ? VisualStudioWriter::Version::Vs2013 | 182 ide == kSwitchIdeValueVs2013 ? VisualStudioWriter::Version::Vs2013 |
| 189 : VisualStudioWriter::Version::Vs2015; | 183 : VisualStudioWriter::Version::Vs2015; |
| 190 std::string sln_name; | 184 std::string sln_name; |
| 191 if (command_line->HasSwitch(kSwitchSln)) | 185 if (command_line->HasSwitch(kSwitchSln)) |
| 192 sln_name = command_line->GetSwitchValueASCII(kSwitchSln); | 186 sln_name = command_line->GetSwitchValueASCII(kSwitchSln); |
| 193 std::string filters; | 187 std::string filters; |
| 194 if (command_line->HasSwitch(kSwitchFilters)) | 188 if (command_line->HasSwitch(kSwitchFilters)) |
| 195 filters = command_line->GetSwitchValueASCII(kSwitchFilters); | 189 filters = command_line->GetSwitchValueASCII(kSwitchFilters); |
| 196 bool res = VisualStudioWriter::RunAndWriteFiles( | 190 bool res = VisualStudioWriter::RunAndWriteFiles( |
| 197 build_settings, builder, version, sln_name, filters, err); | 191 build_settings, builder, version, sln_name, filters, err); |
| 198 if (res && !quiet) { | 192 if (res && !command_line->HasSwitch(switches::kQuiet)) { |
| 199 OutputString("Generating Visual Studio projects took " + | 193 OutputString("Generating Visual Studio projects took " + |
| 200 base::Int64ToString(timer.Elapsed().InMilliseconds()) + | 194 base::Int64ToString(timer.Elapsed().InMilliseconds()) + |
| 201 "ms\n"); | 195 "ms\n"); |
| 202 } | 196 } |
| 203 return res; | 197 return res; |
| 204 } else if (ide == kSwitchIdeValueXcode) { | 198 } else if (ide == kSwitchIdeValueXcode) { |
| 205 bool res = XcodeWriter::RunAndWriteFiles( | 199 bool res = XcodeWriter::RunAndWriteFiles( |
| 206 command_line->GetSwitchValueASCII(kSwitchWorkspace), | 200 command_line->GetSwitchValueASCII(kSwitchWorkspace), |
| 207 command_line->GetSwitchValueASCII(kSwitchRootTarget), | 201 command_line->GetSwitchValueASCII(kSwitchRootTarget), |
| 208 command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs), | 202 command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs), |
| 209 command_line->GetSwitchValueASCII(kSwitchFilters), build_settings, | 203 command_line->GetSwitchValueASCII(kSwitchFilters), build_settings, |
| 210 builder, err); | 204 builder, err); |
| 211 if (res && !quiet) { | 205 if (res && !command_line->HasSwitch(switches::kQuiet)) { |
| 212 OutputString("Generating Xcode projects took " + | 206 OutputString("Generating Xcode projects took " + |
| 213 base::Int64ToString(timer.Elapsed().InMilliseconds()) + | 207 base::Int64ToString(timer.Elapsed().InMilliseconds()) + |
| 214 "ms\n"); | 208 "ms\n"); |
| 215 } | 209 } |
| 216 return res; | 210 return res; |
| 217 } else if (ide == kSwitchIdeValueQtCreator) { | 211 } else if (ide == kSwitchIdeValueQtCreator) { |
| 218 std::string root_target; | 212 std::string root_target; |
| 219 if (command_line->HasSwitch(kSwitchRootTarget)) | 213 if (command_line->HasSwitch(kSwitchRootTarget)) |
| 220 root_target = command_line->GetSwitchValueASCII(kSwitchRootTarget); | 214 root_target = command_line->GetSwitchValueASCII(kSwitchRootTarget); |
| 221 bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err, | 215 bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err, |
| 222 root_target); | 216 root_target); |
| 223 if (res && !quiet) { | 217 if (res && !command_line->HasSwitch(switches::kQuiet)) { |
| 224 OutputString("Generating QtCreator projects took " + | 218 OutputString("Generating QtCreator projects took " + |
| 225 base::Int64ToString(timer.Elapsed().InMilliseconds()) + | 219 base::Int64ToString(timer.Elapsed().InMilliseconds()) + |
| 226 "ms\n"); | 220 "ms\n"); |
| 227 } | 221 } |
| 228 return res; | 222 return res; |
| 229 } else if (ide == kSwitchIdeValueJson) { | |
| 230 std::string file_name = | |
| 231 command_line->GetSwitchValueASCII(kSwitchJsonFileName); | |
| 232 if (file_name.empty()) | |
| 233 file_name = "project.json"; | |
| 234 std::string exec_script = | |
| 235 command_line->GetSwitchValueASCII(kSwitchJsonIdeScript); | |
| 236 std::string exec_script_extra_args = | |
| 237 command_line->GetSwitchValueASCII(kSwitchJsonIdeScriptArgs); | |
| 238 std::string filters = command_line->GetSwitchValueASCII(kSwitchFilters); | |
| 239 | |
| 240 bool res = JSONProjectWriter::RunAndWriteFiles( | |
| 241 build_settings, builder, file_name, exec_script, exec_script_extra_args, | |
| 242 filters, quiet, err); | |
| 243 if (res && !quiet) { | |
| 244 OutputString("Generating JSON projects took " + | |
| 245 base::Int64ToString(timer.Elapsed().InMilliseconds()) + | |
| 246 "ms\n"); | |
| 247 } | |
| 248 return res; | |
| 249 } | 223 } |
| 250 | 224 |
| 251 *err = Err(Location(), "Unknown IDE: " + ide); | 225 *err = Err(Location(), "Unknown IDE: " + ide); |
| 252 return false; | 226 return false; |
| 253 } | 227 } |
| 254 | 228 |
| 255 } // namespace | 229 } // namespace |
| 256 | 230 |
| 257 const char kGen[] = "gen"; | 231 const char kGen[] = "gen"; |
| 258 const char kGen_HelpShort[] = "gen: Generate ninja files."; | 232 const char kGen_HelpShort[] = |
| 233 "gen: Generate ninja files."; |
| 259 const char kGen_Help[] = | 234 const char kGen_Help[] = |
| 260 "gn gen: Generate ninja files.\n" | 235 "gn gen: Generate ninja files.\n" |
| 261 "\n" | 236 "\n" |
| 262 " gn gen [<ide options>] <out_dir>\n" | 237 " gn gen [<ide options>] <out_dir>\n" |
| 263 "\n" | 238 "\n" |
| 264 " Generates ninja files from the current tree and puts them in the given\n" | 239 " Generates ninja files from the current tree and puts them in the given\n" |
| 265 " output directory.\n" | 240 " output directory.\n" |
| 266 "\n" | 241 "\n" |
| 267 " The output directory can be a source-repo-absolute path name such as:\n" | 242 " The output directory can be a source-repo-absolute path name such as:\n" |
| 268 " //out/foo\n" | 243 " //out/foo\n" |
| 269 " Or it can be a directory relative to the current directory such as:\n" | 244 " Or it can be a directory relative to the current directory such as:\n" |
| 270 " out/foo\n" | 245 " out/foo\n" |
| 271 "\n" | 246 "\n" |
| 272 " See \"gn help switches\" for the common command-line switches.\n" | 247 " See \"gn help switches\" for the common command-line switches.\n" |
| 273 "\n" | 248 "\n" |
| 274 "IDE options\n" | 249 "IDE options\n" |
| 275 "\n" | 250 "\n" |
| 276 " GN optionally generates files for IDE. Possibilities for <ide options>\n" | 251 " GN optionally generates files for IDE. Possibilities for <ide options>\n" |
| 277 "\n" | 252 "\n" |
| 278 " --ide=<ide_name>\n" | 253 " --ide=<ide_name>\n" |
| 279 " Generate files for an IDE. Currently supported values:\n" | 254 " Generate files for an IDE. Currently supported values:\n" |
| 280 " \"eclipse\" - Eclipse CDT settings file.\n" | 255 " \"eclipse\" - Eclipse CDT settings file.\n" |
| 281 " \"vs\" - Visual Studio project/solution files.\n" | 256 " \"vs\" - Visual Studio project/solution files.\n" |
| 282 " (default Visual Studio version: 2015)\n" | 257 " (default Visual Studio version: 2015)\n" |
| 283 " \"vs2013\" - Visual Studio 2013 project/solution files.\n" | 258 " \"vs2013\" - Visual Studio 2013 project/solution files.\n" |
| 284 " \"vs2015\" - Visual Studio 2015 project/solution files.\n" | 259 " \"vs2015\" - Visual Studio 2015 project/solution files.\n" |
| 285 " \"xcode\" - Xcode workspace/solution files.\n" | 260 " \"xcode\" - Xcode workspace/solution files.\n" |
| 286 " \"qtcreator\" - QtCreator project files.\n" | 261 " \"qtcreator\" - QtCreator project files.\n" |
| 287 " \"json\" - JSON file containing target information\n" | |
| 288 "\n" | 262 "\n" |
| 289 " --filters=<path_prefixes>\n" | 263 " --filters=<path_prefixes>\n" |
| 290 " Semicolon-separated list of label patterns used to limit the set\n" | 264 " Semicolon-separated list of label patterns used to limit the set\n" |
| 291 " of generated projects (see \"gn help label_pattern\"). Only\n" | 265 " of generated projects (see \"gn help label_pattern\"). Only\n" |
| 292 " matching targets and their dependencies will be included in the\n" | 266 " matching targets and their dependencies will be included in the\n" |
| 293 " solution. Only used for Visual Studio, Xcode and JSON.\n" | 267 " solution. Only used for Visual Studio and Xcode.\n" |
| 294 "\n" | 268 "\n" |
| 295 "Visual Studio Flags\n" | 269 "Visual Studio Flags\n" |
| 296 "\n" | 270 "\n" |
| 297 " --sln=<file_name>\n" | 271 " --sln=<file_name>\n" |
| 298 " Override default sln file name (\"all\"). Solution file is written\n" | 272 " Override default sln file name (\"all\"). Solution file is written\n" |
| 299 " to the root build directory.\n" | 273 " to the root build directory.\n" |
| 300 "\n" | 274 "\n" |
| 301 "Xcode Flags\n" | 275 "Xcode Flags\n" |
| 302 "\n" | 276 "\n" |
| 303 " --workspace=<file_name>\n" | 277 " --workspace=<file_name>\n" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 324 "\n" | 298 "\n" |
| 325 "Eclipse IDE Support\n" | 299 "Eclipse IDE Support\n" |
| 326 "\n" | 300 "\n" |
| 327 " GN DOES NOT generate Eclipse CDT projects. Instead, it generates a\n" | 301 " GN DOES NOT generate Eclipse CDT projects. Instead, it generates a\n" |
| 328 " settings file which can be imported into an Eclipse CDT project. The\n" | 302 " settings file which can be imported into an Eclipse CDT project. The\n" |
| 329 " XML file contains a list of include paths and defines. Because GN does\n" | 303 " XML file contains a list of include paths and defines. Because GN does\n" |
| 330 " not generate a full .cproject definition, it is not possible to\n" | 304 " not generate a full .cproject definition, it is not possible to\n" |
| 331 " properly define includes/defines for each file individually.\n" | 305 " properly define includes/defines for each file individually.\n" |
| 332 " Instead, one set of includes/defines is generated for the entire\n" | 306 " Instead, one set of includes/defines is generated for the entire\n" |
| 333 " project. This works fairly well but may still result in a few indexer\n" | 307 " project. This works fairly well but may still result in a few indexer\n" |
| 334 " issues here and there.\n" | 308 " issues here and there.\n"; |
| 335 "\n" | |
| 336 "Generic JSON Output\n" | |
| 337 "\n" | |
| 338 " Dumps target information to JSON file and optionally invokes python\n" | |
| 339 " script on generated file. \n" | |
| 340 " See comments at the beginning of json_project_writer.cc and\n" | |
| 341 " desc_builder.cc for overview of JSON file format.\n" | |
| 342 "\n" | |
| 343 " --json-file-name=<json_file_name>\n" | |
| 344 " Overrides default file name (project.json) of generated JSON file.\n" | |
| 345 "\n" | |
| 346 " --json-ide-script=<path_to_python_script>\n" | |
| 347 " Executes python script after the JSON file is generated.\n" | |
| 348 " Path can be project absolute (//), system absolute (/) or\n" | |
| 349 " relative, in which case the output directory will be base.\n" | |
| 350 " Path to generated JSON file will be first argument when invoking\n" | |
| 351 " script.\n" | |
| 352 "\n" | |
| 353 " --json-ide-script-args=<argument>\n" | |
| 354 " Optional second argument that will passed to executed script.\n"; | |
| 355 | 309 |
| 356 int RunGen(const std::vector<std::string>& args) { | 310 int RunGen(const std::vector<std::string>& args) { |
| 357 base::ElapsedTimer timer; | 311 base::ElapsedTimer timer; |
| 358 | 312 |
| 359 if (args.size() != 1) { | 313 if (args.size() != 1) { |
| 360 Err(Location(), "Need exactly one build directory to generate.", | 314 Err(Location(), "Need exactly one build directory to generate.", |
| 361 "I expected something more like \"gn gen out/foo\"\n" | 315 "I expected something more like \"gn gen out/foo\"\n" |
| 362 "You can also see \"gn help gen\".").PrintToStdout(); | 316 "You can also see \"gn help gen\".").PrintToStdout(); |
| 363 return 1; | 317 return 1; |
| 364 } | 318 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 setup->scheduler().input_file_manager()->GetInputFileCount()) + | 374 setup->scheduler().input_file_manager()->GetInputFileCount()) + |
| 421 " files in " + | 375 " files in " + |
| 422 base::Int64ToString(elapsed_time.InMilliseconds()) + "ms\n"; | 376 base::Int64ToString(elapsed_time.InMilliseconds()) + "ms\n"; |
| 423 OutputString(stats); | 377 OutputString(stats); |
| 424 } | 378 } |
| 425 | 379 |
| 426 return 0; | 380 return 0; |
| 427 } | 381 } |
| 428 | 382 |
| 429 } // namespace commands | 383 } // namespace commands |
| OLD | NEW |