Index: tools/gn/qt_creator_writer.cc |
diff --git a/tools/gn/qt_creator_writer.cc b/tools/gn/qt_creator_writer.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..96f247f5719a0a580fa874b37ce39bb6351b1e02 |
--- /dev/null |
+++ b/tools/gn/qt_creator_writer.cc |
@@ -0,0 +1,174 @@ |
+// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "tools/gn/qt_creator_writer.h" |
+ |
+#include <set> |
+#include <sstream> |
+#include <string> |
+ |
+#include "base/files/file_path.h" |
+#include "base/files/file_util.h" |
+#include "base/strings/utf_string_conversions.h" |
+ |
+#include "tools/gn/builder.h" |
+#include "tools/gn/config_values_extractors.h" |
+#include "tools/gn/deps_iterator.h" |
+#include "tools/gn/filesystem_utils.h" |
+#include "tools/gn/label.h" |
+#include "tools/gn/loader.h" |
+ |
+namespace { |
+base::FilePath::CharType kProjectDirName[] = |
+ FILE_PATH_LITERAL("qtcreator_project"); |
+base::FilePath::CharType kProjectName[] = FILE_PATH_LITERAL("all"); |
+base::FilePath::CharType kMainProjectFileSuffix[] = |
+ FILE_PATH_LITERAL(".creator"); |
+base::FilePath::CharType kSourcesFileSuffix[] = FILE_PATH_LITERAL(".files"); |
+base::FilePath::CharType kIncludesFileSuffix[] = FILE_PATH_LITERAL(".includes"); |
+base::FilePath::CharType kDefinesFileSuffix[] = FILE_PATH_LITERAL(".config"); |
+} |
+ |
+// static |
+bool QtCreatorWriter::RunAndWriteFile(const BuildSettings* build_settings, |
+ const Builder* builder, |
+ Err* err, |
+ const std::string& root_target) { |
+ base::FilePath project_dir = |
+ build_settings->GetFullPath(build_settings->build_dir()) |
+ .Append(kProjectDirName); |
+ if (!base::DirectoryExists(project_dir)) { |
+ base::File::Error error; |
+ if (!base::CreateDirectoryAndGetError(project_dir, &error)) { |
+ *err = |
+ Err(Location(), "Could not create the QtCreator project directory '" + |
+ FilePathToUTF8(project_dir) + "': " + |
+ base::File::ErrorToString(error)); |
+ return false; |
+ } |
+ } |
+ |
+ base::FilePath project_prefix = project_dir.Append(kProjectName); |
+ QtCreatorWriter gen(build_settings, builder, project_prefix, root_target); |
+ gen.Run(); |
+ if (gen.err_.has_error()) { |
+ *err = gen.err_; |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+QtCreatorWriter::QtCreatorWriter(const BuildSettings* build_settings, |
+ const Builder* builder, |
+ const base::FilePath& project_prefix, |
+ const std::string& root_target_name) |
+ : build_settings_(build_settings), |
+ builder_(builder), |
+ project_prefix_(project_prefix), |
+ root_target_name_(root_target_name) {} |
+ |
+QtCreatorWriter::~QtCreatorWriter() {} |
+ |
+void QtCreatorWriter::CollectDeps(const Target* target) { |
+ for (const auto& dep : target->GetDeps(Target::DEPS_ALL)) { |
+ const Target* dep_target = dep.ptr; |
+ if (targets_.count(dep_target)) |
+ continue; |
+ targets_.insert(dep_target); |
+ CollectDeps(dep_target); |
+ } |
+} |
+ |
+bool QtCreatorWriter::DiscoverTargets() { |
+ auto all_targets = builder_->GetAllResolvedTargets(); |
+ |
+ if (root_target_name_.empty()) { |
+ targets_ = std::set<const Target*>(all_targets.begin(), all_targets.end()); |
+ return true; |
+ } |
+ |
+ const Target* root_target = nullptr; |
+ for (const Target* target : all_targets) { |
+ if (target->label().name() == root_target_name_) { |
+ root_target = target; |
+ break; |
+ } |
+ } |
+ |
+ if (!root_target) { |
+ err_ = Err(Location(), "Target '" + root_target_name_ + "' not found."); |
+ return false; |
+ } |
+ |
+ targets_.insert(root_target); |
+ CollectDeps(root_target); |
+ return true; |
+} |
+ |
+void QtCreatorWriter::AddToSources(const Target::FileList& files) { |
+ for (const SourceFile& file : files) { |
+ const std::string& file_path = |
+ FilePathToUTF8(build_settings_->GetFullPath(file)); |
+ sources_.insert(file_path); |
+ } |
+} |
+ |
+void QtCreatorWriter::HandleTarget(const Target* target) { |
+ SourceFile build_file = Loader::BuildFileForLabel(target->label()); |
+ sources_.insert(FilePathToUTF8(build_settings_->GetFullPath(build_file))); |
+ AddToSources(target->settings()->import_manager().GetImportedFiles()); |
+ |
+ AddToSources(target->sources()); |
+ AddToSources(target->public_headers()); |
+ AddToSources(target->inputs()); |
+ |
+ for (ConfigValuesIterator it(target); !it.done(); it.Next()) { |
+ SourceFile precompiled_source = it.cur().precompiled_source(); |
+ if (!precompiled_source.is_null()) { |
+ sources_.insert( |
+ FilePathToUTF8(build_settings_->GetFullPath(precompiled_source))); |
+ } |
+ |
+ for (const SourceDir& include_dir : it.cur().include_dirs()) { |
+ includes_.insert( |
+ FilePathToUTF8(build_settings_->GetFullPath(include_dir))); |
+ } |
+ |
+ for (std::string define : it.cur().defines()) { |
+ size_t equal_pos = define.find('='); |
+ if (equal_pos != std::string::npos) |
+ define[equal_pos] = ' '; |
+ define.insert(0, "#define "); |
+ defines_.insert(define); |
+ } |
+ } |
+} |
+ |
+void QtCreatorWriter::GenerateFile(const base::FilePath::CharType* suffix, |
+ const std::set<std::string>& items) { |
+ const base::FilePath file_path = project_prefix_.AddExtension(suffix); |
+ std::ostringstream output; |
+ for (const std::string& item : items) |
+ output << item << std::endl; |
+ WriteFileIfChanged(file_path, output.str(), &err_); |
+} |
+ |
+void QtCreatorWriter::Run() { |
+ if (!DiscoverTargets()) |
+ return; |
+ |
+ for (const Target* target : targets_) { |
+ if (target->toolchain()->label() != |
+ builder_->loader()->GetDefaultToolchain()) |
+ continue; |
+ HandleTarget(target); |
+ } |
+ |
+ std::set<std::string> empty_list; |
+ |
+ GenerateFile(kMainProjectFileSuffix, empty_list); |
+ GenerateFile(kSourcesFileSuffix, sources_); |
+ GenerateFile(kIncludesFileSuffix, includes_); |
+ GenerateFile(kDefinesFileSuffix, defines_); |
+} |