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 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. bufio::IFStream f(confPath);
  20. BXParser parser(f);
  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. std::vector<std::string> command = linkCommand(outDir);
  38. std::string dirPath = sys::dirname(outDir + '/' + path_);
  39. BXVariables newCachedVars = {
  40. { "command", command},
  41. };
  42. bufio::OFStream f(confPath(outDir));
  43. BXWriter writer(f);
  44. writer.write(newCachedVars);
  45. sys::mkdirp(dirPath);
  46. sys::ProcConf conf;
  47. conf.print = true;
  48. conf.prefix = "(LD)";
  49. sys::execute(command, conf);
  50. }
  51. toolchain::FileType LinkStep::doGetLinkType() {
  52. for (auto &child: children()) {
  53. if (child->linkType() == toolchain::FileType::CXX) {
  54. return toolchain::FileType::CXX;
  55. }
  56. }
  57. return toolchain::FileType::C;
  58. }
  59. std::vector<std::string> &LinkStep::linkCommand(const std::string &outDir) {
  60. if (hasLinkCommand_) {
  61. return linkCommand_;
  62. }
  63. std::vector<std::string> objs;
  64. for (auto &dep: deps_) {
  65. for (auto &obj: dep->publicObjects(outDir)) {
  66. objs.push_back(obj);
  67. }
  68. }
  69. // TODO: Don't use FileType::CXX hard-coded here
  70. linkCommand_ = toolchain::getLinkCommand(
  71. publicLDFlags(outDir), publicLDLibs(outDir),
  72. linkType(), type_, objs, path_, outDir);
  73. hasLinkCommand_ = true;
  74. return linkCommand_;
  75. }