dede

在windows中,用mingw编译hans boehm gc 7.1

在跨平台开发中,跨越系统、编译器、汇编语法是经常碰到的事情,前段时间就为在mingw下编译hans boehm gc伤神过。

现把我的解决过程记录如下。

首先,请确保您已安装好msys、mingw、gcc4.3.3编译环境,gcc4.3.3为我所用的版本,如有新版,那么更好。
codeblocks用户请暂时放弃IDE环境,习惯一下bash吧。

接下来,在msys目录中运行msys.bat


启动windows下的bash环境。哦,msys的叫sh,反正都是xxsh,也不用太讲究了。

接下来,进入您下载的hans boehm gc 7.1解压目录,键入:

./configure --enable-shared=no --enable-static=yes --enable-cplusplus --enable-large-config --enable-parallel-mark --enable-threads=win32

为什么后面要配置这么多呢,让我一项一项解说一下吧:
--enable-shared=no      是否编译动态库,我个人选否,所以填的=no,如果要编译为动态库,那记得把这个改为=yes啊
--enable-static=yes     是否编译静态库,我个人选是,所以填的=yes,如果要编译为动态库,那记得把这个改为=no啊
                        所以呢,记得,上面这两项最好反着填
--enable-cplusplus      允许c++
--enable-large-config   允许申请大块内存的配置
--enable-parallel-mark  允许并发环境的标记,多线程环境一定得加上这一项
--enable-threads=win32  线程模型,这里为win32(话说当初在doc目录里看了好久,都没翻到到底有那几个模型标志,索性在configure.ac里自己翻出来得了)

好了,现在输入回车,autoconf会自动为您配置好makefile。

接下来呢,make吧:

make

呃,这里,编译到某个文件的时候,会报一个错:

libatomic_ops/src/atomic_ops/sysdeps/gcc/x86.h (114)
inline asm error : input constraint with a matching output constraint of incompatible type
!

哇咧,这是虾米错误,gc干汇编貂事情啊?
没办法,hans boehm还写过一个libatomic_ops(原子操作库),自家人当然更喜欢用自家库咯。
好吧,看看到底是什么问题,改改看先。
打开x86.h,定位到114行,发现如下代码:

  unsigned char oldval;
  
/* Note: the "xchg" instruction does not need a "lock" prefix */
  __asm__ __volatile__(
"xchgb %0, %1"
        : 
"=q"(oldval), "=m"(*addr)
        : 
"0"(0xff), "m"(*addr) : "memory");


天杀的,gcc嵌入的汇编啊,看着头会很疼的啊...

赶紧翻翻AT&T语法,再找找gcc asm资料,哦,知道了gcc嵌入汇编语法如下:

__asm__(汇编语句模板: 输出部分: 输入部分: 破坏描述部分)

前面说输入跟输出的类型约束不匹配,那先看*addr,这个玩意在输入跟输出里长得一个模样嘛,应该不是它的问题
剩下的就是 oldval 跟 0xff 了,这两一个是 unsigned char ,一个是立即数,当然配不上了,不过这个0xff也太
magic num了吧,到底是啥东西啊,回头,打开libatomic_ops/src/atomic_ops/sysdeps/msftc下的x86.h

看看同样的函数里,vc里咋写的:

    __asm
    {
    mov    eax,AO_TS_SET        ;
    mov    ebx,addr        ;
    xchg    
byte ptr [ebx],al    ;
    }

噢噢,是AO_TS_SET,这样有意义多了嘛,好了,我们改这么一改:

  __asm__ __volatile__("xchgb %0, %1"
        : 
"=q"(oldval), "=m"(*addr)
        : 
"0"((unsigned char)AO_TS_SET), "m"(*addr) : "memory");


可能有同学会问,为什么0xff可以直接换成上面这个样子了,这可是汇编啊
恩,介个嘛,括号里的东西还是按c/c++语法来的,gcc会认的,放心咯。

恩,再编译吧:

make

……
……
……

当当当当,编译完成,到.libs目录里翻libgc.a去吧

附注:还记得前面的--enable-shared=no --enable-static=yes么
如果你配置了--enable-static=yes,却没有配置--enable-shared=no
那么在make快结束,生成库的时候,你就会看见一串的以GC_开头的未定义符号
这是为啥咧,就因为允许了生成静态库,确没有禁止生成动态库,配置出来的
makefile默认会先生成动态库,也就是在未定义符号错误前你会发现:

gcc -shared

字样,这是在生成动态库,然而允许静态库时禁用了所有的导出符号,链接动态库就咯屁咯。

所以,要么--enable-shared=no --enable-static=yes,要么--enable-shared=yes --enable-static=no

免得出错。

终于写完了,您也看完了,那么,下回见了。

posted on 2009-05-23 19:57 dede 阅读(2928) 评论(1)  编辑 收藏 引用

评论

# re: 在windows中,用mingw编译hans boehm gc 7.1[未登录] 2010-05-07 11:46 William wang

非常好.

我正在编译ECL 10.3.1,google 到了你的文章。

  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(1)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜