如何将自定义对象文件与Haskell库链接?

25
我创建了一个Haskell包,它可以调用在CUDA代码中定义的函数。我想在打包过程中将.cu文件编译为目标文件(.o),并强制链接器将其链接起来。
到目前为止,我尝试使用在此问题中找到的技术。我自定义了buildHook来:
  1. 运行nvcc
  2. 运行默认的buildHook
  3. 使用nvcc编译代码创建ar库文件。
Setup.hs文件在这里可用。
这种解决方案的主要缺点是限制了该包只能进行静态链接。尽管cabal生成了共享库,但由于它无法解析位于目标文件中的符号,因此它不起作用。
是否有更简单的方法在构建过程中链接自定义代码?
1个回答

3

我做类似的事情。我有一个Haskell文件,调用CUDA代码。

这是我如何编译CUDA库并与Haskell链接的方法:

$(NVCC) -c -E  $(NVCC_OPTS) -o build/file.i file.cu
$(NVCC) -c  $(NVCC_OPTS) -o build/file.o file.cu

然后,我使用Haskell选项将所有内容链接到名为LibSO的C++共享库中。

$(CXX) -shared -Wl,-rpath=\$$$$ORIGIN $(CXX_LINK_LIBS) $(PACKAGE_RPATH) -Lbuild -rdynamic -L/usr/local/lib/ghc-7.6.3 -lHSrts-ghc7.6.3 -o build/LibSO.so build/file.o

在哪里

CXX_LINK_LIBS = -Lbuild -lcudart -lcuda -lpthread -lcupti -lcurand -lnvidia-ml
NVCC_OPTS = --compiler-options -fPIC -maxrregcount=0 --machine 64 --DCUDA

我将Haskell文件编译成o和hi文件。(由于TemplateHaskell,我需要编译两次)

ghc -v0 -Wall -rtsopts -threaded -stubdir build -ibuild/ -no-hs-main  -o build/iop.o -ohi build/iop.hi -c haskell/iop.lhs
ghc -v0 -Wall -rtsopts -threaded -stubdir build -ibuild/ -no-hs-main  -fPIC -dynamic -osuf dyn_o -hisuf dyn_hi -o build/iop.dyn_o -ohi build/iop.dyn_hi -c haskell/iop.lhs

现在我们有了Haskell动态对象和一个C++共享库。 最终,我将一个主Haskell文件与所有内容链接:

ghc -optl "-Wl,-rpath=\$$ORIGIN" $(CXX_LINK_LIBS) -Lbuild -rtsopts -threaded -lstdc++ -lLibSO -o build/Main build/iop.dyn_o

这种帮助有用吗?


1
这并不是很有用,因为您假设最终结果是可执行文件。我的项目需要依赖于在.cabal文件中指定的其他软件包,因此手动将它们作为参数传递给ghc/g++不是一个选项。而且,其他软件包将依赖于我的软件包,因此我不能只在最后构建一个可执行文件。Cabal能够自己构建项目并能够将其用作依赖项是至关重要的。 - Marcin Mikołajczyk
那么你使用的是Cabal而不是直接链接吗?你是否将NVCC预编译为对象,然后将它们传递给Cabal?你首先传递给Cabal哪些参数? - Arnon
我使用一个自定义的Setup.hs文件,它附加在原始问题中。NVCC在构建阶段被调用,并且生成的目标文件稍后与其他Haskell对象一起存档到.a文件中。构建不需要额外的命令行参数,一切都在Setup.hs中指定。 - Marcin Mikołajczyk
我相当有信心Cabal并不适用于如此复杂的方案。我会考虑其他的编译方法。 - Arnon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接