1 module gccbuild.build.common; 2 3 import gccbuild, scriptlike; 4 5 /** 6 * type is used to lookup arguments for the command in the component 7 */ 8 void runBuildCommands(string[] commands, string[string] extraVars = string[string].init) 9 { 10 auto scriptVars = buildVariables.dup; 11 foreach (key, val; extraVars) 12 scriptVars[key] = val; 13 14 foreach (cmd; commands) 15 { 16 cmd = cmd.substituteVars(scriptVars); 17 if (!cmd.empty) 18 runCollectLog(cmd); 19 } 20 } 21 22 string substituteVars(string text, string[string] vars = string[string].init) 23 { 24 size_t numReplaced; 25 do 26 { 27 text = substituteVars(text, vars, numReplaced); 28 } 29 while (numReplaced != 0); 30 return text; 31 } 32 33 string substituteVars(string text, string[string] vars, out size_t numReplaced) 34 { 35 auto result = appender!string(); 36 37 auto remain = text; 38 numReplaced = 0; 39 while (!remain.empty) 40 { 41 auto parts = remain.findSplit("${"); 42 result ~= parts[0]; 43 remain = parts[2]; 44 45 if (parts) 46 { 47 parts = remain.findSplit("}"); 48 failEnforcec(cast(bool) parts, "Can't find closing } in macro:", text); 49 auto val = parts[0] in vars; 50 failEnforce(val != null, "Couldn't find replacement value for ", 51 parts[0], " in ", text); 52 result ~= *val; 53 remain = parts[2]; 54 numReplaced++; 55 } 56 } 57 58 return result.data; 59 } 60 61 /** 62 * 1) Delete old directory 63 * 2) Create directory 64 * 3) chdir into directory 65 */ 66 auto prepareBuildDir(Component component) 67 { 68 component.buildFolder.tryRmdirRecurse(); 69 component.buildFolder.tryMkdirRecurse(); 70 return component.buildFolder.pushCWD(); 71 } 72 73 auto pushCWD(Path dir, bool autoPop = true) 74 { 75 auto saveDir = getcwd(); 76 dir.chdir(); 77 return RefCounted!(RestoreCWD)(saveDir, autoPop); 78 } 79 80 struct RestoreCWD 81 { 82 private: 83 Path saveDir; 84 bool autoPop; 85 86 public: 87 ~this() 88 { 89 if (autoPop) 90 saveDir.chdir(); 91 } 92 93 void popCWD() 94 { 95 saveDir.chdir(); 96 } 97 } 98 99 string updatePathVar(Path additional, bool prepend = true) 100 { 101 auto oldPath = environment["PATH"]; 102 string newPath; 103 if (prepend) 104 newPath = additional.toString() ~ ":" ~ oldPath; 105 else 106 newPath = oldPath ~ ":" ~ additional.toString(); 107 108 environment["PATH"] = newPath; 109 yap("Updated path: ", oldPath, " => ", newPath); 110 return oldPath; 111 } 112 113 void restorePathVar(string val) 114 { 115 yap("Restore path: ", val); 116 environment["PATH"] = val; 117 }