class Builder;
-// XXX Add lib/exe prefix/suffix fields. Some archs may need multiple alternatives, how to handle this?
+/**
+Stores information about an architecture. This includes CPU type, model and
+bitness and operating system.
+*/
class Architecture
{
public:
#include <msp/io/pipe.h>
#include "task.h"
+/**
+Runs an external command. A zero exit status is translated to a SUCCESS status
+for the task, and anything else is treated as an error. Output can optionally
+be captured.
+*/
class ExternalTask: public Task
{
public:
std::string output;
public:
+ /** Creates an ExternalTask with an argument array and an optional working
+ directory. The first element of the argument array should be the command
+ name. If the working directory is not specified, no chdir is done. */
ExternalTask(const Arguments &, const Msp::FS::Path & = Msp::FS::Path());
+
virtual ~ExternalTask();
virtual std::string get_command() const;
#include "gnucompiler.h"
+/**
+The GNU C compiler, commonly known as gcc.
+*/
class GnuCCompiler: public GnuCompiler
{
public:
#include "tool.h"
+/**
+Common base class for GNU compilers. Turns SourceFiles into ObjectFiles.
+
+Since invocation is mostly the same for all language frontends, most of the
+logic is here and the individual tools only handle creating source files of
+appropriate type.
+*/
class GnuCompiler: public Tool
{
protected:
#include "gnucompiler.h"
+/**
+The GNU C++ compiler, commonly known as g++.
+*/
class GnuCxxCompiler: public GnuCompiler
{
public:
#include "tool.h"
+/**
+The GNU linker. Turns ObjectFiles into Executables and SharedLibraries. To
+create a shared library, specify "shared" as the second argument to
+create_target.
+
+Uses either gcc or g++ depending on what was used to compile the object files.
+*/
class GnuLinker: public Tool
{
private:
#include <msp/core/thread.h>
#include "task.h"
+/**
+Runs a worker thread. Tools should derive a thread class from
+InternalTask::Worker. The worker thread must set its status to either SUCCESS
+or ERROR before terminating.
+*/
class InternalTask: public Task
{
public:
#include <string>
+/**
+Stores a filename pattern. A pattern consists of a prefix and a suffix, and
+can be applied to a body to form a complete filename. Either or both of the
+prefix and suffix may be empty.
+*/
class Pattern
{
private:
std::string suffix;
public:
+ /** Constructs a pattern from a single string. The string must have exactly
+ one percent sign (%) to separate the prefix and suffix. */
Pattern(const std::string &);
+ /** Applies the pattern to a body string. */
std::string apply(const std::string &) const;
};
{
if(!tool)
{
+ // This special case is needed for VirtualTargets
state = UPTODATE;
return 0;
}
returns 0. */
virtual Target *get_buildable_target();
- /** If this target is a proxy for another (such as Install), return that
- target. Otherwise, return the target itself.
-
- Implementors should call the function recursively to find the final target. */
+ /** If this target is a proxy for another (such as InstalledFile), return
+ that target. Otherwise, return the target itself. Implementors should call
+ the function recursively to find the final target. */
virtual Target *get_real_target() { return this; }
void set_tool(const Tool &);
+
+ /** Returns the tool used to build the target. To actually build it, call
+ the build() function. */
const Tool *get_tool() const { return tool; }
/** Indicates if it's possible to build this target. */
/** Forces rebuild of the target. */
void force_rebuild();
+ /** Adds a dependency for the target. Order is preseved and is important
+ for some target types. It is an error to create dependency cycles, although
+ this won't be detected until the targets are prepared. */
void add_depend(Target *);
+
+ /// Returns the dependencies of the target, in the order they were added.
const Dependencies &get_depends() const { return depends; }
- /** Finds dependencies for the target. */
+ /** Finds dependencies for the target. Called during preparation. If the
+ target needs to recursively inspect its dependencies, it should prepare its
+ direct dependencies first. */
virtual void find_depends() { }
/** Prepares the target by finding dependencies, recursively preparing them
and then checking whether rebuilding is needed. */
virtual void prepare();
- /** Starts building the target. Returns the Action used for building. */
+ /** Invokes the associated Tool to build the target and returns the
+ resulting Task. The task must be started by the caller. */
Task *build();
+
protected:
+ /** Marks the target to be rebuilt and specified a reason for it. */
void mark_rebuild(const std::string &);
/** Checks if the target needs to be rebuilt and why. */
#include <string>
#include <sigc++/signal.h>
+/**
+Tasks are used to manage other programs and worker threads involved in the
+build process. They are run asynchronously.
+*/
class Task
{
public:
virtual ~Tool() { }
const std::string &get_tag() const { return tag; }
+
+ /** Returns a target for the tool's own executable. If the tool does not
+ use an external program, returns null. */
// XXX The executable target should be retrieved when first needed
FileTarget *get_executable() const { return executable; }
+
+ /// Returns a list of suffixes that can be processed with this tool.
const SuffixList &get_input_suffixes() const { return input_suffixes; }
+
+ /** Returns a list of suffixes that are associated with this tool, but can't
+ be processed directly. For example C and C++ headers. */
const SuffixList &get_auxiliary_suffixes() const { return aux_suffixes; }
- bool accepts_suffix(const std::string &, bool = false) const;
+
+ /** Indicates whether the tool can accept a suffix. If aux is true,
+ auxiliary suffixes are considered as well */
+ bool accepts_suffix(const std::string &, bool aux = false) const;
+
+ /// Returns the systemwide search path for source files.
const SearchPath &get_system_path() const { return system_path; }
+ /// Creates a source file appropriate for this tool.
virtual Target *create_source(const Component &, const Msp::FS::Path &) const { return 0; }
+
+ /** Creates a package-less source file appropriate for this too. This is
+ called during dependency discovery when no package has created a target for
+ the file. */
virtual Target *create_source(const Msp::FS::Path &) const { return 0; }
+
+ /// Convenience function to create a target from a single source.
Target *create_target(Target &, const std::string & = std::string()) const;
+
+ /** Creates a target from sources. The exact types of accepted sources
+ depends on the tool. The optional second argument can be used to select an
+ alternative target type for tools that can create multiple kinds of targets. */
virtual Target *create_target(const std::list<Target *> &, const std::string & = std::string()) const = 0;
+
+ /** Invokes the tool to build a target. This should not be called directly;
+ use Target::build() instead. */
virtual Task *run(const Target &) const = 0;
};