มาดูกันว่ามีอะไรบ้างลอง
$ du -hs A
13M A
$ file A
A: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.27, not stripped
$ ldd A
linux-vdso.so.1 => (0x00007fff1b9ff000)
libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0x00007fb21f418000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x00007fb21f0d9000)
libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00007fb21ee6d000)
libGL.so.1 => /usr/lib/libGL.so.1 (0x00007fb21ebf4000)
libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fb21e988000)
libm.so.6 => /lib/libm.so.6 (0x00007fb21e706000)
...
คุณเห็นจากldd
เอาต์พุตที่ GHC สร้างไฟล์ปฏิบัติการที่เชื่อมโยงแบบไดนามิก แต่เฉพาะไลบรารี C เท่านั้นที่เชื่อมโยงแบบไดนามิก ! ไลบรารี Haskell ทั้งหมดจะถูกคัดลอกแบบคำต่อคำ
นอกเหนือจาก: เนื่องจากนี่เป็นแอปที่เน้นกราฟิกมากฉันจึงรวบรวมด้วย ghc -O2
มีสองสิ่งที่คุณทำได้
สัญลักษณ์การลอก
วิธีง่ายๆ: ดึงไบนารีออก:
$ strip A
$ du -hs A
5.8M A
Strip ละทิ้งสัญลักษณ์จากอ็อบเจ็กต์ไฟล์ โดยทั่วไปจำเป็นสำหรับการดีบักเท่านั้น
ไลบรารี Haskell ที่เชื่อมโยงแบบไดนามิก
การสนับสนุนเมื่อเร็ว ๆ นี้ได้รับ GHC สำหรับเชื่อมโยงแบบไดนามิกของทั้งสองซีและ Haskell ห้องสมุด ปัจจุบัน distros ส่วนใหญ่แจกจ่าย GHC เวอร์ชันที่สร้างขึ้นเพื่อรองรับการเชื่อมโยงแบบไดนามิกของไลบรารี Haskell ไลบรารี Haskell ที่ใช้ร่วมกันอาจใช้ร่วมกันระหว่างโปรแกรม Haskell จำนวนมากโดยไม่ต้องคัดลอกลงในไฟล์ปฏิบัติการในแต่ละครั้ง
ในขณะที่เขียน Linux และ Windows ได้รับการสนับสนุน
ในการอนุญาตให้เชื่อมโยงไลบรารี Haskell แบบไดนามิกคุณต้องคอมไพล์ด้วย-dynamic
ดังนี้:
$ ghc -O2 --make -dynamic A.hs
นอกจากนี้ไลบรารีใด ๆ ที่คุณต้องการแชร์ควรสร้างด้วย--enabled-shared
:
$ cabal install opengl --enable-shared --reinstall
$ cabal install glfw --enable-shared --reinstall
และคุณจะจบลงด้วยไฟล์ปฏิบัติการที่เล็กกว่ามากซึ่งมีทั้งการอ้างอิง C และ Haskell แก้ไขแบบไดนามิก
$ ghc -O2 -dynamic A.hs
[1 of 4] Compiling S3DM.V3 ( S3DM/V3.hs, S3DM/V3.o )
[2 of 4] Compiling S3DM.M3 ( S3DM/M3.hs, S3DM/M3.o )
[3 of 4] Compiling S3DM.X4 ( S3DM/X4.hs, S3DM/X4.o )
[4 of 4] Compiling Main ( A.hs, A.o )
Linking A...
และ voila!
$ du -hs A
124K A
ซึ่งคุณสามารถตัดให้เล็กลงได้:
$ strip A
$ du -hs A
84K A
ไฟล์ปฏิบัติการที่น่าทึ่งสร้างขึ้นจากชิ้นส่วน C และ Haskell ที่เชื่อมโยงแบบไดนามิกจำนวนมาก:
$ ldd A
libHSOpenGL-2.4.0.1-ghc7.0.3.so => ...
libHSTensor-1.0.0.1-ghc7.0.3.so => ...
libHSStateVar-1.0.0.0-ghc7.0.3.so =>...
libHSObjectName-1.0.0.0-ghc7.0.3.so => ...
libHSGLURaw-1.1.0.0-ghc7.0.3.so => ...
libHSOpenGLRaw-1.1.0.1-ghc7.0.3.so => ...
libHSbase-4.3.1.0-ghc7.0.3.so => ...
libHSinteger-gmp-0.2.0.3-ghc7.0.3.so => ...
libHSghc-prim-0.2.0.0-ghc7.0.3.so => ...
libHSrts-ghc7.0.3.so => ...
libm.so.6 => /lib/libm.so.6 (0x00007ffa4ffd6000)
librt.so.1 => /lib/librt.so.1 (0x00007ffa4fdce000)
libdl.so.2 => /lib/libdl.so.2 (0x00007ffa4fbca000)
libHSffi-ghc7.0.3.so => ...
จุดสุดท้าย: แม้ในระบบที่มีการลิงก์แบบคงที่เท่านั้นคุณสามารถใช้ -split-objsเพื่อรับไฟล์. o หนึ่งไฟล์ต่อฟังก์ชันระดับบนสุดซึ่งสามารถลดขนาดของไลบรารีที่ลิงก์แบบสแตติกได้มากขึ้น ต้องสร้าง GHC ด้วย -split-objs ซึ่งบางระบบลืมที่จะทำ