我想构建用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
Run Code Online (Sandbox Code Playgroud)
我知道所有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
Run Code Online (Sandbox Code Playgroud)
这是否意味着基本库是在没有-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 ()
Run Code Online (Sandbox Code Playgroud)
nodehs.cc: …
http://www.vex.net/~trebla/haskell/so.xhtml描述了如何编译共享库.
关于编译命令:
ghc -O2 -dynamic -shared -fPIC -o libEval.so Eval.hs hsbracket.c -lHSrts-ghc7.6.3
Run Code Online (Sandbox Code Playgroud)
它说:
(你能否省略-dynamic请求其他软件包的静态库?不是真的,它们不是用-fPIC生成的.特别是在x86_64上它是非法的.)
为什么会这样?如果没有libHS*依赖项,应该怎么做才能编译共享库?
我想用数组调用Text.Printf函数printf,但我找不到办法.这是两个不工作的版本(实际上是相同的想法).
import Text.Printf
printfa :: (PrintfArg a) => String -> [a] -> String
printfa format args = step (printf format) args
where
step :: (PrintfType r, PrintfArg a) => r -> [a] -> r
step res (x:[]) = res x
step res (x:xs) = step (res x) xs
printfa' :: (PrintfArg a) => String -> [a] -> String
printfa' format args = foldr (\arg p -> p arg) (printf format) args
main = putStrLn $ printfa "%s %s" ["Hello", "World"] …Run Code Online (Sandbox Code Playgroud)