8 #include <sigc++/signal.h>
9 #include <msp/core/noncopyable.h>
10 #include <msp/time/timestamp.h>
11 #include "libbuilder_api.h"
21 Targets make up the build graph. This class is a base for all target types and
22 handles many common tasks. See also FileTarget and VirtualTarget.
24 Targets can depend on other targets. There are two kinds of dependencies:
25 normal and transitive. Normal dependencies will need to be built before the
26 target itself, and will cause the target to be rebuilt if modified. Transitive
27 dependencies can be used by other targets further down the chain.
29 class LIBBUILDER_API Target
32 using Dependencies = std::vector<Target *>;
45 struct PushPrepare: Msp::NonCopyable
47 PushPrepare(Target *t) { prepare_stack.push_back(t); }
48 ~PushPrepare() { prepare_stack.pop_back(); }
52 sigc::signal<void> signal_bubble_rebuild;
53 sigc::signal<void> signal_modified;
57 const SourcePackage *package = 0;
58 const Component *component = 0;
63 std::string rebuild_reason;
64 std::vector<std::string> problems;
67 Dependencies trans_depends;
68 Dependencies side_effects;
69 Target *primary_target = 0;
70 bool rescan_trans_deps = false;
72 static std::vector<Target *> prepare_stack;
74 Target(Builder &, const std::string &);
78 virtual const char *get_type() const = 0;
79 const std::string &get_name() const { return name; }
80 const SourcePackage *get_package() const { return package; }
81 const Component *get_component() const { return component; }
83 /** Adds a dependency for the target. Order is preseved and is important
84 for some target types. It is an error to create dependency cycles, although
85 this won't be detected until the targets are prepared. */
86 void add_dependency(Target &);
88 void add_transitive_dependency(Target &);
90 /** Adds a side effect for the target. Side effects are not built on their
91 own, but together with their primary target. */
92 void add_side_effect(Target &);
95 /** Finds dependencies for the target. Called during preparation. If the
96 target needs to recursively inspect its dependencies, it should prepare its
97 direct dependencies first. */
98 virtual void find_dependencies() { }
101 bool find_transitive_dependencies();
102 void find_transitive_dependencies(Target &, std::vector<Target *> &) const;
105 virtual Target *resolve_transitive_dependency(Target &, Target &dep) const { return &dep; }
108 /// Returns the dependencies of the target, in the order they were added.
109 const Dependencies &get_dependencies() const { return depends; }
111 const Dependencies &get_transitive_dependencies() const { return trans_depends; }
113 /// Returns the side effects of the target.
114 const Dependencies &get_side_effects() const { return side_effects; }
116 /// Returns the primary target associated with a side effect target.
117 Target *get_primary_target() const { return primary_target; }
119 /** Tries to locate a target that will help getting this target built. If
120 all dependencies are up-to-date, returns this target. If there are no
121 targets ready to be built (maybe because they are being built right now),
123 virtual Target *get_buildable_target();
125 /** If this target is a proxy for another (such as InstalledFile), return
126 that target. Otherwise, return the target itself. Implementors should call
127 the function recursively to find the final target. */
128 virtual Target *get_real_target() { return this; }
130 void set_tool(Tool &);
132 /** Returns the tool used to build the target. To actually build it, call
133 the build() function. */
134 const Tool *get_tool() const { return tool; }
136 virtual void collect_build_info(BuildInfo &) const;
138 /** Indicates if it's possible to build this target. */
139 bool is_buildable() const { return tool!=0; }
141 /** Indicates if this target needs rebuilding. Only makes sense after the
142 target has been prepared. */
143 bool needs_rebuild() const { return state>PREPARING && state<UPTODATE; }
145 /** Returns the reason for rebuilding this target. Only makes sense after
146 the target has been prepared. */
147 const std::string &get_rebuild_reason() const { return rebuild_reason; }
149 /** Forces rebuild of the target. */
150 void force_rebuild();
153 /** Marks the target to be rebuilt and specified a reason for it. */
154 void mark_rebuild(const std::string &);
156 /** Checks if the target needs to be rebuilt and why. */
157 virtual void check_rebuild() = 0;
160 bool is_broken() const { return state==BROKEN; }
162 const std::vector<std::string> &get_problems() const { return problems; }
164 /** Prepares the target by finding dependencies, recursively preparing them
165 and then checking whether rebuilding is needed. */
168 /** Invokes the associated Tool to build the target and returns the
169 resulting Task. The task must be started by the caller. */
170 virtual Task *build();
173 /** Targets can override this to do additional setup on the Task. This is
174 also called on side effects, which normally do not get built by themselves. */
175 virtual void build(Task &) { }
177 /** Handler for Task::signal_finished. */
178 virtual void build_finished(bool);
180 virtual void modified() { }
183 /** Removes any results of building the target. */
184 virtual void clean() { }