2011年7月31日 星期日

如何在Ubuntu/Linux中使用 Objective C + Blocks?



接續上篇"Objc Hello範例: Ubuntu上使用GNUstep and gobjc"一文。
當使用Blocks 語法時,卻發現不能使用,原因是Blocks 並未正式通過GNU GCC允許加入內建;
在不斷實驗並尋找後,終於找到一個解法:clang + BlocksRuntime。
BlocksRuntime 是 compiler-rt 專案的一部分。
首先使用svn指令下載: svn checkout http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
接著依序來編繹 ./BlocksRuntime/libBlocksRuntime.so
    1. cd compiler-rt/BlocksRuntime/
    2. 建立 ./config.h 包含下兩行內容
        #define HAVE_SYNC_BOOL_COMPARE_AND_SWAP_INT 1
        #define HAVE_SYNC_BOOL_COMPARE_AND_SWAP_LONG 1
    3. make
demoblocks 程式編繹
  - make run prefix=<你的路徑中包含compiler-rt>
  (註: 筆者的環境中已將 "BlocksRuntime/" 目錄複製到demoblocks 目錄中)
demoblocks範例:
main.m
#include <stdio.h>
#include "Block.h"
typedef int(^ablock)(void);
ablock dosth(int difference)
{
        __block int a = 1;
        int b = difference;
        return Block_copy(^{
                a += b;
                return a;
        });
}
int main()
{
        ablock a = dosth(10);
        int i;
        for (i = 0 ; i < 3; i++) {
                printf("%d\n", a());
        }
        Block_release(a);
        return 0;
}

Makefile
prefix?=.
BLOCKS_RT_DIR=$(prefix)/BlocksRuntime/
BLOCKS_RT= -I$(BLOCKS_RT_DIR) -L$(BLOCKS_RT_DIR) -lBlocksRuntime
all: demoblocks
demoblocks: main.m
        clang $(BLOCKS_RT) -fblocks $^ -o demoblocks
run: demoblocks
        export LD_LIBRARY_PATH=$(BLOCKS_RT_DIR) ; \
        ./demoblocks
clean:
        rm -f ./demoblocks
執行結果:make run prefix="./compiler-rt"

clang -I./BlocksRuntime/ -L./BlocksRuntime/ -lBlocksRuntime -fblocks main.m -o demoblocks
export LD_LIBRARY_PATH=./BlocksRuntime/ ; \
        ./demoblocks
11
21
31
由此下載範例源始碼
可參考Blocks 相關的文章:

沒有留言: