| Index: tools/gn/ninja_build_writer.cc
|
| diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a63765cd3aafadcb7d785d3a53db279a54456b7c
|
| --- /dev/null
|
| +++ b/tools/gn/ninja_build_writer.cc
|
| @@ -0,0 +1,165 @@
|
| +// Copyright (c) 2013 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/ninja_build_writer.h"
|
| +
|
| +#include <fstream>
|
| +
|
| +#include "base/command_line.h"
|
| +#include "base/file_util.h"
|
| +#include "base/process/process_handle.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "build/build_config.h"
|
| +#include "tools/gn/build_settings.h"
|
| +#include "tools/gn/filesystem_utils.h"
|
| +#include "tools/gn/input_file_manager.h"
|
| +#include "tools/gn/scheduler.h"
|
| +#include "tools/gn/target.h"
|
| +
|
| +#if defined(OS_WIN)
|
| +#include <windows.h>
|
| +#endif
|
| +
|
| +namespace {
|
| +
|
| +std::string GetSelfInvocationCommand(const BuildSettings* build_settings) {
|
| +#if defined(OS_WIN)
|
| + wchar_t module[MAX_PATH];
|
| + GetModuleFileName(NULL, module, MAX_PATH);
|
| + //result = "\"" + WideToUTF8(module) + "\"";
|
| + base::FilePath executable(module);
|
| +#elif defined(OS_MACOSX)
|
| + // FIXME(brettw) write this on Mac!
|
| + base::FilePath executable("gn");
|
| +#else
|
| + base::FilePath executable =
|
| + base::GetProcessExecutablePath(base::GetCurrentProcessHandle());
|
| +#endif
|
| +
|
| +/*
|
| + // Append the root path.
|
| + CommandLine* cmdline = CommandLine::ForCurrentProcess();
|
| + result += " --root=\"" + FilePathToUTF8(settings->root_path()) + "\"";
|
| +*/
|
| +
|
| + CommandLine cmdline(executable);
|
| + cmdline.AppendSwitchPath("--root", build_settings->root_path());
|
| +
|
| + // TODO(brettw) append other parameters.
|
| +
|
| +#if defined(OS_WIN)
|
| + return WideToUTF8(cmdline.GetCommandLineString());
|
| +#else
|
| + return cmdline.GetCommandLineString();
|
| +#endif
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +NinjaBuildWriter::NinjaBuildWriter(
|
| + const BuildSettings* build_settings,
|
| + const std::vector<const Settings*>& all_settings,
|
| + const std::vector<const Target*>& default_toolchain_targets,
|
| + std::ostream& out)
|
| + : build_settings_(build_settings),
|
| + all_settings_(all_settings),
|
| + default_toolchain_targets_(default_toolchain_targets),
|
| + out_(out),
|
| + path_output_(build_settings->build_dir(), ESCAPE_NINJA, true),
|
| + helper_(build_settings) {
|
| +}
|
| +
|
| +NinjaBuildWriter::~NinjaBuildWriter() {
|
| +}
|
| +
|
| +void NinjaBuildWriter::Run() {
|
| + WriteNinjaRules();
|
| + WriteSubninjas();
|
| + WritePhonyAndAllRules();
|
| +}
|
| +
|
| +// static
|
| +bool NinjaBuildWriter::RunAndWriteFile(
|
| + const BuildSettings* build_settings,
|
| + const std::vector<const Settings*>& all_settings,
|
| + const std::vector<const Target*>& default_toolchain_targets) {
|
| + base::FilePath ninja_file(build_settings->GetFullPath(
|
| + SourceFile(build_settings->build_dir().value() + "build.ninja")));
|
| + file_util::CreateDirectory(ninja_file.DirName());
|
| +
|
| + std::ofstream file;
|
| + file.open(FilePathToUTF8(ninja_file).c_str(),
|
| + std::ios_base::out | std::ios_base::binary);
|
| + if (file.fail())
|
| + return false;
|
| +
|
| + NinjaBuildWriter gen(build_settings, all_settings,
|
| + default_toolchain_targets, file);
|
| + gen.Run();
|
| + return true;
|
| +}
|
| +
|
| +void NinjaBuildWriter::WriteNinjaRules() {
|
| + out_ << "rule gn\n";
|
| + out_ << " command = " << GetSelfInvocationCommand(build_settings_) << "\n";
|
| + out_ << " description = GN the world\n\n";
|
| +
|
| + out_ << "build build.ninja: gn";
|
| +
|
| + // Input build files.
|
| + std::vector<SourceFile> input_files;
|
| + g_scheduler->input_file_manager()->GetAllInputFileNames(&input_files);
|
| + for (size_t i = 0; i < input_files.size(); i++) {
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, input_files[i]);
|
| + }
|
| +
|
| + // Other files read by the build.
|
| + std::vector<SourceFile> other_files = g_scheduler->GetGenDependencies();
|
| + for (size_t i = 0; i < other_files.size(); i++) {
|
| + out_ << " ";
|
| + path_output_.WriteFile(out_, other_files[i]);
|
| + }
|
| +
|
| + out_ << std::endl << std::endl;
|
| +}
|
| +
|
| +void NinjaBuildWriter::WriteSubninjas() {
|
| + for (size_t i = 0; i < all_settings_.size(); i++) {
|
| + out_ << "subninja ";
|
| + path_output_.WriteFile(out_,
|
| + helper_.GetNinjaFileForToolchain(all_settings_[i]));
|
| + out_ << std::endl;
|
| + }
|
| + out_ << std::endl;
|
| +}
|
| +
|
| +void NinjaBuildWriter::WritePhonyAndAllRules() {
|
| + std::string all_rules;
|
| +
|
| + // Write phony rules for the default toolchain (don't do other toolchains or
|
| + // we'll get naming conflicts).
|
| + for (size_t i = 0; i < default_toolchain_targets_.size(); i++) {
|
| + const Target* target = default_toolchain_targets_[i];
|
| + if (target->output_type() == Target::NONE)
|
| + continue; // Nothing to generate.
|
| +
|
| + OutputFile target_file = helper_.GetTargetOutputFile(target);
|
| + if (target_file.value() != target->label().name()) {
|
| + out_ << "build " << target->label().name() << ": phony ";
|
| + path_output_.WriteFile(out_, target_file);
|
| + out_ << std::endl;
|
| + }
|
| +
|
| + if (!all_rules.empty())
|
| + all_rules.append(" $\n ");
|
| + all_rules.append(target_file.value());
|
| + }
|
| +
|
| + if (!all_rules.empty()) {
|
| + out_ << "\nbuild all: phony " << all_rules << std::endl;
|
| + out_ << "default all" << std::endl;
|
| + }
|
| +}
|
| +
|
|
|