如何解决OSX,ghci,dylib,正确的方法是什么?
| 我需要构建一些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,sizeof( _glfwLibrary.hints ) );
}
麻烦的制造者是memset行,实际上问题是在ghci中运行时,写入_glfwLibrary
的提示结构是内存访问冲突。提示结构只是一堆int。它非常平坦和简单,因此我认为问题在于我如何链接事物或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)
大多数标志直接取自GLFW Makefile,因此我认为它们对于该库应该是正确的。
第一行看起来有些怪异,但这是我用于解决此问题的解决方案。
平台详细信息:
OSX 10.6.6
x86_64
4芯
通过Haskell Platform安装程序安装的GHC版本7.0.3
源回购:https://github.com/dagit/GLFW-b
编辑:这是我的问题:
应该与ghci一起使用吗?
如果是这样,我在做什么错或者我该如何解决崩溃问题?
我可以通过ghci静态访问库的.a版本吗?
解决方法
最初的问题
应该与ghci一起使用吗?
如果是这样,我在做什么错或者我该如何解决崩溃问题?
在OSX 10.6.7(使用Haskell平台/ 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
注意:我使用您提供的Makefile
构建了glfw
库,并另外使用了.cabal
文件来处理src/Graphics/UI/GLFW.hsc
和构建dist/build/Graphics/UI/GLFW.hs
(即我之前运行run9ѭ)。
我可以通过ghci静态访问库的.a版本吗?
是的,GHC 7.0.2(GHC手册)中包含了对加载静态库的支持。 compiler/ghci/Linker.lhs
是一本不错的书,它将使您对ghci如何决定传递给它的命令行参数的处理方式有一个较高的了解。此外,在浏览各种平台支持问题时,我发现本文档非常有用。
将静态档案与ghci链接。
撰写本文时,compiler/ghci/Linker.hs
的1113
行表明ghci
当前要求静态压缩档案由打包系统(即名为ѭ14archive)构建。
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
对cmd行参数解析的进一步研究表明,指定的库在reallyInitDynLinker
函数的第402
行收集:
; classified_ld_inputs <- mapM classifyLdInput cmdline_ld_inputs
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
这意味着,在软件包规范之外,当前没有直接方法可以在ghci中链接归档文件(或者换句话说,当前没有cmd-line参数可以这样做)。
修理你的阴谋包
在您的“ 6”包规范中,您试图构建两个冲突的库:
A:预先构建的库中的链接(根据您在Setup.hs
和Makefile
中的规范构建,并根据extra-libraries
和extra-lib-dirs
指令进行链接)
B:建立一个新的内联库(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
和
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
除了验证以下各项是否正常之外,我没有进行任何测试:
➜ 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>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。