Chromium Code Reviews| 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..df20428814128adf0721c39f429fae14b3f8e332 |
| --- /dev/null |
| +++ b/tools/gn/qt_creator_writer.cc |
| @@ -0,0 +1,172 @@ |
| +// 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 { |
| +const char kProjectDirName[] = "qtcreator_project"; |
| +const char kProjectName[] = "all"; |
| +const char kMainProjectFileSuffix[] = ".creator"; |
| +const char kSourcesFileSuffix[] = ".files"; |
| +const char kIncludesFileSuffix[] = ".includes"; |
| +const char kDefinesFileSuffix[] = ".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()) |
| + .AppendASCII(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.AppendASCII(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 char* suffix, |
| + std::set<std::string>* items) { |
|
brucedawson
2016/05/09 18:56:49
Should be const std::set, and perhaps then a refer
Krzysztof Olczyk
2016/05/10 08:11:18
Done.
|
| + 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_); |
| +} |