diff options
Diffstat (limited to 'src/ninja.cc')
-rw-r--r-- | src/ninja.cc | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/src/ninja.cc b/src/ninja.cc new file mode 100644 index 0000000..f39c77f --- /dev/null +++ b/src/ninja.cc @@ -0,0 +1,103 @@ +#include "ninja.h" + +#include <getopt.h> +#include <limits.h> +#include <stdio.h> + +#include "build.h" +#include "graphviz.h" +#include "parsers.h" + +option options[] = { + { "help", no_argument, NULL, 'h' }, + { } +}; + +void usage() { + fprintf(stderr, +"usage: ninja [options] target\n" +"\n" +"options:\n" +" -g output graphviz dot file for targets and exit\n" +" -i FILE specify input build file [default=build.ninja]\n" + ); +} + +struct RealFileReader : public ManifestParser::FileReader { + bool ReadFile(const string& path, string* content, string* err) { + return ::ReadFile(path, content, err) == 0; + } +}; + +int main(int argc, char** argv) { + const char* input_file = "build.ninja"; + + int opt; + bool graph = false; + while ((opt = getopt_long(argc, argv, "ghi:", options, NULL)) != -1) { + switch (opt) { + case 'g': + graph = true; + break; + case 'i': + input_file = optarg; + break; + case 'h': + default: + usage(); + return 1; + } + } + if (optind >= argc) { + fprintf(stderr, "expected target to build\n"); + usage(); + return 1; + } + argv += optind; + argc -= optind; + + char cwd[PATH_MAX]; + if (!getcwd(cwd, sizeof(cwd))) { + perror("getcwd"); + return 1; + } + + State state; + RealFileReader file_reader; + ManifestParser parser(&state, &file_reader); + parser.set_root(cwd); + string err; + if (!parser.Load(input_file, &err)) { + fprintf(stderr, "error loading '%s': %s\n", input_file, err.c_str()); + return 1; + } + + if (graph) { + GraphViz graph; + graph.Start(); + for (int i = 0; i < argc; ++i) + graph.AddTarget(state.GetNode(argv[i])); + graph.Finish(); + return 0; + } + + Builder builder(&state); + for (int i = 0; i < argc; ++i) { + if (!builder.AddTarget(argv[i], &err)) { + if (!err.empty()) { + fprintf(stderr, "%s\n", err.c_str()); + return 1; + } else { + // Added a target that is already up-to-date; not really + // an error. + } + } + } + + bool success = builder.Build(&err); + if (!err.empty()) { + printf("build stopped: %s.\n", err.c_str()); + } + + return success ? 0 : 1; +} |