Развитие мысли от
http://purebasic.info/phpBB3ex/viewtopic.php?f=7&t=4274&start=90#p82048Как использовать:
1) Переименовываем polink.exe => polink_real.exe
2) На его место кладем наш изврат, назвав соответственно polink.exe
Принцип работы:
1) Парсит командную строку линкера, библиотеки складывает в список
2) пытается отключать по очереди каждую библиотеку, и слинковать без нее.
3) при удачном отключении повторяет с оставшимися (на предмет перекрестных ссылок)
работает очень долго (100500 запусков линкера)
если запуск из IDE (выходной файл PureBasic_Compilation*.exe) линкует как есть.
результат любимого пустого окна:
длина: 18944
Удалены:
StringUtility.lib
UnicodeFunctions.lib
MSVCRT.lib
KERNEL32.lib
COMDLG32.lib
ADVAPI32.lib
COMCTL32.lib
OLEAUT32.lib
System.lib
Date.lib
OLEAUT32.LIB
ADVAPI32.LIB
SHELL32.LIB
UUID.LIB
SHELL32.LIB
WINMM.LIB
лог работы можно глянуть в папке компилятора (polink.log)
собрано и опробовано под PB5.31.
Код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| EnableExplicit OpenConsole() Global GWrkDir$ = GetCurrentDirectory() Global GMyDir$ = GetPathPart(ProgramFilename()) Global GRealExe$ = GMyDir$ + "polink_real.exe" Global GLogName$ = GMyDir$ + "polink.log" DeleteFile(GLogName$, #PB_FileSystem_Force) Global GLogFile = OpenFile(#PB_Any, GLogName$) Structure Libs name$ use.i EndStructure Global NewList GLibs.Libs(), GComStrStatic$, GExitCode ;парсит командную строку ;основные команды идут в ComStrStatic$ ;библиотеки идут в Libs() Procedure ParseCommandString() Protected tmp$, i, count count = CountProgramParameters() - 1 For i=0 To count tmp$ = ProgramParameter(i) If Left(tmp$,1)="/" Or tmp$="PureBasic.obj" GComStrStatic$ + tmp$ + " " Else AddElement(GLibs()) GLibs()\name$=tmp$ GLibs()\use=#True EndIf Next EndProcedure ;собирает полную командную строку Procedure$ AllComStr() Protected result$ = GComStrStatic$ PushListPosition(GLibs()) ForEach GLibs() If GLibs()\use result$ + " " + GLibs()\name$ EndIf Next PopListPosition(GLibs()) ProcedureReturn result$ EndProcedure ;запускает истенный линкир и возвращает успешность сборки Procedure RunRealLink() Protected ComStr$ = AllComStr() WriteStringN(GLogFile, "ComStr:<" + ComStr$ + ">") Protected realPrg = RunProgram(GRealExe$, ComStr$, GWrkDir$, #PB_Program_Open|#PB_Program_Read|#PB_Program_Write|#PB_Program_Error) While ProgramRunning(realPrg) Protected tmp$ = ReadProgramError(realPrg, #PB_Ascii) If Len(tmp$) ConsoleError(tmp$) WriteStringN(GLogFile, "[ERR] " + tmp$) EndIf If AvailableProgramOutput(realPrg) tmp$ = ReadProgramString(realPrg, #PB_Ascii) PrintN(tmp$) WriteStringN(GLogFile, "[STD] " + tmp$) EndIf Delay(1) Wend Protected exitCode = ProgramExitCode(realPrg) WriteStringN(GLogFile, "ExitCode: " + Str(exitCode)) ProcedureReturn exitCode EndProcedure ;попытка выкинуть Libs(position) ;в случае успеха, все предыдущие. Procedure DelLib(Position) Protected i SelectElement(GLibs(), Position) If GLibs()\use GLibs()\use = 0 GLibs()\use = RunRealLink() If Not GLibs()\use And Position For i=1 To Position DelLib(i-1) Next EndIf EndIf EndProcedure ParseCommandString() ;проверяем с полным набором GExitCode = RunRealLink() ;если запуск из IDE If FindString(GComStrStatic$,"PureBasic_Compilation",#PB_String_NoCase) End GExitCode EndIf ;если с полным набором не собирается, сразу выходим If GExitCode End GExitCode EndIf ;если с полным компилируется, пытаемся выкинуть либы Define i, count = ListSize(GLibs())-1 For i=0 To count DelLib(i) Next ;финальная сборка с тем что осталось WriteStringN(GLogFile, "Final pass:") GExitCode = RunRealLink() WriteStringN(GLogFile, "Libs Excluded:") ForEach GLibs() If Not GLibs()\use WriteStringN(GLogFile, GLibs()\name$) EndIf Next WriteStringN(GLogFile, "End") End GExitCode ; IDE Options = PureBasic 5.31 (Windows - x86) ; ExecutableFormat = Console ; CursorPosition = 53 ; Folding = o ; Executable = polink.exe ; DisableDebugger ; CompileSourceDirectory |
зы. это конечно не путь "настоящего джедая", а скорее ананистические припадки, но работает
по хорошему надо создать символьную карту для всех либ, и по ней уже вычислять зависимости(возмется кто-нить?)