Build tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cc 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //#bb ldlibs := -lpthread
  2. #include <getopt.h>
  3. #include <iostream>
  4. #include "SourceFile.h"
  5. #include "BBParser.h"
  6. #include "parallel.h"
  7. #include "toolchain.h"
  8. #include "globals.h"
  9. #include "logger.h"
  10. #include "build.h"
  11. static void printState(const std::vector<SourceFile> &sources) {
  12. for (auto &source: sources) {
  13. std::cout << source.dir() << '/' << source.name() << ":\n";
  14. for (auto &kv: source.vars()) {
  15. std::cout << " " << kv.first << ":\n";
  16. for (auto &val: kv.second) {
  17. std::cout << " " << val << '\n';
  18. }
  19. }
  20. }
  21. }
  22. static bool compileAndLink(const build::BuildConf &conf, toolchain::TargetType targetType) {
  23. std::string targetPath = toolchain::targetFilePath(
  24. targetType, conf.targetName, conf.outDir);
  25. if (build::compile(conf) || !sys::fileExists(targetPath)) {
  26. build::link(conf, targetType);
  27. return true;
  28. }
  29. return false;
  30. }
  31. int main(int argc, char **argv) {
  32. logger::LogContext logCtx = logger::init();
  33. std::string outDir = "bbbuild";
  34. int jobs = parallel::coreCount();
  35. std::string workDir = "";
  36. std::string target = "";
  37. enum class Action {
  38. BUILD, PRINT_STATE,
  39. };
  40. Action action = Action::BUILD;
  41. const char *shortopts = "hvo:j:C:cp";
  42. const struct option opts[] = {
  43. { "help", no_argument, NULL, 'h' },
  44. { "verbose", no_argument, NULL, 'v' },
  45. { "output", required_argument, NULL, 'o' },
  46. { "jobs", required_argument, NULL, 'j' },
  47. { "directory", required_argument, NULL, 'C' },
  48. { "target", required_argument, NULL, 't' },
  49. { "print-state", no_argument, NULL, 'p' },
  50. {},
  51. };
  52. const char usage[] =
  53. "Usage: bbbuild [options...] [sources]\n"
  54. "\n"
  55. " -h, --help "
  56. "Show this help text.\n"
  57. " -v, --verbose "
  58. "Show every command as it's executing.\n"
  59. " -o, --output <dir> "
  60. "Set output directory. Default: bbbuild\n"
  61. " -j, --jobs <count> "
  62. "Set the number of jobs run simultaneously. "
  63. "Default: the number of cores in the machine.\n"
  64. " -C, --directory <dir> "
  65. "Change directory before doing anything else.\n"
  66. " -p, --print-state "
  67. "Print the state instead of building.\n";
  68. // Parse options from argv
  69. while (1) {
  70. int optidx;
  71. int c = getopt_long(argc, argv, shortopts, opts, &optidx);
  72. if (c < 0) {
  73. break;
  74. }
  75. switch (c) {
  76. case 'h':
  77. puts(usage);
  78. return 0;
  79. case 'v':
  80. global::verbose += 1;
  81. break;
  82. case 'o':
  83. outDir = optarg;
  84. break;
  85. case 'j':
  86. jobs = atoi(optarg);
  87. if (jobs <= 0) {
  88. fprintf(stderr, "Can't run %i jobs.\n", jobs);
  89. return 1;
  90. }
  91. break;
  92. case 'C':
  93. workDir = optarg;
  94. break;
  95. case 'p':
  96. action = Action::PRINT_STATE;
  97. break;
  98. default:
  99. printf("Unknown option: '%c'.\n%s", (char)c, usage);
  100. return 1;
  101. }
  102. }
  103. // Change directory?
  104. if (workDir.size() > 0) {
  105. fprintf(stderr, "Entering directory '%s'\n", workDir.c_str());
  106. sys::chdir(workDir);
  107. }
  108. // Read everything related to the build configuration,
  109. // finding all source files and reading their configs
  110. std::vector<std::string> args;
  111. while (optind < argc) {
  112. args.push_back(argv[optind++]);
  113. }
  114. build::BuildConf conf = build::readBuildConf(std::move(outDir), jobs, args);
  115. conf.numJobs = jobs;
  116. switch (action) {
  117. case Action::BUILD:
  118. // TODO: Support more types than BINARY
  119. if (compileAndLink(conf, toolchain::TargetType::BINARY)) {
  120. build::writeCompileCommands(conf);
  121. } else {
  122. logger::log("Nothing to do.");
  123. }
  124. break;
  125. case Action::PRINT_STATE:
  126. printState(conf.sources);
  127. break;
  128. }
  129. }