ghc共享二进制编译为标准库提供了-fPIC错误

时间:2014-11-24 15:56:01

标签: haskell compilation

我想构建用Haskell编写的共享对象(node.js addon)。

编译命令:

cabal exec -- \
   ghc -cpp -pgmc gcc -optc-std=c++0x -optP-lpthread -O2 -threaded \
   -shared -no-hs-main -fPIC -o myaddon.node \
   -I. -I/usr/include/node/ -L. -lstdc++ -lpthread -lHSrts-ghc7.8.3 \
   hsbracket.c node.cc myaddon.hs

据我所知,所有Haskell库都应该使用-fPIC选项编译:

/usr/bin/ld: /usr/lib/ghc-7.8.3/binary-0.7.1.0/libHSbinary-0.7.1.0.a(Get__14.o): relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC

这是否意味着基本库是在没有-fPIC选项的情况下编译的,我应该自己编译所有内容(通过黑客入侵cabal bootstrap.sh脚本)?

编辑(1月4日):

helloWorld.hs:

{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C
hsHelloWorld = newCString "Hello from Haskell"
foreign export ccall "hsHelloWorld" hsHelloWorld :: IO CString
main = return ()

nodehs.cc:

#include <node.h>
#include <v8.h>
#include <nodehs_stub.h>

using namespace v8;

Handle<Value> wrapHelloWorld(const Arguments& args) {
  HandleScope scope;
  return scope.Close(String::New( (char *)hsHelloWorld() ));
}

void Init(Handle<Object> exports) {
  exports->Set( String::NewSymbol("helloWorld"),
    FunctionTemplate::New(wrapHelloWorld)->GetFunction());
}

NODE_MODULE(nodehs, Init)

hsbracket.c(非常标准):

#include <HsFFI.h>
static void my_enter(void) __attribute__((constructor));
static void my_enter(void) {
  static char *argv[] = { "nodehs.node", 0 }, **argv_ = argv;
  static int argc = 1;
  hs_init(&argc, &argv_);
}
static void my_exit(void) __attribute__((destructor));
static void my_exit(void) { hs_exit(); }

编译命令:

ghc -shared -fPIC -o nodehs.node  -I. -L. -lstdc++ -lHSrts-ghc7.8.4 \
 -I/node-v0.10.35/src/             \
 -I/node-v0.10.35/deps/v8/include/ \
 -I/node-v0.10.35/deps/uv/include  \
 nodehs.cc hsbracket.c helloWorld.hs

结果:

/ usr / bin / ld:/usr/local/lib/ghc-7.8.4/base-4.7.0.2/libHSbase-4.7.0.2.a(Base__114.o):针对`stg_bh_upd_frame_info&#39;重新定位R_X86_64_32S制作共享对象时不能使用;用-fPIC重新编译 /usr/local/lib/ghc-7.8.4/base-4.7.0.2/libHSbase-4.7.0.2.a:无法读取符号:错误值 collect2:错误:ld返回1退出状态

使用-dynamic一切正常,但动态链接所有haskell库。

如何将haskell库静态编译到插件中?

对于完全相同的环境和测试,我添加了Dockerfile(docker build -t compile-node . && docker run -v /home/me/nodehs:/src:rw compile-node

FROM debian:wheezy

RUN apt-get update && apt-get -y upgrade
RUN apt-get -y install make curl bzip2 unzip gzip libgmp-dev zlib1g-dev

RUN curl -s http://nodejs.org/dist/v0.10.35/node-v0.10.35.tar.gz | tar xz
RUN curl -s http://downloads.haskell.org/~ghc/7.8.4/ghc-7.8.4-x86_64-unknown-linux-deb7.tar.bz2 |     tar xj
RUN curl -s http://hackage.haskell.org/package/cabal-install-1.18.0.5/cabal-install-1.18.0.5.tar.gz | tar xz

RUN curl -sL https://deb.nodesource.com/setup | bash -
RUN apt-get install -y nodejs

RUN cd ghc-* && ./configure && make install
ENV EXTRA_BUILD_OPTIONS "--enable-executable-dynamic --enable-shared --ghc-options='-fPIC --dynamic-too'"
RUN cd cabal-* && ./bootstrap.sh --global
RUN cabal update

WORKDIR /src/

# first ghc command is needed to make helloWorld_stub.h
CMD ghc helloWorld.hs && \
  ghc -shared -fPIC -o nodehs.node \
  -I. -I/node-v0.10.35/src/ -I/node-v0.10.35/deps/v8/include/ -I/node-v0.10.35/deps/uv/include \
  -L. -lstdc++ -lHSrts-ghc7.8.4 \
  nodehs.cc hsbracket.c helloWorld.hs \
  && node -e "console.log(require('./nodehs.node').helloWorld())'"

0 个答案:

没有答案