Hogyan lehet TC alá file ki/be tömörgető (packager) plugint írni? Ide gereblyéztem össze a tudást. Cygwin alá nem ment, de Visual Studio-val végül is sikerült. Összeszedtem, hogy milyen függvényeket hív meg a TC a WCX-re keresztelt DLL-ben. Azt is leírtam, hogyan kell installálós zip-pet készíteni. Jó szórakázást!
Kis infó:
Példa egy packager lesz:
(Windows dll forgatás mikéntje, amire most nem lesz szükségünk.)
Csak a mihez tartást végett megnéztem:
$ file *.wcx
checksum.wcx: PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit
A csomagban dsw file van, ami valami vindoz-os környezethez a "Makefile". Ebből és normál Makefile-t szertnék kanyarítani. Borzolás közben ezt találtam:
Convert dsw to Makefile: gawk -f C:\msys\1.0\bin\dsw2mak.awk CDP.dsw
Hol van ez az awk szkript? Talán itt:
http://sourceforge.net/projects/mingw/files/MinGW/Utilities/mingw-utils
Ez a legfrissebb:
http://sourceforge.net/projects/mingw/files/MinGW/Utilities/mingw-utils/mingw-utils-0.4-1/mingw-utils-0.4-1-mingw32-src.tar.lzma/download
Letölt, kitömörget:
$ 7z x mingw-utils-0.4-1-mingw32-src.tar.lzma
A tar file-ban itt találtam meg:
mingw-utils-0.4-1-mingw32-src.tar: \mingw-utils-0.4\scripts\dsw2mak.in
A checksum csomag alatt kiadtam a:
$ awk -f ../dsw2mak.awk checksum.dsw
Megcsinálta a Makefile-t és minden kódhoz a *.mak file-t.
Hát akkor
$ make
...
Dob egy csomó warning-ot. Pl.
parser.c:47: warning: comparison between signed and unsigned
No igen... Hmmm... Tipikus... Ezzel most nem foglalkozunk.
És egy hibát: wcx.c:36:20: error: direct.h: No such file or directory
Keressünk egy kicsit:
$ find /usr/include/ -name direct.h
/usr/include/mingw/direct.h
wcx.c 36.sor javít: #include <mingw/direct.h>
Re-make. Most más fáj neki:
/usr/include/mingw/direct.h:15:20: error: _mingw.h: No such file or directory
Talán nem meglepő, hogy
$ find /usr/include/ -name _mingw.h
/usr/include/mingw/_mingw.h
15. sor javít: #include <mingw/_mingw.h>
(Persze csinálhatnék linkeket is eggyel feljebb...)
Alakul. Most a dllwrap program sírt egy keveset:
dllwrap: no export definition file provided.
Úgy néz ki, hogy eljárt felette az idő (deprecated) és ezt ajánlatik használni helyette:
"gcc -shared"
Hát nézzük meg. Próba. A checksum.mak-ben cserélés:
#LD=dllwrap
#LDFLAGS=
LD=gcc
LDFLAGS=-shared
Két helyen is meg kell csinálni! Egyszer a Debug és másszor a Release szekcióban!
Jön a make.
Most már csak ezért sírt:
/usr/lib/gcc/i686-pc-cygwin/4.3.4/../../../../i686-pc-cygwin/bin/ld: cannot open output file Debug/checksum.wcx: No such file or directory
Csináltam neki egy Debug (és Release) könyvtárat, ne rinyáljon! És így már leferdült!
Mivel béna vagyok, a mak file elejére beírtam:
CFG=checksum - Win32 Release
És make clean, majd make. Lefordult!
Most jön a puding próbája! Az evés!
Átnevezem a plug-in-t a Release könyvtárban checksum_mine.wcx-re, mert egy ilyen nevű már van és bemásolom ide: c:\Program Files\totalcmd\plugins\. (Mondjuk érdekes, hogy az eredeti checksum.wcx 8KiB, ez meg vagy 40kB. Vajon miért? Valszeg, mert a Visual Studio fordítás a windows beépített dll-jeit hívja. Plusz UPX.)
Installáltam a Configuration -> options... -> Operation / Plugins / Packager plugins (.WCX) szekció. Már majdnem végigcsinálta, amikor dobott egy MessageBox-ot, hogy "This is not a valid plugin!". Bakter!
Csináltam egy makrót az elejére, amit minden exportálandó függvény elejére odatettem:
#define WCX_API __declspec(dllexport)
wcx.def-be ezeket a függvényeket jelöltem export-ra:
EXPORT
OpenArchive
ReadHeader
ProcessFile
CloseArchive
PackFiles
; DeleteFiles
GetPackerCaps
ConfigurePacker
SetChangeVolProc
SetProcessDataProc
Újra forgatva. Megnéztem, hogy ez milyen dll-ekre hivatkozik (van egy ilyen TotalCommander pulgin, amivel mindenféléket meg lehet nézni: fileinfo). Ezek a cygwin1.dll és a cyggcc_s-1.dll. Ezeket is mellé másoltam, hogy ne hiányozzanak. Ismét megnézve a fileinfo-val, most már megtalálja.
Sajnos amikor megpróbálom hozzáadni a Configuration / Options / Plugins / Packager plugins -> Configure: xxx -hez a New Type-pal hozzárendelem a lefordított kódot. Sajnos valami miatt nem tudja betölteni. Csak teker és semmi. Sajnos a kód teljes kiherélése után sem töltötte be.
Tovább próbálkoztam a linker helyett a dllwrap-ot használni. Beírtam a linker sora helyett, hogy:
dllwrap -v -def wcx.def -o Release/checksum_mine.wcx --mno-cygwin $(OBJS)
De ez sem segített a bajomon. Nincs új ötletem...
(Bezzeg Visual Studio-val leforgatva gond nélkül megy. És működik is.)
Megpróbáltam cygwin1.dll használata nélkül is lefordítani. Bizonyos helyeken azt írják, hogy lehet, másol meg azt, hogy nem. Megpróbáltam, de nem sikerült a cygwin-es dll-eket kigyaknom: -mno-cygwin és -mwindows. Én a cygwin-es gcc-ben nem találtam ezeket, pedig több oldal is hivatkozik rájuk! A cygwin oldal szerint viszont nem lehet ezek nélküli dll-t, exe-t forgatni. Most mi az igazság? :(
Ha letöltöttem a példa CatalogMaker forrását-t (ez is egy jó kis példa), akkor Visual Studióval simán fordul. Minden exportált függvény elejére egy MessageBox-ot tettem és kb. így néz ki egy archive file megnyitás:
- OpenArchive - archiven file name. Itt többnyire mindenféle buffereléssel szoktak küzdeni. Én ezt kihagytam és simán fopen-nel nyitottam meg a filet és a FILE *-ot adtam vissza HANDLE-ként. Tökkéletesen működik és nem kell a buffereléssel tökölni. Viszont az msvcr80.dll-t hozzáfordítja. Ez alapban nincs a /windows/system32 könyvtárban. A legjobban járunk, ha keresünk egyet a gépünkön és oda másoljuk.
- SetProcessDataProc - progress bar callback function. Ezt érdemes eltenni, hogy a kicsomagolás közben legyen kék kukac a képernyőn
- SetChangeVolProc - Ha szétvágott archive-ot készítünk, akkor ezt kell hívni. Ebből egy sima return-nak léphetünk ki.
- ReadHeaderEx - A file header infójának egyes sorainak feldolgozása (file neve, mérete, update dátum). Minden file-ban levő file-ra egyszer lefut.
- ProcessFile - A ReadHeaderEx-ben visszaadott file-ok feldolgozása egyenként. Első menetben PK_SKIP, kitömörgetéskor a kijelölt file-okra PK_EXTRACT-tal meghívva. A file épségének tesztelésekor pedig PK_TEST opcióval van meghívva.
- CloseArchive
Amikor megvan a végleges forgatás, akkor még lehet egyet tömöríteni rajta. Install UPX csomag a cygwin alatt (egy jobban tömörgető verzió fordításának történetét is billnetyűbe öntöttem). Ez egy dll tömörgető eszköz. Kb. 50%-ot nyom a dll méretén. Meghívása ennyi: "upx -v -9 checksum.wcx". -o-val másik kimenetet is definiálhatunk neki.
Ha megvan a wcx, akkor egy install csomagot is összeállíthatunk. Ehhez szükség van egy pliginst.inf file-ra, ami így néz ki:
[plugininstall]
description=Valami szép hosszú leírás, hogy mit is csinál a plugin
type=wcx
file=EzANeve.wcx
defaultdir=EzANeve
defaultextension=kiterj
Ez a "kiterj" kiterjesztésű file-okra működik. Ezt egy zip file-ba kell tenni a wcx-szel. Esetleg még egy ReadMe file-t is belecsomagolhatunk. Ha ez megvan, akkor TotalCommander-ben egy ilyen zip file-ra kattintva megkérdezi, hogy telepítse-e. Ha nemet válaszolunk, akkor legközelebb már csak a zip file touch-olása után fogja újból megkérdezni.
Inst(all)álom alássan minden nap!
+jegyzések