| // 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 <atomic> | |
| #include <bitset> | |
| #include <mutex> | |
| #include <optional> | |
| #include <set> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "base/gtest_prod_util.h" | |
| #include "base/logging.h" | |
| #include "gn/action_values.h" | |
| #include "gn/bundle_data.h" | |
| #include "gn/config_values.h" | |
| #include "gn/item.h" | |
| #include "gn/label_pattern.h" | |
| #include "gn/label_ptr.h" | |
| #include "gn/metadata.h" | |
| #include "gn/output_file.h" | |
| #include "gn/pointer_set.h" | |
| #include "gn/resolved_target_deps.h" | |
| #include "gn/rust_values.h" | |
| #include "gn/settings.h" | |
| #include "gn/source_file.h" | |
| #include "gn/swift_values.h" | |
| #include "gn/target_public_pair.h" | |
| #include "gn/toolchain.h" | |
| #include "gn/unique_vector.h" | |
| class DepsIteratorRange; | |
| class ResolvedTargetData; | |
| class Settings; | |
| class Target; | |
| class Toolchain; | |
| using TargetSet = PointerSet<const Target>; | |
| class Target : public Item { | |
| public: | |
| enum OutputType { | |
| UNKNOWN, | |
| GROUP, | |
| EXECUTABLE, | |
| SHARED_LIBRARY, | |
| LOADABLE_MODULE, | |
| STATIC_LIBRARY, | |
| SOURCE_SET, | |
| COPY_FILES, | |
| ACTION, | |
| ACTION_FOREACH, | |
| BUNDLE_DATA, | |
| CREATE_BUNDLE, | |
| GENERATED_FILE, | |
| RUST_LIBRARY, | |
| RUST_PROC_MACRO, | |
| }; | |
| enum DepsIterationType { | |
| DEPS_ALL, // Iterates through all public, private, and data deps. | |
| DEPS_LINKED, // Iterates through all non-data dependencies. | |
| }; | |
| enum ModuleTypeBits { | |
| HAS_MODULEMAP, | |
| MODULEMAP_IS_GENERATED, | |
| MODULEMAP_IS_TEXTUAL, | |
| N_MODULE_TYPE_BITS, | |
| }; | |
| using ModuleType = std::bitset<N_MODULE_TYPE_BITS>; | |
| using FileList = std::vector<SourceFile>; | |
| using StringVector = std::vector<std::string>; | |
| // We track the set of build files that may affect this target, please refer | |
| // to Scope for how this is determined. | |
| Target(const Settings* settings, | |
| const Label& label, | |
| const SourceFileSet& build_dependency_files = {}); | |
| ~Target() override; | |
| // Returns a string naming the output type. | |
| static const char* GetStringForOutputType(OutputType type); | |
| // Item overrides. | |
| Target* AsTarget() override; | |
| const Target* AsTarget() const override; | |
| // NOTE: This calls OnResolvedWithoutChecks followed by | |
| // RunChecksAfterResolution. | |
| bool OnResolved(Err* err) override; | |
| // Perform all resolution steps except for checks. When this function | |
| // returns, the content of the Target instance, as well as all its | |
| // standard dependencies (i.e. without validations and gen_deps) are | |
| // considered final and immutable. This allows running checks in background | |
| // threads while the rest of the resolution algorithm continues in the main | |
| // thread. | |
| bool OnResolvedWithoutChecks(Err* err); | |
| // Run checks. This requires OnResolvedWithoutChecks() to have been called | |
| // first. This can run in a background thread. | |
| bool RunChecksAfterResolution(Err* err); | |
| OutputType output_type() const { return output_type_; } | |
| void set_output_type(OutputType t) { output_type_ = t; } | |
| // True for targets that compile source code (all types of libraries and | |
| // executables). | |
| bool IsBinary() const; | |
| // Can be linked into other targets. | |
| bool IsLinkable() const; | |
| // True if the target links dependencies rather than propagated up the graph. | |
| // This is also true of action and copy steps even though they don't link | |
| // dependencies, because they also don't propagate libraries up. | |
| bool IsFinal() const; | |
| // Set when the target should normally be treated as a data dependency. These | |
| // do not need to be treated as inputs or hard dependencies for normal build | |
| // steps, but have to be kept in the dependency tree to be properly | |
| // propagated. Treating these as data only decreases superfluous rebuilds and | |
| // increases parallelism. | |
| bool IsDataOnly() const; | |
| // Return true if this target should be generated in the final build graph. | |
| bool ShouldGenerate() const; | |
| // Will be the empty string to use the target label as the output name. | |
| // See GetComputedOutputName(). | |
| const std::string& output_name() const { return output_name_; } | |
| void set_output_name(const std::string& name) { output_name_ = name; } | |
| // Returns the output name for this target, which is the output_name if | |
| // specified, or the target label if not. | |
| // | |
| // Because this depends on the tool for this target, the toolchain must | |
| // have been set before calling. | |
| std::string GetComputedOutputName() const; | |
| bool output_prefix_override() const { return output_prefix_override_; } | |
| void set_output_prefix_override(bool prefix_override) { | |
| output_prefix_override_ = prefix_override; | |
| } | |
| // Desired output directory for the final output. This will be used for | |
| // the {{output_dir}} substitution in the tool if it is specified. If | |
| // is_null, the tool default will be used. | |
| const SourceDir& output_dir() const { return output_dir_; } | |
| void set_output_dir(const SourceDir& dir) { output_dir_ = dir; } | |
| // The output extension is really a tri-state: unset (output_extension_set | |
| // is false and the string is empty, meaning the default extension should be | |
| // used), the output extension is set but empty (output should have no | |
| // extension) and the output extension is set but nonempty (use the given | |
| // extension). | |
| const std::string& output_extension() const { return output_extension_; } | |
| void set_output_extension(const std::string& extension) { | |
| output_extension_ = extension; | |
| output_extension_set_ = true; | |
| } | |
| bool output_extension_set() const { return output_extension_set_; } | |
| const FileList& sources() const { return sources_; } | |
| FileList& sources() { return sources_; } | |
| const FileList& public_inputs() const { return public_inputs_; } | |
| FileList& public_inputs() { return public_inputs_; } | |
| const SourceFileTypeSet& source_types_used() const { | |
| return source_types_used_; | |
| } | |
| SourceFileTypeSet& source_types_used() { return source_types_used_; } | |
| // 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_; } | |
| // Whether this target's includes should be checked by "gn check". | |
| bool check_includes() const { return check_includes_; } | |
| void set_check_includes(bool ci) { check_includes_ = ci; } | |
| // Whether this target enforces strict include checking. | |
| bool check_includes_strict() const { return check_includes_strict_; } | |
| void set_check_includes_strict(bool value) { check_includes_strict_ = value; } | |
| // Whether this static_library target should have code linked in. | |
| bool complete_static_lib() const { return complete_static_lib_; } | |
| void set_complete_static_lib(bool complete) { | |
| DCHECK_EQ(STATIC_LIBRARY, output_type_); | |
| complete_static_lib_ = complete; | |
| } | |
| // Metadata. Target takes ownership of the resulting scope. | |
| const Metadata& metadata() const; | |
| Metadata& metadata(); | |
| bool has_metadata() const { return metadata_.get(); } | |
| // Get metadata from this target and its dependencies. This is intended to | |
| // be called after the target is resolved. | |
| bool GetMetadata(const std::vector<std::string>& keys_to_extract, | |
| const std::vector<std::string>& keys_to_walk, | |
| const SourceDir& rebase_dir, | |
| bool deps_only, | |
| std::vector<Value>* result, | |
| TargetSet* targets_walked, | |
| Err* err) const; | |
| // GeneratedFile-related methods. | |
| bool GenerateFile(Err* err) const; | |
| // Metadata collection methods for GeneratedFile targets. | |
| struct GeneratedFile { | |
| Value output_conversion_; | |
| Value contents_; // Value::NONE if metadata collection should occur. | |
| SourceDir rebase_; | |
| std::vector<std::string> data_keys_; | |
| std::vector<std::string> walk_keys_; | |
| }; | |
| const GeneratedFile& generated_file() const; | |
| GeneratedFile& generated_file(); | |
| bool has_generated_file() const { return generated_file_.get(); } | |
| const Value& contents() const { return generated_file().contents_; } | |
| void set_contents(const Value& value) { generated_file().contents_ = value; } | |
| const Value& output_conversion() const { | |
| return generated_file().output_conversion_; | |
| } | |
| void set_output_conversion(const Value& value) { | |
| generated_file().output_conversion_ = value; | |
| } | |
| const SourceDir& rebase() const { return generated_file().rebase_; } | |
| void set_rebase(const SourceDir& value) { generated_file().rebase_ = value; } | |
| const std::vector<std::string>& data_keys() const { | |
| return generated_file().data_keys_; | |
| } | |
| std::vector<std::string>& data_keys() { return generated_file().data_keys_; } | |
| const std::vector<std::string>& walk_keys() const { | |
| return generated_file().walk_keys_; | |
| } | |
| std::vector<std::string>& walk_keys() { return generated_file().walk_keys_; } | |
| OutputFile write_runtime_deps_output() const { | |
| return write_runtime_deps_output_; | |
| } | |
| void set_write_runtime_deps_output(const OutputFile& value) { | |
| write_runtime_deps_output_ = value; | |
| } | |
| // Runtime dependencies. These are "file-like things" that can either be | |
| // directories or files. They do not need to exist, these are just passed as | |
| // runtime dependencies to external test systems as necessary. | |
| const std::vector<std::string>& data() const { return data_; } | |
| std::vector<std::string>& data() { return data_; } | |
| // Information about the bundle. Only valid for CREATE_BUNDLE target after | |
| // they have been resolved. | |
| const BundleData& bundle_data() const; | |
| BundleData& bundle_data(); | |
| bool has_bundle_data() const { return bundle_data_.get(); } | |
| // 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 || output_type_ == CREATE_BUNDLE || | |
| output_type_ == BUNDLE_DATA || output_type_ == GENERATED_FILE || | |
| builds_swift_module(); | |
| } | |
| // Returns the iterator range which can be used in range-based for loops | |
| // to iterate over multiple types of deps in one loop: | |
| // for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) ... | |
| DepsIteratorRange GetDeps(DepsIterationType type) const; | |
| // Linked private dependencies. | |
| const LabelTargetVector& private_deps() const { return private_deps_; } | |
| LabelTargetVector& private_deps() { return private_deps_; } | |
| // Linked public dependencies. | |
| const LabelTargetVector& public_deps() const { return public_deps_; } | |
| LabelTargetVector& public_deps() { return public_deps_; } | |
| // Non-linked dependencies. | |
| const LabelTargetVector& data_deps() const { return data_deps_; } | |
| LabelTargetVector& data_deps() { return data_deps_; } | |
| // Validation dependencies. | |
| const LabelTargetVector& validations() const { return validations_; } | |
| LabelTargetVector& validations() { return validations_; } | |
| // gen_deps only propagate the "should_generate" flag. These dependencies can | |
| // have cycles so care should be taken if iterating over them recursively. | |
| const LabelTargetVector& gen_deps() const { return gen_deps_; } | |
| LabelTargetVector& gen_deps() { return gen_deps_; } | |
| // List of configs that this class inherits settings from. Once a target is | |
| // resolved, this will also list all-dependent and public configs. | |
| const UniqueVector<LabelConfigPair>& configs() const { return configs_; } | |
| UniqueVector<LabelConfigPair>& 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 UniqueVector<LabelConfigPair>& all_dependent_configs() const { | |
| return all_dependent_configs_; | |
| } | |
| UniqueVector<LabelConfigPair>& all_dependent_configs() { | |
| return all_dependent_configs_; | |
| } | |
| // List of configs that targets depending directly on this one get. These | |
| // configs are also added to this target. | |
| const UniqueVector<LabelConfigPair>& public_configs() const { | |
| return public_configs_; | |
| } | |
| UniqueVector<LabelConfigPair>& public_configs() { return public_configs_; } | |
| // Dependencies that can include files from this target. | |
| const std::set<Label>& allow_circular_includes_from() const { | |
| return allow_circular_includes_from_; | |
| } | |
| std::set<Label>& allow_circular_includes_from() { | |
| return allow_circular_includes_from_; | |
| } | |
| // Pool option | |
| const LabelPtrPair<Pool>& pool() const { return pool_; } | |
| void set_pool(LabelPtrPair<Pool> pool) { pool_ = std::move(pool); } | |
| // This config represents the configuration set directly on this target. | |
| ConfigValues& config_values(); | |
| const ConfigValues& config_values() const; | |
| bool has_config_values() const { return config_values_.get(); } | |
| ActionValues& action_values(); | |
| const ActionValues& action_values() const; | |
| bool has_action_values() const { return action_values_.get(); } | |
| SwiftValues& swift_values(); | |
| const SwiftValues& swift_values() const; | |
| bool has_swift_values() const { return swift_values_.get(); } | |
| // Return true if this targets builds a SwiftModule | |
| bool builds_swift_module() const { | |
| return IsBinary() && source_types_used().SwiftSourceUsed(); | |
| } | |
| RustValues& rust_values(); | |
| const RustValues& rust_values() const; | |
| bool has_rust_values() const { return rust_values_.get(); } | |
| std::vector<LabelPattern>& friends() { return friends_; } | |
| const std::vector<LabelPattern>& friends() const { return friends_; } | |
| std::vector<LabelPattern>& assert_no_deps() { return assert_no_deps_; } | |
| const std::vector<LabelPattern>& assert_no_deps() const { | |
| return assert_no_deps_; | |
| } | |
| ModuleType module_type() const { return module_type_; } | |
| void set_module_type(ModuleType type); | |
| const SourceFile* modulemap_file() const; | |
| const SourceFile* private_modulemap_file() const; | |
| // The toolchain is only known once this target is resolved (all if its | |
| // dependencies are known). They will be null until then. Generally, this can | |
| // only be used during target writing. | |
| const Toolchain* toolchain() const { return toolchain_; } | |
| // Sets the toolchain. The toolchain must include a tool for this target | |
| // or the error will be set and the function will return false. Unusually, | |
| // this function's "err" output is optional since this is commonly used | |
| // frequently by unit tests which become needlessly verbose. | |
| bool SetToolchain(const Toolchain* toolchain, Err* err = nullptr); | |
| // Once this target has been resolved, all outputs from the target will be | |
| // listed here. This will include things listed in the "outputs" for an | |
| // action or a copy step, and the output library or executable file(s) from | |
| // binary targets. | |
| // | |
| // It will NOT include phony targets or object files. | |
| const std::vector<OutputFile>& computed_outputs() const { | |
| return computed_outputs_; | |
| } | |
| // Returns outputs from this target. The link output file is the one that | |
| // other targets link to when they depend on this target. This will only be | |
| // valid for libraries and will be empty for all other target types. | |
| // | |
| // The dependency output file is the file that should be used to express | |
| // a dependency on this one. It could be the same as the link output file | |
| // (this will be the case for static libraries). For shared libraries it | |
| // could be the same or different than the link output file, depending on the | |
| // system. | |
| // | |
| // The dependency output alias is only set when the target does not have an | |
| // output file and is using a Ninja phony target to represent it. The | |
| // exception to this is for phony targets without any real inputs. Ninja | |
| // treats empty phony targets as always dirty, so no other targets should | |
| // depend on that target. In that scenario, both dependency_output_alias or | |
| // dependency_output_file will be empty. | |
| // | |
| // Callers that do not care whether the dependency is represented by a file or | |
| // an alias should use dependency_output(). | |
| // | |
| // These are only known once the target is resolved and will be empty before | |
| // that. This is a cache of the files to prevent every target that depends on | |
| // a given library from recomputing the same pattern. | |
| const OutputFile& link_output_file() const { return link_output_file_; } | |
| // Returns true if there is an output dependency file or phony alias. | |
| bool has_dependency_output() const { | |
| return has_dependency_output_file() || has_dependency_output_alias(); | |
| } | |
| // Return the output dependency file path or phony alias if one is defined, | |
| // or an empty string otherwise. | |
| const OutputFile& dependency_output() const { | |
| return has_dependency_output_file() ? dependency_output_file_ | |
| : dependency_output_alias_; | |
| } | |
| // Return true if there is a dependency file path defined for this target. | |
| bool has_dependency_output_file() const { | |
| return !dependency_output_file_.value().empty(); | |
| } | |
| // Return the dependency output file path for this target if defined, or | |
| // an empty string otherwise. | |
| const OutputFile& dependency_output_file() const { | |
| return dependency_output_file_; | |
| } | |
| // Return true if there is a dependency output alias defined for this target. | |
| bool has_dependency_output_alias() const { | |
| return !dependency_output_alias_.value().empty(); | |
| } | |
| // Return the dependency output alias if any, or an empty string otherwise. | |
| const OutputFile& dependency_output_alias() const { | |
| return dependency_output_alias_; | |
| } | |
| // The subset of computed_outputs that are considered runtime outputs. | |
| const std::vector<OutputFile>& runtime_outputs() const { | |
| return runtime_outputs_; | |
| } | |
| // The module name for the target. | |
| std::string module_name() const { return module_name_; } | |
| void set_module_name(std::string module_name) { | |
| module_name_ = std::move(module_name); | |
| } | |
| // Similar to defined_from(), but for targets created via templates, returns | |
| // the invoker of the template rather than the template definition. | |
| Location user_friendly_location() const; | |
| void set_user_friendly_location(Location location) { | |
| user_friendly_location_ = location; | |
| } | |
| // Computes and returns the outputs of this target expressed as SourceFiles. | |
| // | |
| // For binary target this depends on the tool for this target so the toolchain | |
| // must have been loaded beforehand. This will happen asynchronously so | |
| // calling this on a binary target before the build is complete will produce a | |
| // race condition. | |
| // | |
| // To resolve this, the caller passes in whether the entire build is complete | |
| // (this is used for the introspection commands which run after everything | |
| // else). | |
| // | |
| // If the build is complete, the toolchain will be used for binary targets to | |
| // compute the outputs. If the build is not complete, calling this function | |
| // for binary targets will produce an error. | |
| // | |
| // The |loc_for_error| is used to blame a location for any errors produced. It | |
| // can be empty if there is no range (like this is being called based on the | |
| // command-line. | |
| // | |
| // It is possible for |outputs| to be returned empty without an error being | |
| // reported. This can occur when the output type will result in a phony alias | |
| // target (like a source_set) that is omitted from build files when they have | |
| // no real inputs. | |
| bool GetOutputsAsSourceFiles(const LocationRange& loc_for_error, | |
| bool build_complete, | |
| std::vector<SourceFile>* outputs, | |
| Err* err) const; | |
| // Computes the set of output files resulting from compiling the given source | |
| // file. | |
| // | |
| // For binary targets, if the file can be compiled and the tool exists, fills | |
| // the outputs in and writes the tool type to computed_tool_type. If the file | |
| // is not compilable, returns false. | |
| // | |
| // For action_foreach and copy targets, applies the output pattern to the | |
| // given file name to compute the outputs. | |
| // | |
| // For all other target types, just returns the target outputs because such | |
| // targets conceptually process all of their inputs as one step. | |
| // | |
| // The function can succeed with a "NONE" tool type for object files which | |
| // are just passed to the output. The output will always be overwritten, not | |
| // appended to. | |
| bool GetOutputFilesForSource(const SourceFile& source, | |
| const char** computed_tool_type, | |
| std::vector<OutputFile>* outputs) const; | |
| private: | |
| FRIEND_TEST_ALL_PREFIXES(TargetTest, ResolvePrecompiledHeaders); | |
| FRIEND_TEST_ALL_PREFIXES(TargetTest, HasRealInputs); | |
| // Pulls necessary information from dependencies to this one when all | |
| // dependencies have been resolved. | |
| void PullDependentTargetConfigs(); | |
| void PullDependentTargetLibsFrom(const Target* dep, bool is_public); | |
| void PullDependentTargetLibs(); | |
| void PullRecursiveHardDeps(); | |
| void PullRecursiveBundleData(); | |
| // Checks to see whether this target or any of its dependencies have real | |
| // inputs. If not, this target should be omitted as a dependency. This check | |
| // only applies to targets that will result in a phony rule. | |
| bool HasRealInputs() const; | |
| // Fills the link and dependency output files when a target is resolved. | |
| bool FillOutputFiles(Err* err); | |
| // Checks precompiled headers from configs and makes sure the resulting | |
| // values are in config_values_. | |
| bool ResolvePrecompiledHeaders(Err* err); | |
| // Validates the given thing when a target is resolved. | |
| bool CheckVisibility(Err* err) const; | |
| bool CheckConfigVisibility(Err* err) const; | |
| bool CheckTestonly(Err* err) const; | |
| bool CheckAssertNoDeps(Err* err) const; | |
| void CheckSourcesGenerated() const; | |
| bool CheckSourceSetLanguages(Err* err) const; | |
| OutputType output_type_ = UNKNOWN; | |
| std::string output_name_; | |
| bool output_prefix_override_ = false; | |
| SourceDir output_dir_; | |
| std::string output_extension_; | |
| bool output_extension_set_ = false; | |
| std::string module_name_; | |
| ModuleType module_type_; | |
| Location user_friendly_location_; | |
| // Only filled if the module type is GENERATED_* | |
| SourceFile generated_modulemap_file_; | |
| // For performance reasons we cache private_modulemap_file. | |
| // Modulemap files are passed as pointers, so to keep them as pointers instead | |
| // of values we need to store them somewhere. | |
| mutable SourceFile private_modulemap_file_; | |
| FileList sources_; | |
| SourceFileTypeSet source_types_used_; | |
| FileList public_inputs_; | |
| bool all_headers_public_ = true; | |
| FileList public_headers_; | |
| bool check_includes_ = true; | |
| bool check_includes_strict_ = false; | |
| bool complete_static_lib_ = false; | |
| std::vector<std::string> data_; | |
| std::unique_ptr<BundleData> bundle_data_; | |
| OutputFile write_runtime_deps_output_; | |
| LabelTargetVector private_deps_; | |
| LabelTargetVector public_deps_; | |
| LabelTargetVector data_deps_; | |
| LabelTargetVector validations_; | |
| LabelTargetVector gen_deps_; | |
| // See getters for more info. | |
| UniqueVector<LabelConfigPair> configs_; | |
| UniqueVector<LabelConfigPair> all_dependent_configs_; | |
| UniqueVector<LabelConfigPair> public_configs_; | |
| std::set<Label> allow_circular_includes_from_; | |
| LabelPtrPair<Pool> pool_; | |
| std::vector<LabelPattern> friends_; | |
| std::vector<LabelPattern> assert_no_deps_; | |
| // Used for all binary targets, and for inputs in regular targets. The | |
| // precompiled header values in this struct will be resolved to the ones to | |
| // use for this target, if precompiled headers are used. | |
| std::unique_ptr<ConfigValues> config_values_; | |
| // Used for action[_foreach] targets. | |
| std::unique_ptr<ActionValues> action_values_; | |
| // Used for Rust targets. | |
| std::unique_ptr<RustValues> rust_values_; | |
| // User for Swift targets. | |
| std::unique_ptr<SwiftValues> swift_values_; | |
| // Toolchain used by this target. Null until target is resolved. | |
| const Toolchain* toolchain_ = nullptr; | |
| // Output files. Empty until the target is resolved. | |
| std::vector<OutputFile> computed_outputs_; | |
| OutputFile link_output_file_; | |
| OutputFile dependency_output_file_; | |
| OutputFile dependency_output_alias_; | |
| std::vector<OutputFile> runtime_outputs_; | |
| std::unique_ptr<Metadata> metadata_; | |
| // GeneratedFile as metadata collection values. | |
| std::unique_ptr<GeneratedFile> generated_file_; | |
| friend class ResolvedTargetData; | |
| enum class LazyBool : uint8_t { | |
| kUnknown, | |
| kTrue, | |
| kFalse, | |
| }; | |
| // Cached resolved dependency and link information computed on demand by | |
| // ResolvedTargetData. Owned directly by Target so its lifetime matches | |
| // the target itself without requiring external maps, locks, or generation | |
| // IDs. | |
| struct TargetInfo { | |
| TargetInfo() = default; | |
| explicit TargetInfo(const Target* target) | |
| : target(target), | |
| deps(target->public_deps(), | |
| target->private_deps(), | |
| target->data_deps()) {} | |
| const Target* target = nullptr; | |
| ResolvedTargetDeps deps; | |
| mutable std::mutex mutex; | |
| std::atomic<bool> has_lib_info = false; | |
| std::atomic<bool> has_framework_info = false; | |
| std::atomic<bool> has_hard_deps = false; | |
| std::atomic<bool> has_inherited_libs = false; | |
| std::atomic<bool> has_module_deps_information = false; | |
| std::atomic<bool> has_rust_libs = false; | |
| std::atomic<bool> has_swift_values = false; | |
| std::atomic<bool> has_order_only_deps = false; | |
| std::atomic<LazyBool> does_export_public_inputs = LazyBool::kUnknown; | |
| // Only valid if |has_lib_info| is true. | |
| std::vector<SourceDir> lib_dirs; | |
| std::vector<LibFile> libs; | |
| // Only valid if |has_framework_info| is true. | |
| std::vector<SourceDir> framework_dirs; | |
| std::vector<std::string> frameworks; | |
| std::vector<std::string> weak_frameworks; | |
| std::vector<std::string> weak_libraries; | |
| // Only valid if |has_hard_deps| is true. | |
| TargetSet hard_deps; | |
| // Only valid if |has_inherited_libs| is true. | |
| std::vector<TargetPublicPair> inherited_libs; | |
| // Only valid if |has_module_deps_information| is true. | |
| std::vector<TargetPublicPair> module_deps_information; | |
| // Only valid if |has_rust_libs| is true. | |
| std::vector<TargetPublicPair> rust_inherited_libs; | |
| std::vector<TargetPublicPair> rust_inheritable_libs; | |
| // Only valid if |has_swift_values| is true. | |
| // Most targets will not have Swift dependencies, so only | |
| // allocate a SwiftValues struct when needed. A null pointer | |
| // indicates empty lists. | |
| struct SwiftValues { | |
| std::vector<const Target*> modules; | |
| std::vector<const Target*> public_modules; | |
| SwiftValues(std::vector<const Target*> modules, | |
| std::vector<const Target*> public_modules) | |
| : modules(std::move(modules)), | |
| public_modules(std::move(public_modules)) {} | |
| }; | |
| std::unique_ptr<SwiftValues> swift_values; | |
| // Only valid if |has_order_only_deps| is true. | |
| std::vector<OutputFile> order_only_deps; | |
| }; | |
| TargetInfo& info() const { | |
| DCHECK(info_.has_value()); | |
| return *info_; | |
| } | |
| mutable std::optional<TargetInfo> info_; | |
| Target(const Target&) = delete; | |
| Target& operator=(const Target&) = delete; | |
| }; | |
| std::string Pretty(const Target& target); | |
| extern const char kExecution_Help[]; | |
| #endif // TOOLS_GN_TARGET_H_ |