2012年8月30日 星期四

用 Eclipse 每次編譯 (build) 時自動執行 bash & ndk-build 命令

這裡是之前的的紀錄 Eclipse+Android SDK/NDK 開發環境的過程 (2/2) 步驟 58~62 的附圖詳細說明, 今天 (離上次搞 andriod 有一段時間) 要弄一個別人的案子, 他沒有設置自動編譯 JNI, 對於要改 C 的我頗不方便, 我是少用 Eclipse 的人, 只想到可自動編譯阿, 但又忘了這些步驟, 而且是徹底沒印象怎麼做 :_ 還要回來找老文章 (還好我有留練習紀錄), 那...這次就將過程截圖下來吧, 並加上註解 ;-)

前提:

1. 你已經安裝好 cygwin + NDK 等環境了
2. 你已經做好手動建立 JNI 的 makefile 了 (或是拿別人的專案要改自動化NDK)

如非上述, 請忽略本文吧. 還是從我之前的 Eclipse+Android SDK/NDK 開發環境的過程 1 & 2 開始練起.

---------------------------------------------------------------------

58. (2) (用 Eclipse 每次編譯 (build) 時自動建立 libhello.so)

59. menu -> 'Project' -> 'Properties', 開啟 Properties for xx 對話盒

註: 如果在 Project Explorer 裡有多個專案, 請確認哪一個需要做自動執行 ndk-build, 先選好其中的一個 project, 也可以在其名字上按滑鼠右鍵彈出選單後, 選 'Properties'. 如果多個專案都需要自動執行 ndk-build, 那 "各自" 都要做下面的步驟!

   

60. 點選 Builders 項目, 按下 'New...', 開啟 Choose configuration type
    對話盒


61. 點選 Program 項目, 按下 'OK', 開啟 Edit launch configuration
    properties 對話盒

    Name: 隨你高興        (建議取有意義的字, 我都用 'NDK Builder')

    Main 標籤頁下 (如下圖):

        Location: C:\cygwin\bin\bash.exe
        Working Directory: (留白)
        Arguments: --login -c "/cygdrive/c/android-ndk/ndk-build -C `cygpath -u '${build_project}' `"

    NOTE: 1. 以上 cygwin 及 android-ndk 路徑, 請依真實情況修改
          2. 另外一種 Arguments 寫法:

--login -c "cd '${project_loc}' && /cygdrive/c/android-ndk/ndk-build"


註: 這裡非常重要, 就是實際手動執行 bash, ndk-build 的方式在此輸入好.




    Refresh 標籤頁下 (如下圖):

        Refresh resources upon completion    打勾

註:告知當 ndk-build 執行完畢後, 要接著刷新專案的哪些資源, 一般我們只選因為 ndk-build 執行後所影響(變更)的文件 (如 libs...), 這樣專案其他不相關的文件不會重新又編譯一次.

        選取下方的
        The Entire workspace
        或
        Specific resources 項目
        按 'Specify Resources...' 按鈕, 將專案中的 libs 目錄(*)  打勾

 註: (*) 第一次建立時, 若沒有編譯 jni 過, 可能沒有 libs 目錄, 建議編譯過 jni 後改選這個.

        Recursive include sub-folders        打勾




    Environment 標籤頁下 (如下圖):

        (留白)



     Build Options 標籤頁下 (如上圖):

        Allocate Console       打勾
        File                   不勾

        Launch in background   打勾

        After a "Clean"        打勾 (或不勾看你習慣)
        During manual builds   打勾
        During auto builds     打勾 (或不勾看你習慣)
        During a "Clean"       不勾 (或勾看你習慣)

        Specify working set of relevant resources  打勾

 註: Eclipse help 裡說鑑於效能考量, 不建議 During auto builds 打勾, 我是覺得還好啦. 看你習不習慣 Eclipse 自動(暗自)啟動 ndk-build 囉.



    按 'Specify Resources...' 按鈕, 將專案中的 jni 目錄打勾

註: 這樣子只有 jni 資源目錄下的文件有變更時才會啟動自動編譯, 或是依你需求可以加選擇其他的資源目錄. (例如把 C/C++ source files 放在另外一個目錄, 如果不選 Specify working set of relevant resources 則專案內任一資源變動都會啟動自動編譯)



    設置好後, 按 'Finish' 回到上一層對話盒, 再按 'OK'



62. 此時, 你的 makefile 會依 Run the builder 的指定時機自動編譯, 或手動在選單->Project->Clean + Build Project

    注意 NDK Builder 編譯的時候, Eclipse 的 Console 視窗會同手動一樣顯示 ndk-build 結果,下圖, Console 顯示 bash 執行 NDK Builder...


註: 我經驗上, 以上是設置好了, 但 console 視窗卻沒有出現上圖執行過程...原因

1. 確認步驟 61 的 bash ndk-build 路徑有沒有正確...
2. Eclipse 認定不需要執行 NDK Builder (也許因為你已經手動執行過一次了, 之後沒有再修改 C sources 或 makefile), 試著強制從選單-> clean project 看看...
P.S. 我都是修改一下 jni 的 makefile 內容, 多加一個空白按儲存, 就 (或按 F5 Refresh) 判定需要重新編譯了~
3. C sources 的檔案應該要放到 Project Explorer 裡得 jni folder (或 working set of relevant resources 之處) 才能有相依關連.


後記:
以上的設置 Eclipse 會放在 .externalToolBuilders 下 (NAME).launch, 我的是 NDK_Builder.launch, 這個文件可以直接編輯, 我把此文件隨著專案檔案控管, 當專案其他的成員 check out 時也能直接使用(或修改一下路徑)而不是重複以上的 NDK 環境設置.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration
..略...
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--login -c &quot;/cygdrive/c/android-ndk/ndk-build -C `cygpath -u '${build_project}' `&quot;"/>
..略...
</launchConfiguration>


2012年8月21日 星期二

Visual Studio (as C/C++) 20xx 問題與解決 1

在我使用 VC6 至今(*) VS2010 已經數十年頭, 有些問題常常遇到但很多不知所以然....

(*) sorry, 其實 m$ 在 vs200x 的時候我都還堅守 VC6 啦, 最近才開始混用 VC6 and VS2010


問題1:編譯時遇到下面訊息

xx.lib(oo.obj) : warning LNK4204: 'C:\..\Debug\vc100.pdb' is missing debugging information for referencing module; linking object as if no debug info

原因:
Reason:

1)
這警告是因為要去建立除錯版本時, 使用到外部的某一個程式庫卻沒有該庫對應的 xx.pdb (program database) 檔案, 這檔案包含了一些除錯需要的型別及符號的資訊.

像是你編譯除錯版 (Debug) 的應用程式, 但你引用程式庫全都是發行 (Release) 版, 這樣你無法取得這些庫的偵錯資訊.

It was warning about debugging with particular external lib but without its xx.pdb ( program database) file which contains the type and symbolic debugging information.

It would appear that you're compiling your application in a Debug configuration, but the libraries you referenced are all Release builds, meaning there is no debug information for them.

2)
另外一個可能性是... 該程式庫跟另外一個程式庫用的 .pdb 名字相同 (大多發生在採用預設的 vcx0.pdb), 但在拷貝中檔案被覆蓋過去了.

or in the same name (default as vcx0.pdb) with another .pdb file and been overwrote while copying into.

3)
這也發生在一個 'rebuild solution' 之後, 如果有兩個以上 .vcproj 檔案, 他共享相同的暫時輸出 (intermediate-output) 目錄, 而發生存取相同名字的 'Program Database File Name' (vcx0.pdb) 衝突.

It is also seen after a 'rebuild solution', if two .vcproj files share the same intermediate-output directory and there is a conflict in accessing the same 'Program Database File Name' (vcx0.pdb).


解決 1 和 2:
Solution for 1 and 2:

1)
就忽略這些警告吧 (大家都這樣吧...)

just ignored these warnings (you should already now...)

2)
建立一個程式庫, 把偵錯訊息嵌入進去 (也就是不用 .pdb)

在 Visual Studio 2005/2008/2010 你可以在設定裡這樣做:

Project Properties -> C++ -> General -> Debug Information Format 改成 “/Z7″

一般這選項是預設為 “/ZI” 這樣把偵錯訊息產生在另外的檔案.

make the library to embed the debug information (aka without .pdb)

In Visual Studio 2005/2008/2010 one can do that by setting:

Project Properties -> C++ -> General -> Debug Information Format to “/Z7″

usually this option was set to “/ZI” which generates debug info to external file.

3)
否則找到該 'pdb' (含偵錯訊息) 檔案, 必須放置在跟程式庫相同的目錄下.

otherwise find the 'PDB' file (with debug info) must be placed in the same folder as the libaray.

more info: http://msdn.microsoft.com/en-us/library/958x11bc%28v=VS.100%29.aspx

4)
在 Visual Studio 2005 之前...

避免這個警告,試著按下面步驟建立自己的除錯模式的程式庫:

a) 把 "Debug Information Format" 從 /ZI 改成 Disabled <-- 注意:只有在 vs2005 更早的版本才有
b) 把 "Enable Minimal Rebuild" 從 /Gm 改成 Disabled
c) 改 "Basic Runtime Checks" 為 Default

這基本跟預設的發行磨是設定差不多,少了最佳化. 使用這些設定,你可以移除全部的 OBJ, PDB, 和 IDB 檔案並且使用這些程式庫不會有連結的警告.

before Visual Studio 2005...

To prevent these warnings, try the following to debug mode for my lib:

a) Switched the "Debug Information Format" from /ZI to Disabled <-- note: only available before vs2005
b) Switched the "Enable Minimal Rebuild" from /Gm to Disabled
c) Changed "Basic Runtime Checks" to Default

This is basically the same setup as the default release mode settings, minus the optimization. Using these settings, you can remove all of the OBJ, PDB, and IDB files from compilation and just use the LIB file with no linker warnings.


解決 3:
Solution for 3:

1)
為每一個 .vcproj 修改 Intermediate Output 目錄名字
(在 'Configuration Properties > General > Intermediate Directory' 之下)

change the Intermediate Output dir for one .vcproj
(under 'Configuration Properties > General > Intermediate Directory')

2)
修改 'Program Database File Name' 為另外一個非 VC70.pdb 的名字
(在 'Configuration Properties > C/C++ > Output Files > Program Database File Name' 之下)

change the name of the 'Program Database File Name' to something different than vc70.pdb.
(under 'Configuration Properties > C/C++ > Output Files > Program Database File Name')