2011/07/15

2011-07-14 13.24.57

2011-07-14 13.24.57 by nanotiny
2011-07-14 13.24.57, a photo by nanotiny on Flickr.

全Linux生活:第75天 - 設定Linux中的Firefox Java Plugin

From Evernote:

全Linux生活:第75天 - 設定Linux中的Firefox Java Plugin

目錄與檔案:

java安裝路徑:${JAVA_HOME}
32bit: /opt/java/jdk1.6.0_25
64bit: /opt/java_x64/jdk1.6.0_25

Plugin路徑:${JAVA_PLUGIN}
32bit: ${JAVA_HOME}/jre/lib/i386/libnpjp2.so
64bit: ${JAVA_HOME}/jre/lib/amd64/libnpjp2.so

Firefox Plugins路徑:${FIREFOX_PLUGIN}
/usr/lib/mozilla/plugins

安裝方式:

1. sudo ln -s ${JAVA_PLUGIN} /etc/alternatives/mozilla-javaplugin.so
2. sudo ln -s /etc/alternatives/mozilla-javaplugin.so ${FIREFOX_PLUGINS}/libjavaplugin.so

2011/06/17

全Linux生活:第47天 - Fedora 15真的不錯,但還是輸給Ubuntu 11.04﹍

From Evernote:

全Linux生活:第47天 - Fedora 15真的不錯,但還是輸給Ubuntu 11.04﹍

嗯﹍Fedora 15終於開始有比較像樣的UI了,操作上完全跳脫M$系統的框架,新的操作方式我覺得甚至比Windows7好,耳目一新,很快就可以適應,但很可惜,小細節的精緻度還是遠遠落後Ubuntu 11.04,當然最大的敗筆還是字型,再來就是過大的應用程式圖示,搞到像十元硬幣那麼大是怎樣﹍當我們是蝦子嗎!

結論:如果要當Server,乖乖裝CentOS 5.6吧,如果要當Desktop,目前沒別得選擇就是Ubuntu 11.04了,那Fedora 15可以當Desktop嗎?先把字型的顯示精緻化才有機會,否則很難滿足像我們這種視覺系的使用者,最重要就是要看起來很爽,不然怎麽用得下去?不過從Fedora 15看得出來,要用Fedora當Desktop應該不會等太久,也許Fedora 16有機會,但比較可能是Fedora 17以後。

2011/06/03

全Linux生活:第34天 - BitNami Redmine Stack設定篇

From Evernote:

全Linux生活:第34天 - BitNami Redmine Stack設定篇

BitNami Redmine Stack不是說很簡單,還要設定嗎?其實要看每個人的雞歪程度來決定!一般狀況下的確是不用設定就可以用了,到底多簡單看就知道,首先下載安裝檔:

     http://bitnami.org/files/stacks/redmine/1.2.0-0/bitnami-redmine-1.2.0-0-linux-installer.bin

執行安裝檔:

     $ chmod +x bitnami-redmine-1.2.0-0-linux-installer.bin
     $ ./bitnami-redmine-1.2.0-0-linux-installer.bin

設定基本資訊:
設定安裝目錄
     預設:/opt/redmine-1.2.0-0
設定Redmine管理員使用者代號
     範例:admin
設定Redmine管理員使用者密碼
設定Redmine管理員使用者名稱
     範例:Redmine Administrator
設定Redmine管理員email帳號
     範例:projectname.iisi.com.tw@gmail.com
設定Redmine管理員使用語言
     預設:[4] English
設定Redmine SMTP
設定Redmine SMTP伺服器位址
     範例:smtp.gmail.com
設定Redmine SMTP Domain
     範例:smtp.gmail.com
設定Redmine SMTP埠號
     範例:587
設定Redmine SMTP帳號
     範例:projectname.iisi.com.tw@gmail.com
設定Redmine SMTP密碼

接下來就是等待安裝﹍

Screenshot_redmine_installation

安裝完成後會問我們要不要啟動Redmine,如果你已經迫不期待想知道Redmine到底是圓的還是方的,可以回答Y立即啟動。

瀏覽器開啟網址:http://<redmine_server_ip>/ ,當然,BitNami還是要宣告一下主權,不然我們可能會忘了它的存在!

Screenshot_bitnami_running

主角上場,點上圖中的"Access BitNami Redmine Stack"或是直接開啟網址:http://<redmine_server_ip>/redmine/,登入在右上角,用剛剛設定的管理員帳號與密碼登入﹍好了,這就是傳說中的Redmine!比自己搞半天還裝得五五六六實在快太多了,重點是如果不說也許你還沒發現其實Redmine是用Rudy on Rail寫的,而且還省掉搞那些Rudy和MySQL還有Apache加起來有三卡車的亂七八糟設定了。

Screenshot_redmine_running

咦,結束了嗎?廢話,當然沒有!又不是第一天搞電腦,當然知道事情怎麽可能那麼順利,有這種程度已經是佛心來的了!其實裝到這裡,是真的已經可以用了,但雞歪一點的人會發現幾件事:

     1. 只有HTTP,沒有HTTPS,資料被人看光光,Oh my god!
     2. Email永遠通知不到要通知的人﹍Holy shit!
     3. Subversion根本還沒設定!不過這不能怪BitNami啦,我們又沒跟他說我們要用Subversion!搞不好有人想用Git不行嗎?
     4. Subversion就算照README.txt設定好,媽的!怎麽只支援svn://﹍連source code也被看光光﹍給我https啦!

BitNami會將所有的東西放在安裝目錄中,也就是/opt/redmine-1.2.0-0目錄下,啟動與停止系統可以這樣做:

     啟動所有servers
     $ sudo ./ctlscript.sh start

     只啟動特定server
     $ sudo ./ctlscript.sh start apache
     $ sudo ./ctlscript.sh start mysql
     $ sudo ./ctlscript.sh start subversion
     $ sudo ./ctlscript.sh start redmine

     停止所有servers
     $ sudo ./ctlscript.sh stop

     只停止特定server
     $ sudo ./ctlscript.sh stop apache
     $ sudo ./ctlscript.sh stop mysql
     $ sudo ./ctlscript.sh stop subversion
     $ sudo ./ctlscript.sh stop redmine


如何啟用HTTPS

1. 修改/opt/redmine-1.2.0-0/apache2/conf/httpd.conf

     $ sudo vi /opt/redmine-1.2.0-0/apache2/conf/httpd.conf

     載入SSL設定檔,找出這行:
     #Include conf/extra/httpd-ssl.conf
     註解拿掉:
     Include conf/extra/httpd-ssl.conf

     避免Redmine的資料被HTTP存取,找到這行:
     Include "/opt/redmine-1.1.3-1/apps/redmine/conf/redmine.conf"
     加上註解:
     #Include "/opt/redmine-1.1.3-1/apps/redmine/conf/redmine.conf"

2. 產生SSL憑證

     $ sudo /opt/redmine-1.2.0-0/common/bin/openssl genrsa -des3 -passout pass:密碼 -out /opt/redmine-1.2.0-0/apache2/conf/privatekey.pem 1024
     $ sudo /opt/redmine-1.2.0-0/common/bin/openssl req -new -key /opt/redmine-1.2.0-0/apache2/conf/privatekey.pem -out /opt/redmine-1.2.0-0/apache2/conf/cert.csr
     設定憑證資訊,這些資訊知道的話就輸入,但大部分如果不知道要打什麼就直接按Enter留白,但記得輪到Common Name(CN)時一定要回答,不可以空白。
     $ sudo /opt/redmine-1.2.0-0/common/bin/openssl rsa -in /opt/redmine-1.2.0-0/apache2/conf/privatekey.pem -out /opt/redmine-1.2.0-0/apache2/conf/server.key
     $ sudo /opt/redmine-1.2.0-0/common/bin/openssl x509 -in /opt/redmine-1.2.0-0/apache2/conf/cert.csr -out /opt/redmine-1.2.0-0/apache2/conf/server.crt -req -signkey /opt/redmine-1.2.0-0/apache/conf/server.key -days 36500
     36500指憑證有效期100年,夠久了吧。

3. 修改/opt/redmine-1.2.0-0/apache2/conf/extra/httpd-ssl.conf

     $ sudo vi /opt/redmine-1.2.0-0/apache2/conf/extra/httpd-ssl.conf

     確保所有Request都會使用HTTPS。找出以下區段:
     #   General setup for the virtual host
     DocumentRoot "/opt/redmine-1.2.0-0/apache2/htdocs"
     ServerName www.example.com:443
     ServerAdmin you@example.com
     ErrorLog "/opt/redmine-1.2.0-0/apache2/logs/error_log"
     TransferLog "/opt/redmine-1.2.0-0/apache2/logs/access_log"
     後面加上一行設定如下:
     #   General setup for the virtual host
     DocumentRoot "/opt/redmine-1.2.0-0/apache2/htdocs"
     ServerName you@example.com:443
     ServerAdmin you@example.com
     ErrorLog "/opt/redmine-1.2.0-0/apache2/logs/error_log"
     TransferLog "/opt/redmine-1.2.0-0/apache2/logs/access_log"
     RequestHeader set X_FORWARDED_PROTO 'https'

     設定server.csr與server.key,不過剛好我們產生憑證時已故意將憑證與金鑰產生在與設定檔裡的設定相同,所以就不用再改了。

     加上Redmine相關設定,讓Redmine的網頁可以使用HTTPS連入。找出以下區段:
     CustomLog "/opt/redmine-1.2.0-0/apache2/logs/ssl_request_log" \
               "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

     </VirtualHost>
     加上一行如下:
     CustomLog "/opt/redmine-1.2.0-0/apache2/logs/ssl_request_log" \
               "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
     Include "/opt/redmine-1.2.0-0/apps/redmine/conf/redmine.conf"
     </VirtualHost>

4. 重新啟動Apache

     $ sudo /opt/redmine-1.2.0-0/ctlscript.sh restart apache

5. 以後改用https://<redmine_server_ip>/redmine/取代http://<redmine_server_ip>/redmine/,而且HTTP不能再用來連Redmine了。

如何設定真的可以用的EMAIL通知

安裝時候可以設定SMTP參數,但那僅限走不加密的SMTP Server可以在設定好直接使用,而且一般是走25埠。因為我們這次打算使用gmail來送信, Gmail使用TLS加密,埠號是587,不幸的是,BitNami安裝Redmine時並沒有把TLS相關的程式加進來,所以有些事還是要自己來。

1. 安裝TLS Plugin

     $ cd /opt/redmine-1.2.0-0
     $ sudo ./use_redmine
     # cd apps/redmine
     # ruby script/plugin install git://github.com/collectiveidea/action_mailer_optional_tls.git
     Initialized empty Git repository in /opt/redmine-1.2.0-0/apps/redmine/vendor/plugins/action_mailer_optional_tls/.git/
     remote: Counting objects: 14, done.
     remote: Compressing objects: 100% (10/10), done.
     remote: Total 14 (delta 2), reused 10 (delta 2)
     Unpacking objects: 100% (14/14), done.
     From git://github.com/collectiveidea/action_mailer_optional_tls
      * branch            HEAD       -> FETCH_HEAD

2. 編輯/opt/redmine-1.2.0-0/apps/redmine/config/email.yml,修改如下:

     production:
       delivery_method: :smtp
       smtp_settings:
         tls: true
         address: "smtp.gmail.com"
         port: '587'
         domain: "smtp.gmail.com"
         authentication: :plain
         user_name: "projectname.iisi.com.tw@gmail.com"
         password: "密碼"

     development:
       delivery_method: :smtp
       smtp_settings:
         tls: true
         address: "smtp.gmail.com"
         port: '587'
         domain: "smtp.gmail.com"
         authentication: :plain
         user_name: "projectname.iisi.com.tw@gmail.com"
         password: "密碼"

3. 重新啟動

     $ sudo /opt/redmine-1.2.0-0/ctlscript.sh stop
     $ sudo /opt/redmine-1.2.0-0/ctlscript.sh start

如何設定Subversion

Subversion支援四種Protocols: http://,https://,svn://,svn+ssh://,因為我們只要用https://所以其他類型就先省略了。

1. 編輯/opt/redmine-1.2.0-0/apache2/conf/httpd.conf,加入Subversion模組

     $ sudo vi /opt/redmine-1.2.0-0/apache2/conf/httpd.conf
     跟apache說要載入svn相關模組,找出這兩行:
     #LoadModule dav_svn_module     modules/mod_dav_svn.so
     #LoadModule authz_svn_module   modules/mod_authz_svn.so
     把註解拿掉
     LoadModule dav_svn_module     modules/mod_dav_svn.so
     LoadModule authz_svn_module   modules/mod_authz_svn.so

2. 建立Subversion Repository

因為BitNami使用的Subversion Apache Module需要特定版本的SQLite檔案,但安裝時沒有放進去,會造成新版的Subversion資料庫檔案寫入失敗,因此建立儲存庫時必須註明相容1.6以前的版本:

     $ sudo /opt/redmine-1.2.0-0/subversion/bin/svnadmin create --fs-type fsfs --pre-1.6-compatible /var/svn/repos/儲存庫名稱

由於BitNami啟動Apache時使用daemon使用者,所以必須把儲存庫下所有檔案與目錄的擁有者改為daemon,否則會有無法開啟或寫入檔案的問題:

     $ sudo chown -R daemon.daemon /var/svn/repos/儲存庫名稱
     $ sudo chown -R g+w /var/svn/repos/儲存庫名稱/db

備註:如果想要從舊得儲存庫把資料搬過來,還是要先以上面的步驟建立一個相容1.6版以前的新儲存庫,接著進行匯出跟匯入:

     於舊得儲存庫執行匯出:
     $ sudo svnadmin dump 舊儲存庫路徑 > repo.backup

     在新的儲存庫進行匯入:
     $ sudo svnadmin load /var/svn/repos/儲存庫名稱 < repo.backup

2. 編輯/opt/redmine-1.2.0-0/apache2/conf/extra/httpd-ssl.conf

     $ sudo vi /opt/redmine-1.2.0-0/apache2/conf/extra/httpd-ssl.conf

     在<VirtualHost>的最後 部份再加上一行,如下:
     Include "/opt/redmine-1.2.0-0/apps/redmine/conf/redmine.conf"
     Include "conf/extra/httpd-svn.conf"
     </VirtualHost>

3. 建立新檔/opt/redmine-1.2.0-0/apache2/conf/extra/httpd-svn.conf

     $ sudo vi /opt/redmine-1.2.0-0/apache2/conf/extra/httpd-svn.conf

     新增內容如下:
        <Location "/svn">
                DAV svn
                AuthType Basic
                SVNParentPath /var/svn/repos
                AuthName "Subversion Repository"
                AuthUserFile /var/svn/repos/auth.conf
                AuthzSVNAccessFile /var/svn/repos/access.conf
                require valid-user
        </Location>

4. 建立/var/svn/repos/auth.conf

為每一位使用者建立密碼檔:

     $ sudo /opt/redmine-1.2.0-0/apache2/bin/htpasswd -m -n 使用者名稱 >> /var/svn/repos/auth.conf
     $ sudo chown -R daemon.daemon /var/svn/repos/auth.conf

5. 建立/var/svn/repos/access.conf

     $ sudo vi /var/svn/repos/access.conf
     新增如下內容:
     [儲存庫名稱:/]
     使用者名稱 = rw
     ﹍﹍

     $ sudo chown -R daemon.daemon /var/svn/repos/access.conf

6. 重新啟動Apache

     $ sudo /opt/redmine-1.2.0-0/ctlscript.sh restart apache

好了,就醬!

2011/06/01

全Linux生活:第31天 - Redmine﹍不,是BitNami Redmine Stack啦!

From Evernote:

全Linux生活:第31天 - Redmine﹍不,是BitNami Redmine Stack啦!

最近一個案子準備進入開發階段,剛好可以利用這個機會把塵封已久的Redmine拿出來玩一玩。剛剛看了一下,我那個PMS VM裡面的Redmine是1.0.3版,上次搞這個東西已經是去年(2010)的事了,雖然記憶已經很模糊了,但一直有個很深刻的印象是這鬼東西還要裝起來還真麻煩!這個PMS VM自從裝好之後,一直陪我走到現在,也歷經了幾個案子,很可惜的是後來Redmine並沒有真正派上用場,倒是裡面的Subversion變成了主角!

記得那時候裝這個PMS VM時,刻意採用全手動安裝,裡面有Apache2+SSL,Subversion,Trac,Redmine,花了不少時間跟精力,後來想起來,會發現其實這些東西都是協助我們管理開發程式的工具,誰是主角?答案其實很清楚,我們要開發的程式才是主角,工具從頭到尾就是工具而已,它的用途其實是讓我們更有條理的把程式做好,而不應該讓我們花太多精力去搞這些工具,特別是很多時候我們花時間研究工具其實就只為了把這些鬼東西跑起來,到底是我們在搞它,還是它在搞我們?所以這次為了不想被工具搞,其實有一個更好的選擇,那就是宛如佛祖下凡的BitNami Stacks!

BitNami Stacks其實更早以前就有試過了,說實話還不錯,可是當時對一個血氣方剛的GY工程師來說,一開始就用這招實在有點遜,講出去搞不好還會被笑,不過隨著經驗與年紀漸漸累積了之後才發現,很遜﹍沒關係,被笑﹍又怎樣,工具好用最重要,它用什麼寫得,它要怎麽安裝才漂亮一點都不重要,BitNami Stacks簡單說就是一堆讓生活變得更快樂的東西,吃下去,雖然上不了天堂,但至少可以讓你準時下班回家陪陪老婆小孩享享天倫之樂!更重要的是,除非是一個很閒很雞歪又很龜毛的工程師,否則自己裝一個Redmine很難會比BitNami裝的好用跟好維護。

所以今天的主角就是:BitNami Redmine Stack,這是什麼鬼﹍簡單講就是菩薩利用空閒時間幫我們包好的Redmine+Subversion+MysQL+Apache2的懶人包,而且既然菩薩做的,所以一定是Windows/Linux/MacOSX全部照顧到,這時候,菩薩當然也有想到,如果你連滑鼠點兩下安裝檔都懶得點,甚至連整套系統含OS都裝好的VM都給你下載,不過如果是連下載都懶的人,唉,那連菩薩也救不了了。

2011/05/17

難忘的AIX日

From Evernote:

難忘的AIX日

距離上次比較認真在用AIX的日子可能快五年了。今天有一個機會又要用到AIX,不過其實我不是AIX專家,很多東西都是現學現賣,畢竟如果不是工作上需要,誰會去搞一台R6裝AIX來玩。不過還好,整體看起來,今天還算順利,雖然遇到很多問題,但總算都有解決:
  1. 磁碟空間不足,需要擴增LV的空間
  2. 使用者預設檔案大小限制1G
  3. ISO檔使用問題
  4. DB2安裝問題:沒有X Window,只能用db2_install安裝
  5. WAS安裝問題:沒有X Window,只能用Silent Mode安裝
  6. SWAP太小!非常嚴重。
  7. COMM. SERVER安裝問題:必須用smit安裝
整體工作分配大致是這樣:
taskpie20110516
其中傳檔花了蠻多時間,因為廠商區的網路頻寬被限制住,除此之外花最多時間是在搞檔案大小問題,LVM,SWAP,SMIT這些東西。

今天最驚險部份發生在設定WAS的時候,因為客戶提供的機器實在有夠兩光,RAM只有1G,而且SWAP只有開512M,而且誰會沒事去注意這個?所以,當我db2跑起來而且dmgr跟nodeagent都搞定後,準備要啟動server01的時候,怎麽弄都無法啟動,回到console下指令的時候才發現大事不妙,不管執行什麼程式,只要不是目前正在跑得程式全都無法啟動,顯示的訊息都是:no swap space!靠夭咧,這下完全動不了,所有指令全部無效,最慘的是連kill,reboot跟shutdown這些都沒用,而且想到機器根本不在台北,看來這種狀況非得在機器上接console線才能處理,而且還要去跟客戶解釋這個狀況﹍簡直快昏倒了。還好,天無絕人之路,靈機一動想說dmgr好像還可以用,雖然dmgr似乎沒辦法把自己停下來,可是nodeagent可以!於是進去admin console把nodeagent停下來之後,終於﹍console恢復正常了。事不宜遲,現在第一件事當然是趕快研究一下SWAP如何加大,給你4G總夠了吧,害我差點搞掛一台R6!

今天的經驗發現,AIX有些很龜毛的限制,比如每個使用者都有建立檔案大小的限制,預設值是1G,很衰的是DB2的壓縮檔剛好超過1G一點點。所以傳檔的時候怎麽傳都會失敗,想說是見鬼了喔,一開始不太相信怎麽會有這麼龜毛的限制,結果查了一下,媽的﹍還真的是這麼龜毛。光這問題也害我卡了快辦個小時﹍

順道一題AIX的LVM還蠻強的,原本Linux的LVM我已經覺得很好用了說,結果看到AIX的LVM﹍嗯﹍這就是Benz跟Toyota的差別!

2011/05/16

很模糊,但很有感覺。

夭壽好吃牛肉麵在麻辣火鍋店?

全Linux生活:第16天 - 在Linux下編譯Windows DLLs

From Evernote:

全Linux生活:第16天 - 在Linux下編譯Windows DLLs

最近工作上要做一個Windows下的JNI DLL,這原本在純Windows下是很簡單的事,但在Linux下,是有那麼一點麻煩。在Linux下要做cross platform compile,有幾個選擇:MingGW,Cygwin。但如果考量到team work的話,要強迫其他人也要使用Linux來寫程式也說不過去,所以目前暫時不考慮"純種"的cross platform compilation,我的作法是使用Windows下的C/C++ Compiler來進行編譯,考量到Comiler大小與不要有runtime相依性問題,那選擇有3個Visual C++ 6.0,MinGW Windows版,Borland C++ 5.5(什麼﹍這鬼東西還有人用嗎?)。當然,可以免費使用的只有MinGW與Borland C++ 5.5,而且Size最小的是Borland C++ 5.5,只需要50MB左右,最大的是Visual C++ 6.0,約180MB,第二名是MinGW,約120MB。

可是這些東西在Linux下可以用嗎?當然是不能直接用,但是透過WINE就可以。這樣做最大的好處是同一個專案可以在Linux與Windows下通用(甚至Mac OS X,但一樣要裝WINE才行)。

不囉唆,先準備JNI環境:
  1. 首先在Eclipse建立一個HelloWorldJNI專案
  2. 建立目錄結構如下圖:
    helloworldjni_structure
    其中jdk_include目錄內的檔案請從32位元Windows版的JDK中複製取得。

如果想用Visual C++ 6.0,請服用:
  1. 取得VIsual C++ 6.0:噓﹍不要問很恐怖﹍
  2. 安裝Visual C++ 6.0:

    $ wine <PATH-TO-MSVC60-CD>/setup.exe

  3. 在Eclipse建立MSVC60專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf "~/.wine/drive_c/Program Files/Microsoft Visual Studio/Common" <PATH-TO-MSVC60-PROJECT>
    $ cp -rvf "~/.wine/drive_c/Program Files/Microsoft Visual Studio/VC98" <PATH-TO-MSVC60-PROJECT>

    msvc60_structure

  5. 複製並修改vcvars32.bat:

    $ cp <PATH-TO-MSVC60-PROJECT>/VC98/Bin/VCVARS32.BAT <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/vcvars32.bat
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/vcvars32.bat

    @echo off
    set MSVC60_HOME=%CD%\..\..\..\msvc60

    rem
    rem Root of Visual Developer Studio Common files.
    set VSCommonDir=%MSVC60_HOME%\Common

    rem
    rem Root of Visual Developer Studio installed files.
    rem
    set MSDevDir=%MSVC60_HOME%\Common\msdev98

    rem
    rem Root of Visual C++ installed files.
    rem
    set MSVCDir=%MSVC60_HOME%\VC98

    rem
    rem VcOsDir is used to help create either a Windows 95 or Windows NT specific path.
    rem
    set VcOsDir=WIN95
    if "%OS%" == "Windows_NT" set VcOsDir=WINNT

    rem
    echo Setting environment for using Microsoft Visual C++ tools.
    rem

    if "%OS%" == "Windows_NT" set PATH=%MSDevDir%\BIN;%MSVCDir%\BIN;%VSCommonDir%\TOOLS\%VcOsDir%;%VSCommonDir%\TOOLS;%PATH%
    if "%OS%" == "" set PATH="%MSDevDir%\BIN";"%MSVCDir%\BIN";"%VSCommonDir%\TOOLS\%VcOsDir%";"%VSCommonDir%\TOOLS";"%windir%\SYSTEM";"%PATH%"
    set INCLUDE=%MSVCDir%\ATL\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\MFC\INCLUDE;%INCLUDE%
    set LIB=%MSVCDir%\LIB;%MSVCDir%\MFC\LIB;%LIB%

    set VcOsDir=
    set VSCommonDir=

  6. 建立cl.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/cl.bat

    echo off
    @call bin\vcvars32.bat
    cl %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\cl -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -MD -LD ${moduleName}\\${moduleName}.c -Fe${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\cl -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -MD -LD ${moduleName}\\${moduleName}.c -Fe${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>

  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse

如果想用MingGW,請服用:
  1. 取得MingGW:MinGW官網

    $ wget http://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/mingw-get-inst/mingw-get-inst-20110316/mingw-get-inst-20110316.exe/download


  2. 安裝MingGW:

    $ wine <PATH-TO-DOWNLOAD-DIR>/mingw-get-inst-20110316.exe

  3. 在Eclipse建立MINGW專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf ~/.wine/drive_c/MingGW/* <PATH-TO-MINGW-PROJECT>

    mingw_structure

  5. 建立mingwenv.bat:
     
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/mingwenv.bat

    @echo off
    set MINGW_HOME=..\..\..\mingw
    set PATH=%MINGW_HOME%\bin;%MINGW_HOME%\mingw32\bin;%PATH%
     
  6. 建立gcc.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/gcc.bat

    echo off
    @call bin\mingwenv.bat
    gcc %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -shared ${moduleName}\\${moduleName}.c -o ${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -Ijdk_include -Ijdk_include\\win32 -I${moduleName} -shared ${moduleName}\\${moduleName}.c -o ${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>

  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse -1


如果想用Borland C++ 5.5,請服用:
  1. 取得Borland C++ 5.5:Codegear官網
  2. 安裝Borland C++ 5.5:

    $ wine <PATH-TO-DOWNLOAD-DIR>/freecommandLinetools.exe

  3. 在Eclipse建立BCC55專案(General Project就可以了)
  4. 複製Compiler檔案:

     $ cp -rvf ~/.wine/drive_c/Borland/BCC55/* <PATH-TO-BCC55-PROJECT>

    bcc55_structure

  5. 建立bcc55env.bat:
     
    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/bcc55env.bat

    @echo off
    set BCC55_HOME=..\..\..\bcc55
    set PATH=%BCC55_HOME%\bin;%PATH%
     
  6. 建立bcc32.bat:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/src/jni/bin/bcc32.bat

    echo off
    @call bin\bcc55env.bat
    bcc32 %*

  7. 編輯build.xml:

    $ vi <PATH-TO-HELLOWORLDJNI-PROJECT>/build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project name="Packaging Generator" default="all">

        <property name="dir.src" value="src" />
        <property name="dir.src.java" value="${dir.src}/java" />
        <property name="dir.src.junit" value="${dir.src}/junit" />
        <property name="dir.src.jni" value="${dir.src}/jni" />
        <property name="dir.src.jdkinclude" value="${dir.src}/jni/jdk_include" />
        <property name="dir.etc" value="etc" />
        <property name="dir.lib" value="lib" />
        <property name="dir.deploy" value="deploy" />
        <property name="dir.classes" value="tmp" />
        <property name="dir.build" value="build" />

        <target name="all">
            <antcall target="HelloWorld.dll" />
        </target>

        <target name="HelloWorld.dll">
            <property name="moduleName" value="HelloWorld" />
            <mkdir dir="${dir.deploy}" />
            <delete>
                <fileset dir="${dir.src.jni}" includes="${moduleName}.*" />
            </delete>
            <javah class="test.${moduleName}" outputFile="${dir.src.jni}/${moduleName}.h" classpath="${dir.classes}" />
            <exec dir="${dir.src.jni}" executable="wine" os="Linux,Mac OS X">
                <arg line="cmd /c bin\\bcc32 -Ijdk_include -Ijdk_include\\win32 -I..\\..\\..\\bcc55\\Include -L..\\..\\..\\bcc55\\Lib -I${moduleName} -WD ${moduleName}\\${moduleName}.c -o${moduleName}.dll" />
            </exec>
            <exec dir="${dir.src.jni}" executable="cmd" os="Windows 95,Windows 98,Windows NT,Windows 2000,Windows XP,Windows Vista,Windows 7">
                <arg line="/c bin\\bcc32 -Ijdk_include -Ijdk_include\\win32 -I..\\..\\..\\bcc55\\Include -L..\\..\\..\\bcc55\\Lib -I${moduleName} -WD ${moduleName}\\${moduleName}.c -o${moduleName}.dll" />
            </exec>
            <copy todir="${dir.deploy}" overwrite="true" failonerror="false">
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.dll" />
                    <include name="${moduleName}.lib" />
                </fileset>
            </copy>
            <delete>
                <fileset dir="${dir.src.jni}">
                    <include name="${moduleName}.*" />
                </fileset>
            </delete>
        </target>

    </project>
     
  8. 執行build.xml,產生HelloWorld.dll:

    Screenshot-Java - HelloWorldJNI-build.xml - Eclipse -2


2011/05/15

全Linux生活:第15天 - 製作光碟ISO

From Evernote:

全Linux生活:第15天 - 製作光碟ISO

在Linux下製作ISO真是出奇的簡單,用dd或mkisofs就搞定了。
從硬碟資料產生ISO,請服用:

     $ mkisofs -o /tmp/cd.iso /source_directory

從光碟機產生ISO,請服用:

     $ dd if=<device> of=/tmp/image.iso

其中<device>就是光碟機的裝置,我目前的Ubuntu是/dev/sr0,但有些可能是叫/dev/cdrom或/dev/hdc或/dev/sdb之類的,如果真的不確定,可以用指令查一下:

     $ dmesg|grep CD-ROM
     [    3.693625] scsi 1:0:0:0: CD-ROM            HL-DT-ST DVD+-RW GA31N    A102 PQ: 0 ANSI: 5
     [    3.706587] cdrom: Uniform CD-ROM driver Revision: 3.20
     [    3.706778] sr 1:0:0:0: Attached scsi CD-ROM sr0

如果什麼都沒有,哪你可能要懷疑一下你的電腦是不是有光碟機?不過還是可以來找看看,查一下系統目前有哪些磁碟裝置:

     $ ls -l /sys/block/*/device
     lrwxrwxrwx 1 root root 0 2011-05-15 11:02 /sys/block/sda/device -> ../../../0:0:0:0
     lrwxrwxrwx 1 root root 0 2011-05-15 11:32 /sys/block/sdb/device -> ../../../5:0:0:0
     lrwxrwxrwx 1 root root 0 2011-05-15 11:02 /sys/block/sr0/device -> ../../../1:0:0:0

然後看一下裝置type是不是5,因為5表示ROM,如果看到是0,表示是DISK:

     $ cat /sys/block/sda/device/type
     0
     $ cat /sys/block/sdb/device/type
     0
     $ cat /sys/block/sr0/device/type
     5

如果吃飽太閒沒事幹,想知道有哪些type是什麼意思,可以查一下:

     $ cat /usr/include/scsi/scsi.h|grep TYPE_
     #define TYPE_DISK           0x00
     #define TYPE_TAPE           0x01
     #define TYPE_PROCESSOR      0x03    /* HP scanners use this */
     #define TYPE_WORM           0x04    /* Treated as ROM by our system */
     #define TYPE_ROM            0x05
     #define TYPE_SCANNER        0x06
     #define TYPE_MOD            0x07    /* Magneto-optical disk -
                                          * - treated as TYPE_DISK */
     #define TYPE_MEDIUM_CHANGER 0x08
     #define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
     #define TYPE_NO_LUN         0x7f



2011/05/14

這條路到底要搞多久啊?

這個時候,最適合在這個位置想事情。

瑪莉亞二號報到!

瑪莉亞二號報到! by nanotiny
瑪莉亞二號報到!, a photo by nanotiny on Flickr.

全Linux生活:第11天 - PDF印表機

From Evernote:

全Linux生活:第11天 - PDF印表機

又是工作上的需要,我要將列印資料輸出到PDF檔案,以前在Windows下,有很多選擇可以選,如CutePDF,PDFCreater﹍可是在Linux下,這些都不能用,那用WINE執行呢?很抱歉,還是不能用,親自測試的結果是,CutePDF連安裝程式都跑不完就掛了,PDFCreater看起來還不錯,至少安裝程式跑完了,虛擬印表機也有出現,但實際列印時,好像石沉大海一樣,沒有任何反應。嚴格說起來,WINE在Printing的支援度,只能說還是不行,光看WINEHQ-Printing這份清單還有那麼多叉叉就已經三條線了﹍

     Screenshot-Printing - The Official Wine Wiki - Google Chrome

想在WINE下使用PDF Printer目前看起來只有Adobe Arcobat比較有機會(實在懶得試了,況且我手上也有沒有任何版本的Acrobat,但至少有人說可以用)。

不過話說回來,幹麼一定要使用Windows環境的PDF Printer?是頭殼壞掉嗎?其實Linux下的PDF Printer也是很多,最簡單的就是CUPS-PDF。
安裝CUPS-PDF:

     $ sudo apt-get install cups-pdf

這樣就ok了,接著在『控制中心』的『列印』裡面就可以看到已預設裝好一個『PDF』的虛擬印表機:

     Screenshot-列印 - localhost

在Linux下,只要列印的時候選這台就對了。接下來,我們會很好奇那如果是WINE下的Microsoft Word,Excel,Visio這些軟體可以使用Linux下的Printer嗎?答案是,可以的。實際使用結果是:不管Linux或WINE下的應用程式,都可以使用這個PDF Printer,同理如果是一般印表機應該也是ok的。

要注意的是,CUPS-PDF產生PDF檔時,不會像Windows下的PDF Printer一樣跳一個視窗出來問你要存到哪裡,而是直接產生一個PDF檔到${HOME}/PDF下面,如果想修改存檔路徑或是檔名或其他參數,可以看一下/etc/cups/cups-pdf.conf設定檔。