我有一个项目分为两部分:
可执行部分具有客户端特定代码,但该库具有通用功能,不会在不同的客户端项目中进行更改.
现在我有5个项目在编译时每个都创建一个25 MB的可执行文件,因为GHC将可执行文件和所有依赖项静态编译到一个文件中.
我想要做的是将我的库与所有依赖项静态编译到一个文件中,然后可执行文件可以动态加载.这样外部依赖项的所有.a文件都被编译成一个.so文件.
引用解释我想做什么的引用(从多个C++和C对象文件生成单个.so):
最简单的方法是将它们组合成一个.so文件,方法是组合所有目标文件,或者构建两个静态.a库,然后将它们链接到一个共享库中.
这对GHC来说甚至可能吗?
我一直在寻找不同的解决方案,使用split-objs动态链接所有库,但我似乎无法找到我想做的解决方案.
编辑:添加有关我的设置和我迄今为止尝试过的信息.
我目前正在使用该库的cabal-install版本1.18.1.2和1.18.1.1.
我在沙盒中设置了项目:
$ cabal sandbox init
$ cabal install --dependencies-only
$ cabal configure
Run Code Online (Sandbox Code Playgroud)
这将在我的项目目录中的.cabal-sandbox中安装所有依赖项.在每个依赖文件夹里面都有一个编译的.a文件,参见acid-state-0.12.1作为例子:
?.cabal-sandbox/
?lib/
?x86_64-linux-ghc-7.6.3/
?acid-state-0.12.1/
? Data/
FileIO.hi
libHSacid-state-0.12.1.a
Paths_acid_state.hi
?aeson-0.6.2.1/
?base-unicode-symbols-0.2.2.4/
?base64-bytestring-1.0.0.1/
?blaze-builder-0.3.1.1/
?blaze-html-0.6.1.1/
?blaze-markup-0.5.1.5/
?blaze-textual-0.2.0.8/
?cereal-0.4.0.0/
?clay-0.8/
?clock-0.3/
?dlist-0.5/
?email-validate-1.0.0/
?entropy-0.2.2.4/
?extensible-exceptions-0.1.1.4/
?gd-3000.7.3/
?happstack-lite-7.3.1/
?happstack-server-7.3.1/
?hslogger-1.2.3/
?MissingH-1.2.0.2/
?monad-control-0.3.2.2/
?postgresql-libpq-0.8.2.4/
?postgresql-simple-0.3.8.0/
?safecopy-0.8.2/
?scrypt-0.3.6/
?sendfile-0.7.9/
?system-filepath-0.4.8/
?threads-0.5.0.2/
?time-compat-0.1.0.3/
?transformers-base-0.4.1/
?utf8-string-0.3.7/
Run Code Online (Sandbox Code Playgroud)
就像我在inro中所说的那样,我的项目分为两部分,如我的cabal文件中所示(请注意,删除了一些信息以保持示例更短):
name: myserver
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.8
library
hs-source-dirs: lib
ghc-options: -Wall -fno-warn-orphans -fno-warn-unused-do-bind -threaded
exposed-modules:
Crypto.SimpleScrypt,
Util.Response,
Html.Components,
Storage.Memory,
Storage.Disk
build-depends:
base >=4.6 && <4.7,
bytestring >=0.10 && <0.11,
MissingH >=1.2 && <1.3,
happstack-lite >=7.3 && <7.4,
clay >=0.8 && <0.9,
text >=0.11 && <0.12,
blaze-markup >=0.5 && <0.6,
blaze-html >=0.6 && <0.7,
postgresql-simple >=0.3 && <0.4,
mtl >=2.1 && <2.2,
acid-state >=0.12 && <0.13,
safecopy >=0.8 && <0.9,
containers >=0.5 && <0.6,
scrypt >=0.3 && <0.4,
transformers >=0.3 && <0.4,
happstack-server >=7.3 && <7.4,
time >=1.4 && <1.5,
filepath >=1.3 && <1.4,
directory >=1.2 && <1.3,
gd >=3000.7 && <3000.8,
aeson >=0.6 && <0.7,
email-validate >=1.0 && <1.1,
clock >=0.3 && <0.4,
random >=1.0 && <1.1
executable myserver
hs-source-dirs: app
main-is: App.hs
ghc-options: -Wall -fno-warn-orphans -fno-warn-unused-do-bind -threaded
build-depends:
base >=4.6 && <4.7,
bytestring >=0.10 && <0.11,
MissingH >=1.2 && <1.3,
happstack-lite >=7.3 && <7.4,
clay >=0.8 && <0.9,
text >=0.11 && <0.12,
blaze-markup >=0.5 && <0.6,
blaze-html >=0.6 && <0.7,
postgresql-simple >=0.3 && <0.4,
mtl >=2.1 && <2.2,
acid-state >=0.12 && <0.13,
safecopy >=0.8 && <0.9,
containers >=0.5 && <0.6,
scrypt >=0.3 && <0.4,
transformers >=0.3 && <0.4,
happstack-server >=7.3 && <7.4,
time >=1.4 && <1.5,
filepath >=1.3 && <1.4,
directory >=1.2 && <1.3,
gd >=3000.7 && <3000.8,
aeson >=0.6 && <0.7,
email-validate >=1.0 && <1.1,
clock >=0.3 && <0.4,
random >=1.0 && <1.1,
myserver
Run Code Online (Sandbox Code Playgroud)
我已经尝试添加-shared -fPIC
到ghc-options
库和-dynamic
可执行文件.但是这产生了这个错误:
Linking a.out ...
/usr/bin/ld: /home/rzetterberg/development/haskell/myserver/.cabal-sandbox/lib/x86_64-linux-ghc-7.6.3/scrypt-0.3.6/libHSscrypt-0.3.6.a(Scrypt.o): relocation R_X86_64_32S against `stg_CAF_BLACKHOLE_info' can not be used when making a shared object; recompile with -fPIC
/home/rzetterberg/development/haskell/myserver/.cabal-sandbox/lib/x86_64-linux-ghc-7.6.3/scrypt-0.3.6/libHSscrypt-0.3.6.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
问题是我真的不知道从哪里开始,这就是我寻求帮助的原因.