1 module gccbuild.cleanup; 2 3 import scriptlike, gccbuild, painlessjson, std.json; 4 5 void cleanupToolchain(Duration totalTime) 6 { 7 startSection("Finalizing toolchain"); 8 9 removeFolders(); 10 stripTargetLibraries(); 11 stripHostBinaries(); 12 13 if (build.cleanup.matchesBuildType && !build.cleanup.commands.empty) 14 { 15 writeBulletPoint("Executing custom cleanup commands"); 16 auto oldCWD = pushCWD(toolchainDir); 17 runBuildCommands(build.cleanup.commands); 18 endBulletPoint(); 19 } 20 21 writeBulletPoint("Writing GCC information"); 22 auto info = GCCInfo(build.target, build.host, build.multilibs); 23 auto json = info.toJSON(); 24 writeFile(toolchainDir ~ "gcc_info.json", toJSON(&json, true)); 25 endBulletPoint(); 26 27 endSectionLog(); 28 writelnLog(); 29 writelnLog("Total execution time: ", totalTime); 30 closeLog(); 31 32 writeBulletPoint("Compressing log file"); 33 runCollectLog("xz -9 " ~ logFilePath.toString()); 34 runCollectLog( 35 "mv " ~ (logFilePath.toString() ~ ".xz") ~ " " ~ (toolchainDir ~ "build.log.xz").toString()); 36 endBulletPoint(); 37 38 endSection(false); 39 } 40 41 struct GCCInfo 42 { 43 string target, host; 44 MultilibEntry[] multilibs; 45 } 46 47 void removeFolders() 48 { 49 writeBulletPoint("Removing unnecessary folders"); 50 if ((build.cleanup.matchesBuildType && !build.cleanup.remove.empty) 51 || (build.variantCleanup && !build.variantCleanup.remove.empty)) 52 { 53 if (build.cleanup.matchesBuildType) 54 { 55 foreach (entry; build.cleanup.remove) 56 { 57 tryRmdirRecurse(toolchainDir ~ entry.substituteVars); 58 } 59 } 60 if (build.variantCleanup) 61 { 62 foreach (entry; build.variantCleanup.remove) 63 { 64 tryRmdirRecurse(toolchainDir ~ entry.substituteVars); 65 } 66 } 67 } 68 else 69 { 70 tryRmdirRecurse(sysrootDirWithPrefix ~ "bin"); 71 tryRmdirRecurse(sysrootDirWithPrefix ~ "libexec"); 72 tryRmdirRecurse(sysrootDirWithPrefix ~ "sbin"); 73 tryRmdirRecurse(sysrootDirWithPrefix ~ "etc"); 74 tryRmdirRecurse(sysrootDirWithPrefix ~ "var"); 75 tryRmdirRecurse(sysrootDirWithPrefix ~ "share"); 76 tryRmdirRecurse(sysrootDir ~ "bin"); 77 tryRmdirRecurse(sysrootDir ~ "libexec"); 78 tryRmdirRecurse(sysrootDir ~ "sbin"); 79 tryRmdirRecurse(sysrootDir ~ "etc"); 80 tryRmdirRecurse(sysrootDir ~ "var"); 81 tryRmdirRecurse(sysrootDir ~ "share"); 82 tryRmdirRecurse(toolchainDir ~ "etc"); 83 tryRmdirRecurse(toolchainDir ~ "var"); 84 tryRmdirRecurse(toolchainDir ~ "share"); 85 } 86 endBulletPoint(); 87 } 88 89 void stripTargetLibraries() 90 { 91 if (skipStripLibraries) 92 { 93 writeBulletPoint("Stripping target libraries... (skipped)"); 94 return; 95 } 96 writeBulletPoint("Stripping target libraries..."); 97 98 auto oldPath = updatePathVar(binDir); 99 100 if ((build.cleanup.matchesBuildType && !build.cleanup.stripTarget.empty) 101 || (build.variantCleanup && !build.variantCleanup.stripTarget.empty)) 102 { 103 if (build.cleanup.matchesBuildType) 104 { 105 foreach (entry; build.cleanup.stripTarget) 106 { 107 stripPath(toolchainDir ~ entry.substituteVars, build.target ~ "-strip"); 108 } 109 } 110 if (build.variantCleanup) 111 { 112 foreach (entry; build.variantCleanup.stripTarget) 113 { 114 stripPath(toolchainDir ~ entry.substituteVars, build.target ~ "-strip"); 115 } 116 } 117 } 118 else 119 { 120 foreach (multilib; build.multilibs) 121 { 122 auto path = sysrootDirWithPrefix ~ Path("lib") ~ Path(multilib.osFolder); 123 auto path2 = toolchainDir ~ Path(build.target) ~ Path("lib") ~ Path(multilib.osFolder); 124 auto path3 = toolchainDir ~ Path("lib") ~ Path(multilib.osFolder); 125 auto path4 = toolchainDir ~ Path("lib"); 126 stripPath(path, build.target ~ "-strip"); 127 stripPath(path2, build.target ~ "-strip"); 128 stripPath(path3, build.target ~ "-strip"); 129 stripPath(path4, build.target ~ "-strip"); 130 } 131 } 132 restorePathVar(oldPath); 133 endBulletPoint(); 134 } 135 136 void stripHostBinaries() 137 { 138 if (skipStripBinaries) 139 { 140 writeBulletPoint("Stripping host binaries... (skipped)"); 141 return; 142 } 143 writeBulletPoint("Stripping host binaries..."); 144 145 if ((build.cleanup.matchesBuildType && !build.cleanup.stripHost.empty) 146 || (build.variantCleanup && !build.variantCleanup.stripHost.empty)) 147 { 148 if (build.cleanup.matchesBuildType) 149 { 150 foreach (entry; build.cleanup.stripHost) 151 { 152 stripPath(toolchainDir ~ entry.substituteVars, hostStrip, true, false); 153 } 154 } 155 if (build.variantCleanup) 156 { 157 foreach (entry; build.variantCleanup.stripHost) 158 { 159 stripPath(toolchainDir ~ entry.substituteVars, hostStrip, true, false); 160 } 161 } 162 } 163 else 164 { 165 auto path = toolchainDir ~ "bin"; 166 auto path2 = toolchainDir ~ Path(build.target) ~ "bin"; 167 stripPath(path, hostStrip, true, false); 168 stripPath(path2, hostStrip, true, false); 169 } 170 endBulletPoint(); 171 } 172 173 void stripPath(Path path, string stripProgram, bool stripExes = false, bool stripLibs = true) 174 { 175 yapFunc(stripProgram, " ", path); 176 if (!path.exists || !path.isDir) 177 return; 178 179 foreach (entry; path.dirEntries(SpanMode.depth)) 180 { 181 if (!entry.isFile) 182 continue; 183 if (stripLibs && (entry.extension == ".so" || entry.extension == ".dll")) 184 { 185 // Skip linker script files (libc.so) 186 if (!runCollectLog("file -b " ~ entry).canFind("ASCII")) 187 { 188 tryRunCollectLog(stripProgram ~ " " ~ entry); 189 } 190 } 191 else if (stripExes && (entry.extension == ".exe" 192 || runCollectLog("file -b " ~ entry).canFind("executable"))) 193 { 194 tryRunCollectLog(stripProgram ~ " " ~ entry); 195 } 196 } 197 }