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.

LinkStep.cc 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include "LinkStep.h"
  2. #include <string>
  3. #include <fstream>
  4. #include "sys.h"
  5. #include "logger.h"
  6. #include "globals.h"
  7. #include "BXParser.h"
  8. bool LinkStep::checkHasChanged(const std::string &outDir) {
  9. std::string targetPath = toolchain::targetFilePath(type_, path_, outDir);
  10. if (!sys::fileExists(targetPath)) {
  11. return true;
  12. }
  13. std::string confPath = this->confPath(outDir);
  14. if (!sys::fileExists(confPath)) {
  15. return true;
  16. }
  17. BXVariables cachedVariables;
  18. try {
  19. std::ifstream f = sys::ifstream(confPath);
  20. BXParser parser(f, BXParser::FLAG_NONE);
  21. parser.parse(cachedVariables);
  22. } catch (BXParseError &err) {
  23. logger::log(confPath + ": " + err.what());
  24. return true;
  25. }
  26. auto commandIt = cachedVariables.find("command");
  27. if (commandIt == cachedVariables.end()) {
  28. logger::log(confPath + ": Missing 'command' field");
  29. return true;
  30. }
  31. if (linkCommand(outDir) != commandIt->second) {
  32. return true;
  33. }
  34. return false;
  35. }
  36. void LinkStep::doBuild(const std::string &outDir) {
  37. logger::log("Link " + path_);
  38. std::vector<std::string> command = linkCommand(outDir);
  39. std::string dirPath = sys::dirname(outDir + '/' + path_);
  40. BXVariables newCachedVars = {
  41. { "command", command},
  42. };
  43. std::ofstream f = sys::ofstream(confPath(outDir));
  44. BXWriter writer(f);
  45. writer.write(newCachedVars);
  46. sys::mkdirp(dirPath);
  47. sys::execute(command, nullptr, global::verbose >= 1);
  48. }
  49. std::vector<std::string> &LinkStep::linkCommand(const std::string &outDir) {
  50. if (hasLinkCommand_) {
  51. return linkCommand_;
  52. }
  53. std::vector<std::string> objs;
  54. for (auto &dep: deps_) {
  55. for (auto &obj: dep->publicObjects(outDir)) {
  56. objs.push_back(obj);
  57. }
  58. }
  59. // TODO: Don't use FileType::CXX hard-coded here
  60. linkCommand_ = toolchain::getLinkCommand(
  61. publicLDFlags(outDir), publicLDLibs(outDir),
  62. toolchain::FileType::CXX, type_, objs, path_, outDir);
  63. hasLinkCommand_ = true;
  64. return linkCommand_;
  65. }