// 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_TARGET_H_
#define TOOLS_GN_TARGET_H_
#include <set>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/synchronization/lock.h"
#include "tools/gn/action_values.h"
#include "tools/gn/config_values.h"
#include "tools/gn/item.h"
#include "tools/gn/label_ptr.h"
#include "tools/gn/ordered_set.h"
#include "tools/gn/source_file.h"
class InputFile;
class Settings;
class Token;
class Target : public Item {
public:
enum OutputType {
UNKNOWN,
GROUP,
EXECUTABLE,
SHARED_LIBRARY,
STATIC_LIBRARY,
SOURCE_SET,
COPY_FILES,
ACTION,
ACTION_FOREACH,
};
typedef std::vector<SourceFile> FileList;
typedef std::vector<std::string> StringVector;
Target(const Settings* settings, const Label& label);
virtual ~Target();
// Returns a string naming the output type.
static const char* GetStringForOutputType(OutputType type);
// Item overrides.
virtual Target* AsTarget() OVERRIDE;
virtual const Target* AsTarget() const OVERRIDE;
virtual void OnResolved() OVERRIDE;
OutputType output_type() const { return output_type_; }
void set_output_type(OutputType t) { output_type_ = t; }
bool IsLinkable() const;
// Will be the empty string to use the target label as the output name.
const std::string& output_name() const { return output_name_; }
void set_output_name(const std::string& name) { output_name_ = name; }
const std::string& output_extension() const { return output_extension_; }
void set_output_extension(const std::string& extension) {
output_extension_ = extension;
}
const FileList& sources() const { return sources_; }
FileList& sources() { return sources_; }
// Set to true when all sources are public. This is the default. In this case
// the public headers list should be empty.
bool all_headers_public() const { return all_headers_public_; }
void set_all_headers_public(bool p) { all_headers_public_ = p; }
// When all_headers_public is false, this is the list of public headers. It
// could be empty which would mean no headers are public.
const FileList& public_headers() const { return public_headers_; }
FileList& public_headers() { return public_headers_; }
// Compile-time extra dependencies.
const FileList& inputs() const { return inputs_; }
FileList& inputs() { return inputs_; }
// Runtime dependencies.
const FileList& data() const { return data_; }
FileList& data() { return data_; }
// Returns true if targets depending on this one should have an order
// dependency.
bool hard_dep() const {
return output_type_ == ACTION ||
output_type_ == ACTION_FOREACH ||
output_type_ == COPY_FILES;
}
// Linked dependencies.
const LabelTargetVector& deps() const { return deps_; }
LabelTargetVector& deps() { return deps_; }
// Non-linked dependencies.
const LabelTargetVector& datadeps() const { return datadeps_; }
LabelTargetVector& datadeps() { return datadeps_; }
// List of configs that this class inherits settings from. Once a target is
// resolved, this will also list all- and direct-dependent configs.
const LabelConfigVector& configs() const { return configs_; }
LabelConfigVector& configs() { return configs_; }
// List of configs that all dependencies (direct and indirect) of this
// target get. These configs are not added to this target. Note that due
// to the way this is computed, there may be duplicates in this list.
const LabelConfigVector& all_dependent_configs() const {
return all_dependent_configs_;
}
LabelConfigVector& all_dependent_configs() {
return all_dependent_configs_;
}
// List of configs that targets depending directly on this one get. These
// configs are not added to this target.
const LabelConfigVector& direct_dependent_configs() const {
return direct_dependent_configs_;
}
LabelConfigVector& direct_dependent_configs() {
return direct_dependent_configs_;
}
// A list of a subset of deps where we'll re-export direct_dependent_configs
// as direct_dependent_configs of this target.
const LabelTargetVector& forward_dependent_configs() const {
return forward_dependent_configs_;
}
LabelTargetVector& forward_dependent_configs() {
return forward_dependent_configs_;
}
const std::set<const Target*>& inherited_libraries() const {
return inherited_libraries_;
}
// This config represents the configuration set directly on this target.
ConfigValues& config_values() { return config_values_; }
const ConfigValues& config_values() const { return config_values_; }
ActionValues& action_values() { return action_values_; }
const ActionValues& action_values() const { return action_values_; }
const OrderedSet<SourceDir>& all_lib_dirs() const { return all_lib_dirs_; }
const OrderedSet<std::string>& all_libs() const { return all_libs_; }
const std::set<const Target*>& recursive_hard_deps() const {
return recursive_hard_deps_;
}
private:
// Pulls necessary information from dependencies to this one when all
// dependencies have been resolved.
void PullDependentTargetInfo(std::set<const Config*>* unique_configs);
// These each pull specific things from dependencies to this one when all
// deps have been resolved.
void PullForwardedDependentConfigs();
void PullRecursiveHardDeps();
OutputType output_type_;
std::string output_name_;
std::string output_extension_;
FileList sources_;
bool all_headers_public_;
FileList public_headers_;
FileList inputs_;
FileList data_;
bool hard_dep_;
// Note that if there are any groups in the deps, once the target is resolved
// these vectors will list *both* the groups as well as the groups' deps.
//
// This is because, in general, groups should be "transparent" ways to add
// groups of dependencies, so adding the groups deps make this happen with
// no additional complexity when iterating over a target's deps.
//
// However, a group may also have specific settings and configs added to it,
// so we also need the group in the list so we find these things. But you
// shouldn't need to look inside the deps of the group since those will
// already be added.
LabelTargetVector deps_;
LabelTargetVector datadeps_;
LabelConfigVector configs_;
LabelConfigVector all_dependent_configs_;
LabelConfigVector direct_dependent_configs_;
LabelTargetVector forward_dependent_configs_;
bool external_;
// Static libraries and source sets from transitive deps. These things need
// to be linked only with the end target (executable, shared library). Source
// sets do not get pushed beyond static library boundaries, and neither
// source sets nor static libraries get pushed beyond sahred library
// boundaries.
std::set<const Target*> inherited_libraries_;
// These libs and dirs are inherited from statically linked deps and all
// configs applying to this target.
OrderedSet<SourceDir> all_lib_dirs_;
OrderedSet<std::string> all_libs_;
// All hard deps from this target and all dependencies. Filled in when this
// target is marked resolved. This will not include the current target.
std::set<const Target*> recursive_hard_deps_;
ConfigValues config_values_; // Used for all binary targets.
ActionValues action_values_; // Used for action[_foreach] targets.
DISALLOW_COPY_AND_ASSIGN(Target);
};
#endif // TOOLS_GN_TARGET_H_