我需要编译一些C代码,然后通过FFI引用它们。我想在OSX上使用ghci内的绑定。我的限制之一是不能在.cabal文件中直接把C源代码交给ghc。这是由于ghc / cabal的一个限制,可能会在ghc的下一个版本中修复(但我希望我的代码现在和旧版本中都能正常工作)。有关详细信息,请参见此错误。
该错误的主要问题在于,C代码需要与一些Objective-C模块一起编译,而ghc将它们误解为链接器脚本。 我尝试了很多东西,自己用makefile构建文件是唯一有效的方法。 但实际上,这不应该成为一个问题,因为它应该与我决定使用未经自己构建的外部C库相同。 为了解决此问题,让我们假装它是一个可以轻松重建不同选项的单独的C库。
如果我将C库构建为.a,则ghci会抱怨无法打开.dlyb。我的第一个问题是:为什么ghci需要.dlyb并且它真的使用它吗?
当我构建dylib时,加载代码到ghci时会出现段错误。
请记住,此绑定已在其他平台(Linux和Windows)上正常工作,而且当我编译而不是使用ghci时,在OSX上绑定也可以正常工作。这个问题只出现在osx / ghci组合中。
在上面的跟踪中,我正在使用gdb,但无论是否使用gdb都会崩溃。我追踪到了导致崩溃的代码行:
void _glfwClearWindowHints( void )
{
memset( &_glfwLibrary.hints, 0, sizeof( _glfwLibrary.hints ) );
}
问题出在memset那一行,实际上问题是当在ghci内运行时写入_glfwLibrary
的hints结构体会导致内存访问冲突。hints结构体只是一些整数。它非常简单,因此我认为问题可能是链接方式或ghci加载代码的方式有问题。
以下是我使用的makefile部分内容,用于构建dylib和.a文件:
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)
大部分标志都直接从GLFW Makefile中获取,因此我认为它们应该适用于该库。
第一行看起来有点奇怪,但这是我为解决这个问题所使用的解决方案。
平台细节:
- OSX 10.6.6
- x86_64
- 4个核心
- GHC版本为7.0.3,通过Haskell平台安装程序安装
- 源存储库:https://github.com/dagit/GLFW-b
编辑:这是我的问题:
- 这是否适用于ghci?
- 如果是这样,我做错了什么或如何修复崩溃?
- 我能否只使用库的静态.a版本与ghci配合使用?