छोटे Haskell कार्यक्रम को GHC के साथ विशाल बाइनरी में संकलित किया गया


127

यहां तक ​​कि तुच्छ रूप से छोटे हास्केल कार्यक्रम विशाल निष्पादन योग्य में बदल जाते हैं।

मैंने एक छोटा सा कार्यक्रम लिखा है, जिसे 7 एमबी तक के आकार के साथ बाइनरी में (जीएचसी के साथ) संकलित किया गया था!

विशाल बाइनरी को संकलित करने के लिए एक छोटे हास्केल कार्यक्रम का क्या कारण हो सकता है?

क्या, अगर कुछ भी हो, तो क्या मैं इसे कम कर सकता हूं?


2
क्या आपने इसे छीनने की कोशिश की है?
फ्रेड फू

21
stripप्रतीक तालिका को हटाने के लिए बाइनरी पर प्रोग्राम चलाएं ।
फ्रेड फू

1
@ tm1rbt: भागो strip test। यह कमांड प्रोग्राम से कुछ डीबग जानकारी को निकालता है और इसे छोटा बनाता है।
फ़ूज

8
एक तरफ के रूप में 3 डी गणित पुस्तकालय में अपने डेटा प्रकार प्रदर्शन कारणों के लिए सख्त होना चाहिए: data M3 = M3 !V3 !V3 !V3और data V3 = V3 !Float !Float !Float। के साथ संकलित करें ghc -O2 -funbox-strict-fields
डॉन स्टीवर्ट

8
इस पोस्ट में मेटा पर चर्चा की गई है ।
पैट्रिक हॉफमैन

जवाबों:


215

आइए देखें कि क्या चल रहा है, कोशिश करें

  $ 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 -O2

दो चीजें हैं जो आप कर सकते हैं।

अलग करना प्रतीकों

एक आसान समाधान: बाइनरी पट्टी:

$ strip A
$ du -hs A
5.8M    A

स्ट्रीप ऑब्जेक्ट फ़ाइल से प्रतीकों को हटाता है। वे आम तौर पर केवल डिबगिंग के लिए आवश्यक हैं।

गतिशील रूप से हास्केल पुस्तकालयों से जुड़ा हुआ है

हाल ही में, जीएचसी ने सी और हास्केल पुस्तकालयों के गतिशील लिंकिंग के लिए समर्थन प्राप्त किया है । अधिकांश डिस्ट्रोस अब HHCell पुस्तकालयों के गतिशील लिंकिंग का समर्थन करने के लिए निर्मित GHC के एक संस्करण को वितरित करते हैं। साझा हास्केल पुस्तकालयों को हर बार निष्पादन योग्य में कॉपी किए बिना, कई हास्केल कार्यक्रमों के बीच साझा किया जा सकता है।

लेखन के समय लिनक्स और विंडोज समर्थित हैं।

हास्केल पुस्तकालयों को गतिशील रूप से जोड़ने की अनुमति देने के लिए, आपको उन्हें इस -dynamicतरह से संकलित करने की आवश्यकता है :

 $ ghc -O2 --make -dynamic A.hs

इसके अलावा, आपके द्वारा साझा की जाने वाली कोई भी लाइब्रेरी को इसके साथ बनाया जाना चाहिए --enabled-shared:

 $ cabal install opengl --enable-shared --reinstall     
 $ cabal install glfw   --enable-shared --reinstall

और आप एक बहुत छोटे निष्पादन योग्य के साथ समाप्त हो जाएंगे, जिसमें सी और हास्केल निर्भरता दोनों गतिशील रूप से हल हो जाएंगे।

$ 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...

और, आवाज!

$ du -hs A
124K    A

जिसे आप छोटा करने के लिए पट्टी कर सकते हैं:

$ strip A
$ du -hs A
84K A

एक्नेसी वेन्से निष्पादन योग्य, कई गतिशील रूप से जुड़े सी और हास्केल टुकड़ों से निर्मित:

$ 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 की जरूरत है, जिसके साथ -plplit-objs बनाया जाना चाहिए, जिसे कुछ सिस्टम करना भूल जाते हैं।


7
मैक पर ghc आने के कारण डायनामिक लिंकिंग कब है?
कार्टर ताज़ियो शोनवल्ड

1
... cabal installडिफ़ॉल्ट रूप से स्थापित बाइनरी को पट्टी नहीं करता है ?
hvr

1
ऐसा करने पर विंडोज परिणामी फाइल को अन-रन करने योग्य बनाता है, यह गुम libHSrts-ghc7.0.3.dll के बारे में शिकायत करता है
is7s

3
क्या यह बाइनरी इन प्रक्रियाओं के बाद अन्य लिनक्स मशीनों पर काम कर रही होगी?
ア ッ ア ア

1
2011 से हाय ओपी! मैं भविष्य से हूं और बता सकता हूं कि Ubuntu 16.04 पर पंडोक निष्पादन योग्य 50 एमबी वसा है और यह संकुल के आधार पर परिवर्तित नहीं होने जा रहा है ।ubuntu.com/zesty/pandoc । निकट-भविष्य के स्व और दूसरों को संदेश: संपर्क पैकेज अनुरक्षक और पूछें कि enable-sharedक्या विचार किया गया था। launchpad.net/ubuntu/+source/pandoc/+bugs
स्टीफन गौरीचॉन

11

हास्केल डिफ़ॉल्ट रूप से स्थैतिक लिंकिंग का उपयोग करता है। यह, OpenGL के पूरे बाइंडिंग को आपके प्रोग्राम में कॉपी किया जाता है। जैसा कि वे काफी बड़े हैं, आपका कार्यक्रम अनावश्यक रूप से फुलाया जाता है। आप डायनेमिक लिंकिंग का उपयोग करके इसके आसपास काम कर सकते हैं, हालांकि यह डिफ़ॉल्ट रूप से सक्षम नहीं है।


5
आप इसके चारों ओर काम करने के लिए पुस्तकालयों को गतिशील रूप से लिंक कर सकते हैं। यह निश्चित नहीं है कि यह क्यों महत्वपूर्ण है क्या डिफ़ॉल्ट है, झंडा काफी सरल है।
थॉमस एम। डुबिसन

4
समस्या यह है कि "आपके द्वारा साझा की जाने वाली कोई भी लाइब्रेरी --enabled-shared" के साथ निर्मित होनी चाहिए, इसलिए यदि आपका हास्केल प्लेटफ़ॉर्म आपके द्वारा बनाए गए पुस्तकालयों के साथ आता है, --enabled sharedतो आपको आधार पुस्तकालयों को फिर से तैयार करना होगा जो काफी दर्दनाक हो सकते हैं।
nponeccop
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.