在跨平臺(tái)開發(fā)中,跨越系統(tǒng)、編譯器、匯編語法是經(jīng)常碰到的事情,前段時(shí)間就為在mingw下編譯hans boehm gc傷神過。
現(xiàn)把我的解決過程記錄如下。
首先,請(qǐng)確保您已安裝好msys、mingw、gcc4.3.3編譯環(huán)境,gcc4.3.3為我所用的版本,如有新版,那么更好。
codeblocks用戶請(qǐng)暫時(shí)放棄IDE環(huán)境,習(xí)慣一下bash吧。
接下來,在msys目錄中運(yùn)行msys.bat

啟動(dòng)windows下的bash環(huán)境。哦,msys的叫sh,反正都是xxsh,也不用太講究了。

接下來,進(jìn)入您下載的hans boehm gc 7.1解壓目錄,鍵入:
./configure --enable-shared=no --enable-static=yes --enable-cplusplus --enable-large-config --enable-parallel-mark --enable-threads=win32
為什么后面要配置這么多呢,讓我一項(xiàng)一項(xiàng)解說一下吧:
--enable-shared=no 是否編譯動(dòng)態(tài)庫,我個(gè)人選否,所以填的=no,如果要編譯為動(dòng)態(tài)庫,那記得把這個(gè)改為=yes啊
--enable-static=yes 是否編譯靜態(tài)庫,我個(gè)人選是,所以填的=yes,如果要編譯為動(dòng)態(tài)庫,那記得把這個(gè)改為=no啊
所以呢,記得,上面這兩項(xiàng)最好反著填
--enable-cplusplus 允許c++
--enable-large-config 允許申請(qǐng)大塊內(nèi)存的配置
--enable-parallel-mark 允許并發(fā)環(huán)境的標(biāo)記,多線程環(huán)境一定得加上這一項(xiàng)
--enable-threads=win32 線程模型,這里為win32(話說當(dāng)初在doc目錄里看了好久,都沒翻到到底有那幾個(gè)模型標(biāo)志,索性在configure.ac里自己翻出來得了)
好了,現(xiàn)在輸入回車,autoconf會(huì)自動(dòng)為您配置好makefile。
接下來呢,make吧:
make
呃,這里,編譯到某個(gè)文件的時(shí)候,會(huì)報(bào)一個(gè)錯(cuò):
libatomic_ops/src/atomic_ops/sysdeps/gcc/x86.h (114)
inline asm error : input constraint with a matching output constraint of incompatible type!
哇咧,這是蝦米錯(cuò)誤,gc干匯編貂事情啊?
沒辦法,hans boehm還寫過一個(gè)libatomic_ops(原子操作庫),自家人當(dāng)然更喜歡用自家?guī)炜?br>好吧,看看到底是什么問題,改改看先。
打開x86.h,定位到114行,發(fā)現(xiàn)如下代碼:
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嵌入的匯編啊,看著頭會(huì)很疼的啊...
趕緊翻翻AT&T語法,再找找gcc asm資料,哦,知道了gcc嵌入?yún)R編語法如下:
__asm__(匯編語句模板: 輸出部分: 輸入部分: 破壞描述部分)
前面說輸入跟輸出的類型約束不匹配,那先看*addr,這個(gè)玩意在輸入跟輸出里長(zhǎng)得一個(gè)模樣嘛,應(yīng)該不是它的問題
剩下的就是 oldval 跟 0xff 了,這兩一個(gè)是 unsigned char ,一個(gè)是立即數(shù),當(dāng)然配不上了,不過這個(gè)0xff也太
magic num了吧,到底是啥東西啊,回頭,打開libatomic_ops/src/atomic_ops/sysdeps/msftc下的x86.h
看看同樣的函數(shù)里,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");
可能有同學(xué)會(huì)問,為什么0xff可以直接換成上面這個(gè)樣子了,這可是匯編啊
恩,介個(gè)嘛,括號(hào)里的東西還是按c/c++語法來的,gcc會(huì)認(rèn)的,放心咯。
恩,再編譯吧:
make
……
……
……
當(dāng)當(dāng)當(dāng)當(dāng),編譯完成,到.libs目錄里翻libgc.a去吧
附注:還記得前面的--enable-shared=no --enable-static=yes么
如果你配置了--enable-static=yes,卻沒有配置--enable-shared=no
那么在make快結(jié)束,生成庫的時(shí)候,你就會(huì)看見一串的以GC_開頭的未定義符號(hào)
這是為啥咧,就因?yàn)樵试S了生成靜態(tài)庫,確沒有禁止生成動(dòng)態(tài)庫,配置出來的
makefile默認(rèn)會(huì)先生成動(dòng)態(tài)庫,也就是在未定義符號(hào)錯(cuò)誤前你會(huì)發(fā)現(xiàn):
gcc -shared
字樣,這是在生成動(dòng)態(tài)庫,然而允許靜態(tài)庫時(shí)禁用了所有的導(dǎo)出符號(hào),鏈接動(dòng)態(tài)庫就咯屁咯。
所以,要么--enable-shared=no --enable-static=yes,要么--enable-shared=yes --enable-static=no
免得出錯(cuò)。
終于寫完了,您也看完了,那么,下回見了。