무슨 일인지 보자, 시도 해봐
$ 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는 C 및 Haskell 라이브러리의 동적 연결에 대한 지원을 얻었습니다 . 대부분의 배포판은 이제 Haskell 라이브러리의 동적 연결을 지원하기 위해 빌드 된 GHC 버전을 배포합니다. 공유 된 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...
그리고, voilà!
$ 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 파일을 얻을 수 있으며, 이는 정적으로 링크 된 라이브러리의 크기를 더욱 줄일 수 있습니다. -split-objs를 사용하여 GHC를 빌드해야하는데, 일부 시스템에서는이를 잊어 버립니다.