SyntaxHighlighter

2016-07-03

[翻譯文]開源跨平台開發方法與工具

這是我近年來一直很想好好坐下來寫的一篇文章。我一開始是從開發90年代後期的軟體開始的,並且為我自己取得了一個Borland C++編譯器,藉此我快速地理解在Windows中什麼才是真正在背後實際應該要做的事。一開始我寫了一些小型的命令列應用程式,並且開始嘗試使用圖性介面的應用程式。我好愛創造的過程,也對這套工具的很多地方感到不滿。在那時候,我並沒有真正走進適用簡單的範例之後的過程。

過了一段時間後,我開始對開發網路應用程式感到興趣,並在對Perl感到失望後開始玩弄一個叫做PHP的新語言。我喜歡那些讓我可以非常自由的混合程式碼與HTML,並擁有使用PHP語言來對伺服端機器擁有完整存取權的感覺。我用PHP開發了一些網站,並試著使用不同的方法在可能的狀況下盡可能地將處理丟給JavaScript去做。這些真的很菜,但是將他與資料庫連結這件事讓我成長了很多。我也同時開始處理郵件清單,回答一些問題,並學習我所能知道有關已開發的開源軟體語言的任何事情。

在那之後我有一點分心到Linux身上,封裝應用程式,身為一個Gentoo開發者將那些推送給新的64位元架構。那真的很好玩,而且我學到了很多有關相依性、安全性更新、共享函數庫、以及在撰寫建造系統中許多科學家是處於多麼壞的處境中。經過這個時期,我也學到有關如何成為一個延展的線上社群的一份子,並有機會與很多非常熟練且專業的人共同作業。

C++與原生開發

最終,我理解到我想要開發軟體,而且當我不得不存取硬體時我真的想要使用原生語言來做開發。在那時候我使用Linux作為我的主要作業系統,但是我也必須與那些使用主流的Windows與Mac OS X的人們一起工作。我想讓可以使用我開發的軟體,但不想因為這樣寫三次程式碼。於是我開始調整軟體庫,主要針對KDE以及那些我必須要在Google Summer of Code專案中使用的部分。這就是最近九年左右我在Google Summer of Code專案中所做的事,而且我主要使用同樣的堆疊,增加或是更新函數,來促進合作,開源與跨平台開發。

C++是一個標準化的程式語言,擁有很多強力的開源編譯器與許多延伸編譯器支援,分散於從嵌入式系統到地球上最大的超級電腦中的所有地方。在我的作業中,我們定期將目標放在業界的兩個極端,就像是在桌機/筆記型電腦上的許多作業一樣。我想它仍然是最多元化的語言之一,擁有對比於C語言的高階特性,卻又與基層夠接近可以得到良好的性能。他也可以使用許多通常使用C語言介面擴展的API, 甚至可以在需要的時候與FORTRAN溝通。

跨平台抽象度

C++可以用可攜式的方式撰寫,但是有很多平台專用的API, 工具組,以及語言延伸套件。有很多方式可以建造C++應用程式。我一開始使用簡單的手寫Makefile,但是很快地就發現即使是維護那些簡單的專案也十分的瑣碎且容易出錯。我開始尋找Autotools, 然後轉向SCONS, 在大約是KDE在尋找切換方式前開始跨到CMake。

CMake是一個標記型建造系統生成器,那意味著他並沒有自己直接打造任何東西。你會使用CMake語言去指定你的專案應該要怎麼被建造,並且可以在必要的時候定義特定平台的例外。這也許聽起來有一點瑣碎,但是你可以得到一些十分巨大的回饋——他將為你的環境創建一個編譯系統。如果你想要用Visual Studio,請自便。如果你想要Makefile,很好。如果你偏好新的Ninja系統,你可以用它。我通常使用Ninja與那個叫CodeBlocks的東西來打造我的Qt Creator集成環境。

一旦你有某些可以打造的東西了,你會想要思考如何將視窗介面虛擬化。我也歷經了一點虛擬化,包括Java Swing, GTKMM(C++可以用GTK來替換), wxWidget, 以及一些我想我不願提到。我最後是留在Qt身上了,而他已經慣於擁有一個大缺點是他是在GPLv2版權協議下,而你的代碼必須同樣使用GPL公開,除非你付商業版權的費用。那總是雙重定義,但我從不真的喜歡這個方案。比起其他我試過的方案,他真的是非常好用,並且讓我覺得非常務實且自然,而且它在KDE上有一個很大的友善開源開發者社群。

另一個好事我經常藉由Qt獲得的是原生的視覺外觀。這個虛擬化努力的使用原生的Widget, 檔案對話框、色彩選擇器、諸如此類。就像工具箱進化後,他可以延伸到支援Android與iOS, 並且他在Nokia被Trolltech合併後改為使用LGPL授權。他也與KDE e.V.達成協議確保她永遠都是自由的,這替未來提供了保障。

版本控制,源碼review

我一開始使用CVS,而我們通常在東西被整合進Gentoo與KDE之後會review源碼。他做得很好,但是需要規範開發者留意提交清單上的提交訊息。切換到Subversion之後事情依然很類似,但是工具感覺較為易於使用且擁有更小的單元性(atomicity)。

對我來說,最大的改革是發生在搬到Git的時候。一開始,我們慣於把它用的像是一個簡單的拖拉置換,有能力可以在在上傳前於本機端提交。晚一點我們開始尋找更為整合性的源碼review,試著找出一些解決方案。有一陣子我們使用Gerrit, 但是我從不覺得那個介面夠直觀,我也不喜歡他專注於單一的提交上。

我現在大部分的工作都是使用GitHub或是GitLab, 兩者都擁有強力的焦點在拉取/整合需求上,感覺就像是分支包含了一個或多個的提交。這讓我們分離事情給分別的提交上,而這感覺比較符合直覺,可以發行他們就像他們被開發的目的一樣,而且請求review當它已經準備好被整合了。我喜歡這個等級的粗度,讓我可以切換到單一的提交,了解為什麼發生了一組變更,或是看到分支中的不同點。逐行註解容許我們專注在review上,並讓高層級的討論可以被放在主要頁籤裡面。

自動化構建與測試

跨平台開發中的另一個重要的方面是自動化構建與測試。這也同時讓我們不用進入到構建/封裝的相依性之中,就像我們很少寫那些不會在其他函式庫中重用的源碼。這是另一個CMake提供了非常大的幫助的部分,而我們的做法也時常進化。

我想這是在跨平台開發中一個或是多個困難的方面,而某些平台上會比其他平台更加困難。傳統的做法是使用cron工作分配去自動執行構建起始過程,而控制host上的dashboard腳本主要使用CMake透過CTest去自動建構。他們也會生成建構文件並上傳到CDash.

很多專案都擁有我們稱之為超建構(superbuilds)的某種東西。他們會在我們感興趣的專案最終建構之前自動化建構與專案的相依性階段。他們讓我們可以確定每一件東西都是在正確的旗標與正確的版本下被建造的。他們也會與CPack互動,在某些狀況下創建為不同的平台創建安裝器。CDash將會顯示出建造的概要,被自動創建的安裝器,測試結果,等等的資訊。

總結

跨平台開發是一個挑戰。這很重要,看到你所做的改變的結果在數小時(或者是數天,在最糟的狀況下)推放到其他平台上。一個專案需要考慮到跨平台作為他的流程的一部份,為了獲得最佳的結果。我可以在我們的做法上提到更多,但是這篇文章已經太長了。你可以用原生碼來獲得更好的結果,而且科學應用程式通常擁有數量龐大的額外依賴。一旦你將超級電腦與崁入式裝置混進來,事情就會變得十分有趣。


本文章原文來源: Open source cross-platform development methods and toolsI by Marcus D. Hanwell posted 20 Jun 2016 on opensource.com

2016-05-21

[BASH]搬移單一檔案到特定名稱資料夾

專門在整理謎片用Bash Script
結合最近才學到的find指令

find是個好指令,可以找出目前目錄下的特定檔案名稱的檔名
簡單說明一下使用法

使用法1, 找特定檔名。
find . -name [想找的名字(可搭配萬用字元)]

乍看之下跟ls很像,但是這傢伙可以自動找出子目錄中的檔名。但是光這點還不是很實用啊

使用法2, 找特定檔名後執行特定動作。
find . -name [*.txt] -exec rm -rvf {} \;
好,這很重要。上面示範了找到特定名稱後直接刪除。而且是連同同名子目錄下檔案一同遞歸刪除。上面的{}代表找到的檔案名稱,最後的\;代表執行指令到此為止。

好吧,上面的功能都是拿來刪除不需要的檔案的,根本沒有踏入正題
實際上很常用的功能:替單檔建立個別資料夾,然後把單檔歸檔
for file in `ls -1 *.avi`
    do
        mkdir -v ${file%.*}
        mv -v $file ${file%.*}/
    done
怎麼做到的?
首先找出特定單檔:這裡我用了找.avi檔。-1很重要,這個清單我並不想看到除了檔名以外的資訊。
然後用bash script裡面的字串操作,將最後的副檔名去除${file%.*}
接下來大家就知道啦,反正就是個別搬走。
但是這招現在有缺點,對付名字中間有空格的還是沒輒。還需要改進啊...

以上

2016-04-15

[LISP]LISP基本指令-取出表元素

前言

Lisp的全名叫做LISt Processor,事實上內部大部分的元素都是一種表,而且是一種二元樹(binary tree)表。

在LISP裡面有用括號圍起來的都叫做表(table? tree?),比如說
(+ 1 2)
'(hello world)

而沒有用括號圍起來的都是原子,翻譯應該是Atom(我亂唬爛的)。
比如說上面的'(hello world)裡面就有兩個元素helloworld
空白的表,通常會傳回()或是NIL

表操作指令

CAR

好,我在上面有寫到,在LISP裡面其實是用二元樹表儲存所有的資料。所以可以利用一些內建函數去取出裡面的內容。
而CAR是用來取出二元樹的左分支用的內建函數
我們假設有個表長得像'(a b c d),以下的敘述會抓到左分支,也就是a
(car '(a b c d))
記得我上一篇有寫到,LISP裡面是沒有大小寫之分的,所以CARcar在LISP中都是一樣的指令。
某網站有寫到FIRSTCAR的全名,但是在AutoCAD中並不支援...所以還是乖乖開CAR

CDR

有抓到二元樹的左枝了,那也要想辦法抓右枝阿。抓右枝的函數在LISP裡面就叫做CDR
(CDR '(a b c d))
結果會是(b c d)

其他的表元素抽取函數?

好,我們能抽取出左分支,也能抽出右分枝。那我們來練習一下取出第二個元素好了。要在一串LIST裡面取出第二個元素,第二個元素其實就是右分支的左分支,我們可以這樣寫
(CAR (CDR '(a b c d)))
很長喔,所以在AutoLISP裡面有短縮版,就是CDAR
(CADR '(a b c d))
都一樣可以得到我們想要的結果:取得元素b。
那如果我們要取出第三元素呢?OK, AutoLISP又有短縮版可以取得第三元素以後的右分支,CDDR
(CDDR '(a b c d))
他會傳回(3 4)這個表。當然也可以用古老式的逼供法
(CDR (CDR '(a b c d)))
他一樣會傳會(3 4)這個表。
接下來就不用教了吧(笑),開CAR去把左元素取出來阿。
(CAR (CDDR '(a b c d)))
也可以縮寫成以下形式
(CADDR '(a b c d))
以此類推...要記得不要把A卡在右元素,你會拿不到內容阿(笑)

LISP基本概念(1)

繁體中文的LISP的網路教學太少,只好自己寫筆記
起始原因只是因為AutoCAD用的很火大,想要自己寫Batch Script來做轉換
很不巧AutoCAD使用的是VisualLISP,前身是AutoLISP,最最原始的就是LISP,或者我們說是CommonLISP。新潮一點的,可以找Clozure CL

參考網站

  • 維基教科書:LISP入門 - (正體中文)說實在的他不是一個教學AutoLISP的網站,內容也有點舊,但是這是我能看到比較完整的LISP正體中文教材。
  • AfraLISP() - (English)在Google能查到的AutoLISP/Visual LISP免費教學網站,一開始由Kenny Ramage建構,有經過大改版,有很多入門文章。
  • OffshoreCad AutoLISP (SpeedDraft) - (日本語)某公司放出來的教學。也有放出原始碼供參考,算是源碼參考的好站點吧。

LISP的基礎

第一個重點,LISP是一種前制運算元的語言。換句話說,你必須改掉在其他編程語言的習慣。

舉例來說,在一般的加法上,我們也許會寫
a+b
但是在LISP裡面,你必須寫成像這樣
(+ a b)

同理可證,
A*B
必須寫成
(* A B)

ok,這是基本的二元運算,現在我們來看看函數function。
一般的編程語言中,我們會寫
f(x)
而在LISP之中,他會看起來像是
(f x)
直接將引數放在函數名後面,很容易理解吧

當有兩個以上的引數時要怎麼寫呢?在一般的語言中,他會長得像
f(x,y)
而在LISP中,他會看起來像是
(f x y)
非常直覺,很好

最後一個重點,LISP之中指令(或說函數名)是大小寫不分的。

2015-09-15

AutoCAD 2016系列 中文字無法正確排列問題

在AutoCAD 2016系列中
內建的DWG to PDF設定有問題,導致中文字的排列間隔不正確

解決方法如下
1. 變更出圖設定,將文字以圖形方式出圖
2. 使用外部PDF轉換程式
3. 到下面網址下載update後,自行置換掉內建的DWGtoPDF Driver
連結請按此


參考網址:
http://www.synnex.com.tw/asp/fae_qaDetail.asp?topic=FAE&group=&parent=&classifyid=01997&seqno=22284&vendor=AUTOD

人気の投稿