// 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.

#ifndef TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_
#define TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_

#include "gn/c_tool.h"
#include "gn/config_values.h"
#include "gn/ninja_target_writer.h"
#include "gn/toolchain.h"
#include "gn/unique_vector.h"

struct EscapeOptions;

// Writes a .ninja file for a binary target type (an executable, a shared
// library, or a static library).
class NinjaBinaryTargetWriter : public NinjaTargetWriter {
 public:
  NinjaBinaryTargetWriter(const Target* target, std::ostream& out);
  ~NinjaBinaryTargetWriter() override;

  void Run() override;

 protected:
  // Structure used to return the classified deps from |GetDeps| method.
  struct ClassifiedDeps {
    UniqueVector<OutputFile> extra_object_files;
    UniqueVector<const Target*> linkable_deps;
    UniqueVector<const Target*> non_linkable_deps;
    UniqueVector<const Target*> framework_deps;
    UniqueVector<const Target*> swiftmodule_deps;
  };

  // Writes to the output stream a phony rule for inputs, and
  // returns the target to be appended to source rules that encodes the
  // implicit dependencies for the current target.
  // If num_output_uses is small, this might return all input dependencies
  // directly, without writing a phony rule.
  // If there are no implicit dependencies and no extra target dependencies
  // are passed in, this returns an empty vector.
  std::vector<OutputFile> WriteInputsStampOrPhonyAndGetDep(
      size_t num_phony_uses) const;

  // Gets all target dependencies and classifies them, as well as accumulates
  // object files from source sets we need to link.
  ClassifiedDeps GetClassifiedDeps() const;

  // Classifies the dependency as linkable or nonlinkable with the current
  // target, adding it to the appropriate vector of |classified_deps|. If the
  // dependency is a source set we should link in, the source set's object
  // files will be appended to |classified_deps.extra_object_files|.
  void ClassifyDependency(const Target* dep,
                          ClassifiedDeps* classified_deps) const;

  void WriteCompilerBuildLine(const std::vector<SourceFile>& sources,
                              const std::vector<OutputFile>& extra_deps,
                              const std::vector<OutputFile>& order_only_deps,
                              const Tool* tool,
                              const std::vector<OutputFile>& outputs,
                              bool can_write_source_info = true,
                              bool restat_output_allowed = false);

  void WriteLinkerFlags(std::ostream& out,
                        const Tool* tool,
                        const SourceFile* optional_def_file);
  void WriteCustomLinkerFlags(std::ostream& out, const Tool* tool);
  void WriteLibrarySearchPath(std::ostream& out, const Tool* tool);
  void WriteLibs(std::ostream& out, const Tool* tool);
  void WriteFrameworks(std::ostream& out, const Tool* tool);
  void WriteSwiftModules(std::ostream& out,
                         const Tool* tool,
                         const std::vector<OutputFile>& swiftmodules);
  void WritePool(std::ostream& out);

  void AddSourceSetFiles(const Target* source_set,
                         UniqueVector<OutputFile>* obj_files) const;

  // Cached version of the prefix used for rule types for this toolchain.
  std::string rule_prefix_;

 private:
  NinjaBinaryTargetWriter(const NinjaBinaryTargetWriter&) = delete;
  NinjaBinaryTargetWriter& operator=(const NinjaBinaryTargetWriter&) = delete;
};

#endif  // TOOLS_GN_NINJA_BINARY_TARGET_WRITER_H_
