haskell - que - La compilación binaria compartida de ghc proporciona el error-FPIC para las bibliotecas estándar
haskell lenguaje de programacion (0)
Quiero construir un objeto compartido (node.js addon) escrito en Haskell.
Comando para compilar:
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
Entiendo que todas las bibliotecas de Haskell deben compilarse con la opción -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
¿Significa que las bibliotecas base se compilan sin la opción -fPIC y debería compilar todo yo mismo (pirateando la secuencia de comandos cabal bootstrap.sh)?
Editar (Ene, 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 (muy estándar):
#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(); }
compilando comando:
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
resultado:
/ usr / bin / ld: /usr/local/lib/ghc-7.8.4/base-4.7.0.2/libHSbase-4.7.0.2.a(Base__114.o): la reubicación R_X86_64_32S contra `stg_bh_upd_frame_info ''no se puede usar cuando hacer un objeto compartido; recompile con -fPIC /usr/local/lib/ghc-7.8.4/base-4.7.0.2/libHSbase-4.7.0.2.a: no se pudieron leer los símbolos: Valor malo collect2: error: ld devuelto 1 estado de salida
Con -dynamic
todo funciona pero vincula dinámicamente todas las bibliotecas de haskell.
¿Cómo puedo compilar las bibliotecas haskell estáticamente en addon?
Para exactamente el mismo entorno y pruebas agrego 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())''"