July 30, 2008

建立 Gtk+/WebKit 的 API 文件以加速開發流程

上週在教育訓練 [Gtk+ 程式設計初體驗] 中,花了一些時間探討 Gtk+/WebKit,可相當輕鬆地透過既有的 Web Applications,強化 Gtk+ 應用程式的顯示。那麼,該如何擴充給定的範例檔案呢?當然,首先得搞清楚像 WebKitWebView 物件中,到底有哪些 signal、相關繼承關係等。透過 [DevHelp] 這個工具,可視覺化的呈現簡單扼要的類別與 API 資訊,但預設沒有 Gtk+/WebKit 的文件文件支援,所以我們得自力救濟。

我們必先取得系統中 Gtk+/WebKit 的原始程式碼,可透過 "apt-get source" 一類的指令,這裡就不贅述。接著,我們需要 gtk-doc 的工具集合,在 Debian/Ubuntu 中,套件名稱為 "gtk-doc-tools",這些工具可針對給定的組態,自動生成 DevHelp 可讀取的文件格式 (基本上也是 HTML),筆者已事先做好一份參考設定 [webkit-gtkdoc-stub.tar.bz2],具體操作方式如下: (以 Ubuntu 8.10 為例)
  • 切換到 Gtk+/WebKit 原始檔目錄,注意,這裡指的是 top level 的 "WebKit" 目錄,所以目錄下應該要有 "JavaScriptCore", "WebCore", "WebKit" 等子目錄
  • 解開筆者打包的組態設定:
      $ tar jxvf webkit-gtkdoc-stub.tar.bz2
  • 切換到解開的 doc 目錄:
      $ cd WebKit/gtk/doc
  • 由給定的 Makefile,呼叫 gtk-doc 工具組去產生必要的文件檔案:
      $ make
等待一段時間,讓 gtk-doc 慢慢執行,結束時,應該會看到類似以下輸出:
...
Computing chunks...
Writing WebKitWebSettings.html for refentry(WebKitWebSettings)
Writing WebKitWebFrame.html for refentry(WebKitWebFrame)
Writing WebKitWebHistoryItem.html for refentry(WebKitWebHistoryItem)
Writing WebKitWebView.html for refentry(WebKitWebView)
Writing WebKitWebBackForwardList.html for refentry(WebKitWebBackForwardList)
Writing WebKitNetworkRequest.html for refentry(WebKitNetworkRequest)
Writing ch01.html for chapter
Writing index.html for book(index)
Writing index.sgml for book(index)
Writing webkit.devhelp for book(index)
Writing webkit.devhelp2 for book(index)
有了文件檔之後,就來看如何讓 DevHelp 得以讀取。由於我們不打算更動 /usr 目錄下的文件檔,所以就直接放在 $HOME 目錄下,具體操作方式如下:
$ mkdir -p ~/.local/share/gtk-doc/html
$ cp -af html ~/.local/share/gtk-doc/html/webkit
此時,開啟 DevHelp,在視窗左側搜尋 "WebKitWebView" 一類的關鍵字,就應該會有結果出現。另外,也可將 DevHelp 線上查詢的功能整合到 vim 中,使用情境類似下圖:

由圖可見,下方的視窗是 vim 正在編輯程式,而編輯游標停留在 "webkit_web_view_new" 這個函式上,我們可按下 Esc-h,DevHelp 就會查詢這個 Gtk+/WebKit API,相當方便。只要對 vim 稍微作點設定,就可有如此的功能,方法是,修改 ~/.vimrc,加入以下巨集:
" vim macro to jump to devhelp topics.
function! DevHelpCurrentWord()
        let word = expand("<cword>")
        exe "!devhelp -s " . word
endfunction

" Example: bind <ESC>h to start devhelp and search for the word under the
" cursor
nmap <ESC>h :call DevHelpCurrentWord()<CR>
再搭配前文 [在 vim 凸顯 Gtk+ 特有語法],應該就可更舒適的撰寫程式了。
由 jserv 發表於 July 30, 2008 05:46 PM
迴響

ubuntu 8.04
sudo apt-get source libwebkitgtk-dev
裡面沒有
SOURCEDIR = ../WebViewDocsSandbox
ORIG_SOURCEDIR = ../webkit
兩個目錄

robert 發表於 July 31, 2008 04:10 PM

只有這幾個
webkit-0~svn29752/WebKit/gtk/doc$ ls ..
ChangeLog doc WebCoreSupport WebKitGtk.pc.in WebView

robert 發表於 July 31, 2008 04:29 PM

@robert,

請將 Makefile 的 "ORIG_SOURCEDIR = ../webkit" 一行,更改為:
"ORIG_SOURCEDIR = ../WebView"
至於其他,應不需要更動,請測試並告知狀況,謝謝!

jserv 發表於 July 31, 2008 06:54 PM

出現以下錯誤:
gtk-doc: Compiling scanner
gtk-doc: Linking scanner
/usr/bin/ld: cannot find -lwebkit-1.0
collect2: ld 回傳 1
Linking of scanner failed:
make: *** [doc] Error 1

我有安裝 libwebkitgtk-dev

robert 發表於 August 1, 2008 02:45 PM

@robert,
感謝回報,那基本上就快成功了 :-)

請將這一行:
LIBS = "`pkg-config gtk+-2.0 --libs` -lwebkit-1.0"
更改為
LIBS = "`pkg-config gtk+-2.0 WebKitGtk--libs`"

jserv 發表於 August 1, 2008 04:18 PM

不好意思,試著自己解決,還是解決不了,
錯誤如下:
cp -rf ../WebView ../WebViewDocsSandbox
for h in ../WebViewDocsSandbox/*.h; do \
sed 's/WEBKIT_API //g' $h > ../WebViewDocsSandbox/.tmp. && \
mv ../WebViewDocsSandbox/.tmp. $h ; \
done
for s in webkitsettings.h webkitsettings.cpp webkit-marshal.cpp webkit-marshal.h webkitdefines.h webkitprivate.cpp webkitprivate.h; do \
rm -f ../WebViewDocsSandbox/$s ; \
done
gtkdoc-scan --module=webkit --source-dir=../WebViewDocsSandbox --output-dir=.
CFLAGS="`pkg-config gtk+-2.0 --cflags`" LDFLAGS="`pkg-config gtk+-2.0 WebKitGtk--libs`" LIBS="`pkg-config gtk+-2.0 WebKitGtk--libs`" gtkdoc-scangobj --module=webkit --types=webkit.types --output-dir=.
gtk-doc: Compiling scanner
gtk-doc: Linking scanner
webkit-scan.o: In function `get_object_types':
webkit-scan.c:(.text+0x12): undefined reference to `webkit_web_settings_get_type'
webkit-scan.c:(.text+0x25): undefined reference to `webkit_web_frame_get_type'
webkit-scan.c:(.text+0x38): undefined reference to `webkit_web_view_get_type'
webkit-scan.c:(.text+0x4b): undefined reference to `webkit_network_request_get_type'
webkit-scan.c:(.text+0x87): undefined reference to `g_type_test_flags'
webkit-scan.c:(.text+0x9d): undefined reference to `g_type_class_ref'
webkit-scan.c:(.text+0xaf): undefined reference to `g_type_fundamental'
webkit-scan.c:(.text+0xc6): undefined reference to `g_type_default_interface_ref'
webkit-scan.o: In function `main':
webkit-scan.c:(.text+0xf9): undefined reference to `g_type_init'
webkit-scan.c:(.text+0x105): undefined reference to `g_type_class_ref'
webkit-scan.o: In function `output_signals':
webkit-scan.c:(.text+0x18e): undefined reference to `g_log'
webkit-scan.o: In function `compare_signals':
以下 error 雷同, 都是 webkit-scan.c:(.text+0x105): undefined reference to
沒全貼上
最後是
collect2: ld 回傳 1
Linking of scanner failed:
make: *** [doc] Error 1

我有裝 glibc 的 include, 一般的 gtk+ 程式也都能 compile, 此處不知為何找不到

robert 發表於 August 3, 2008 01:48 PM

@robert,
功敗垂成 :-)

仔細看可發現,這行 LIBS="`pkg-config gtk+-2.0 WebKitGtk--libs`"
WebKitGtk--libs 應該要用空白區隔呀,上個留言,小弟筆誤了,兄臺恰好沒察覺。

jserv 發表於 August 3, 2008 04:38 PM

sorry, 沒把注意力放在 LIBS 上
看到 undefined, 直覺就想到 CFLAGS
原來是 link 出錯
感謝大大幫忙

robert 發表於 August 3, 2008 05:24 PM
發表迴響









記住我的資訊?