Jas*_*git 22 macos haskell ffi segmentation-fault cabal
我需要构建一些C代码,然后通过FFI引用该C代码.我想在osx上使用ghci里面的绑定.根据我的限制,我不能只将C源文件传递给.cabal文件中的ghc.这是因为ghc/cabal的限制可以在ghc的下一个版本中修复(但我希望我的代码现在可以在旧版本中使用).看到这个的细节错误.
该错误的要点是C代码需要使用一些Objective-C模块进行编译,并且ghc将这些错误解释为链接器脚本.我尝试了很多东西,用makefile自己构建文件是唯一有效的方法.实际上,这应该不是一个问题,因为它应该像我决定使用我自己没有构建的外部C库一样.为了解决这个问题,让我们假装它是一个单独的C库,我可以使用不同的选项轻松地重建它.
如果我将C库构建为.a,那么ghci会抱怨它无法打开.dylib.我的第一个问题是:为什么ghci需要一个.dylib并且它真的使用它吗?
当我构建一个dylib 时,在将代码加载到ghci时会出现段错误.
请记住,这个绑定已经在其他平台上工作了,包括linux和windows,当我编译而不是使用ghci时,绑定在osx上工作正常.这个问题特定于osx/ghci组合.
在上面的那个跟踪中,我正在使用gdb,但无论我是否使用gdb,它都会崩溃.我将其追踪到导致崩溃的线条:
void _glfwClearWindowHints( void )
{
memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );
}
Run Code Online (Sandbox Code Playgroud)
麻烦制造者就是那个memset系列,实际上问题是当在ghci里面运行时写入提示结构_glfwLibrary是一个内存访问违规.提示结构只是一堆整数.它非常扁平和简单,因此我认为问题是一个问题,无论是我如何链接事物或ghci加载代码的方式.
以下是我用来构建dylib和.a的makefile的位:
GCCFLAGS := $(shell ghc --info | ghc -e "fmap read getContents >>= \
putStrLn . unwords . read . Data.Maybe.fromJust . lookup \
\"Gcc Linker flags\"")
FRAMEWORK := -framework Cocoa -framework OpenGL
GLFW_FLAG := $(GCCFLAGS) -O2 -fno-common -Iglfw/include -Iglfw/lib \
-Iglfw/lib/cocoa $(CFLAGS)
all: $(BUILD_DIR)/static/libglfw.a $(BUILD_DIR)/dynamic/libglfw.dylib
$(BUILD_DIR)/dynamic/libglfw.dylib: $(OBJS)
$(CC) -dynamiclib -Wl,-single_module -compatibility_version 1 \
-current_version 1 \
$(GLFW_FLAG) -o $@ $(OBJS) $(GLFW_SRC) $(FRAMEWORK)
$(BUILD_DIR)/static/libglfw.a: $(OBJS)
ar -rcs $@ $(OBJS)
Run Code Online (Sandbox Code Playgroud)
大多数标志都是直接从GLFW Makefile中获取的,所以我认为它们对于该库应该是正确的.
第一行看起来有点奇怪,但它是我用于此问题的解决方案.
平台细节:
编辑:以下是我的问题:
这应该与ghci一起使用吗?如果是这样,我做错了什么或如何解决崩溃?
在OSX 10.6.7(使用Haskell Platform/w GHC 7.0.2)上,我可以将您构建的共享库加载到ghci中,如下所示:
? GLFW-b git:(master) ? ghci dist/build/Graphics/UI/GLFW.hs -Lbuild/dynam
ic -lglfw
GHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Loading object (dynamic) glfw ... done
final link ... done
[1 of 1] Compiling Graphics.UI.GLFW ( dist/build/Graphics/UI/GLFW.hs, inte
rpreted )
Ok, modules loaded: Graphics.UI.GLFW.
*Graphics.UI.GLFW> initialize
True
Run Code Online (Sandbox Code Playgroud)
注意:我glfw使用您提供的库构建了库Makefile,并且还使用了您的.cabal文件来处理src/Graphics/UI/GLFW.hsc和构建dist/build/Graphics/UI/GLFW.hs(即我之前运行过cabal configure/build).
我可以使用带有ghci的库的静态.a版本吗?
是的,GHC 7.0.2(GHC手册)中包含了对加载静态库的支持.compiler/ghci/Linker.lhs这是一个很好的阅读,它将让您高度了解ghci如何决定传递给它的命令行参数.此外,在浏览各种平台支持问题时,我发现此文档非常有用.
截至编写时,当前需要通过包系统构建静态存档(即命名)1113的compiler/ghci/Linker.hs演示行ghciHSlibname.a
locateOneObj :: [FilePath] -> String -> IO LibrarySpec
locateOneObj dirs lib
| not ("HS" `isPrefixOf` lib)
-- For non-Haskell libraries (e.g. gmp, iconv) we assume dynamic library
= assumeDll
| not isDynamicGhcLib
-- When the GHC package was not compiled as dynamic library
-- (=DYNAMIC not set), we search for .o libraries or, if they
-- don't exist, .a libraries.
= findObject `orElse` findArchive `orElse` assumeDll
Run Code Online (Sandbox Code Playgroud)
对cmd行参数解析的进一步研究表明,指定的库是402在reallyInitDynLinker函数的行中收集的:
; classified_ld_inputs <- mapM classifyLdInput cmdline_ld_inputs
Run Code Online (Sandbox Code Playgroud)
在哪里classifyLdInput定义
classifyLdInput :: FilePath -> IO (Maybe LibrarySpec)
classifyLdInput f
| isObjectFilename f = return (Just (Object f))
| isDynLibFilename f = return (Just (DLLPath f))
| otherwise = do
hPutStrLn stderr ("Warning: ignoring unrecognised input `" ++ f ++ "'")
return Nothing
Run Code Online (Sandbox Code Playgroud)
这意味着在包规范之外,目前没有直接的方法来链接ghci中的存档文件(或者换句话说,目前没有cmd-line参数可以这样做).
在您的.cabal包规范中,您正在尝试构建两个冲突的库:
Setup.hs和Makefile,并链接为每extra-libraries和extra-lib-dirs指令)c-sources和frameworks指令).上述错误的一个简单修复是在为Mac OSX构建时简单地删除所有启用B的指令,如下所示:
include-dirs:
glfw/include
glfw/lib
- c-sources:
- glfw/lib/enable.c
- glfw/lib/fullscreen.c
- glfw/lib/glext.c
- glfw/lib/image.c
- glfw/lib/init.c
- glfw/lib/input.c
- glfw/lib/joystick.c
- glfw/lib/stream.c
- glfw/lib/tga.c
- glfw/lib/thread.c
- glfw/lib/time.c
- glfw/lib/window.c
+
+ if !os(darwin)
+ c-sources:
+ glfw/lib/enable.c
+ glfw/lib/fullscreen.c
+ glfw/lib/glext.c
+ glfw/lib/image.c
+ glfw/lib/init.c
+ glfw/lib/input.c
+ glfw/lib/joystick.c
+ glfw/lib/stream.c
+ glfw/lib/tga.c
+ glfw/lib/thread.c
+ glfw/lib/time.c
+ glfw/lib/window.c
Run Code Online (Sandbox Code Playgroud)
和
if os(darwin)
- include-dirs:
- glfw/lib/cocoa
- frameworks:
- AGL
- Cocoa
- OpenGL
extra-libraries: glfw
- extra-lib-dirs: build/static build/dynamic
+ extra-lib-dirs: build/dynamic
Run Code Online (Sandbox Code Playgroud)
我没有测试任何东西,除了验证以下现在正常工作:
? GLFW-b git:(master) ? ghci
GHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> :m + Graphics.UI.GLFW
Prelude Graphics.UI.GLFW> initialize
Loading package GLFW-b-0.0.2.6 ... linking ... done.
True
Prelude Graphics.UI.GLFW>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1959 次 |
| 最近记录: |