Lazarus Faq/zh TW

From Free Pascal wiki
Jump to navigationJump to search

العربية (ar) Deutsch (de) English (en) español (es) français (fr) magyar (hu) italiano (it) 日本語 (ja) 한국어 (ko) português (pt) русский (ru) slovenčina (sk) 中文(中国大陆)‎ (zh_CN) 中文(台灣)‎ (zh_TW)

這份常見問答是從 www.freepascal.org 的常見問答中複製來的, 就像這份維基百科文件一樣,是比較容易維護跟擴充的。

一般問題

我可以從哪裡找到更多常見問答呢?

您可以參考Free Pascal官方網站. 那裏也有一些常見問答的資料。

為何編譯後產生的二進位檔案這麼大呢?

目前的二進位檔案之所以會這麼大,是因為裡面包含了很多用 GNU 偵錯程式(gdb)需要的偵錯所需的資訊。

編譯器裡面有個選項可以用來移除這些偵錯所需的資訊 (-Xs),但因為編譯器早期的版本(2.0.2版與更早的版本)中有個錯誤,所以早期的版本使用這個去除偵錯資訊的功能時會出錯。但這個問題已經在2.0.2版以後被修正了。

您也可以使用一個叫做 “strip” 的程式來把偵錯資訊從執行檔裡面給移除掉,”strip”這個程式位於lazarus 的目錄底下的 lazarus\pp\bin\i386-win32\.

您只要在命令列上輸入這個命令: "strip --strip-all <您的執行檔檔名(要完整路徑) >" 就能把偵錯資訊整個移除掉了。

如果您想讓您的程式檔案更小,那麼您也可以試試看UPX UPX。UPX是一個很棒的執行檔壓縮程式,由於使用了替換式解壓縮法(in-place decompression),它並不會使用額外的記憶體,而解壓縮的速度也非常快。(在 Pentium 133 CPU上面解壓縮,速度約10 MB/sec)

使用UPX,只要在命令列上輸入"upx <您的執行檔檔名(要完整路徑) >" 即可。

在使用了strip與upx對Lazarus編譯出來的簡單視窗程式進行處理後: Linux 上檔案的大小,約剩下 700KB Windows 上的檔案大小,約剩下 420 KB

如果您對UPX的運作背景需要更深入的了解,請參閱 Size Matters.

請記得,在Lazarus的標準安裝程式中,已經包含了許多功能,這些功能是很重要的,包含有:

  • XML 處理函式庫
  • 對 png, xpm, bmp 與 ico 格式圖片的處理函式庫
  • 在 Lazarus 元件庫中,包含了幾乎所有的視窗元件 (widgets)
  • 所有 Free Pascal 的Runtime Library

所以Lazarus占用的磁碟空間是挺大,不過也幾乎已經包含了在現實世界的程式裡面所需要的功能。

Lazarus 的執行檔一開始也會占用不少記憶體,但占用記憶體的成長速度在執行過程中很慢,因為在Free Pascal 編譯器的設計是如此的。一般而言,C++ 編譯器製作出來的程式在一開始會占用很少的記憶體,但很快的,這些程式在使用到程式語言內附的功能以外的程式碼時,占用的記憶體就以幾次方的幅度成長了。 (只是以 C++做個例子,其他的程式語言跟工具也都一樣)

Lazarus vs cpp.png

為何在Windows系統上面連結程式會這麼慢?

一般來說,在Windows作業系統上面的編譯會比其他作業系統來的慢,這是因為Free Pascal 所使用的連結程式: GNU的連結程式(Linker),在Windows上面比較慢。這個問題只發生在Windows作業系統上,而且只有在比較慢的電腦上(CPU 為單核,且頻率低於 1GHz,而記憶體低於128MB時)

另外,如果您對LCL使用SmartLink,也會讓這個連結速度變慢,您可以參考這個研究: File size and smartlinking

因此從 Free Pascal 2.2 版開始,Free Pascal就內建了一個連結程式,這個連結程式大大的降低了連結程式所花的時間。

註記: 在 2.1.1 版,Free Pascal 就在Windows 作業系統上面使用了一個內建的連結程式,用來連結 win32/64/ce的程式,結果的確加快了一些速度,當時 Lazarus的重新編譯作業,耗費將近280MB的記憶體。

我會需要 ppc386.cfg 或 fpc.cfg 嗎?

您只需要fpc.cfg. 從這個檔案裡面,編譯器會知道要從哪裡找到相關的函式庫。

我要如何編譯 Lazarus 呢?

在命令列裡面輸入類似以下的指令即可 (Windows 需要安裝有 VC++或 GCC喔):

$ cd lazarus
$ make clean all

我要怎麼編譯/產生其他使用 LCL的專案呢

如果你無法使用 Lazarus的IDE的話,請使用 lazbuild。這是沒有視窗版的IDE,可以用來編譯 Lazarus的專案或套件。 如果您既不想透過IDE,也不想用lazbuild來編譯專案的話,請將以下這幾行加在您的“fpc.cfg”裡面:

  # 搜尋您要編譯的套件所在的路徑 (Linux)
  -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/{YourToolKit}
  #搜尋您要編譯的套件所在的路徑(Windows)
 -Fu/{YourLazarusDirectory}/components/units/{YourToolKit}
這裡的{YourToolKit} 可能是 gtk2, gnome, qt 或者 win32,然後執行:
ppc386 your.project.pp

提示: 別忘了在您的系統上面安裝您想安裝的套件所用到的開發函式庫,否則在連結的時候,您可能會看到畫面上回應出現類似的錯誤: Linker message: cannot find -l.

我需要哪個版本的FPC 呢?

Mac OSX 目前只能使用2.0.4,而2.2.0則可以使用在其他任何的作業系統上。 小心喔: 2.2.0使用在 Mac OSX 上面,會因為檔名會分辨大小寫而發生錯誤。 您也可以使用 SVN 來取得 FPC 2.2.1與2.3.x

我無法編譯 Lazarus,怎麼辦?

  1. 請檢查您的編譯器是否為正確的版本
  2. 請檢查您的 Free Pascal 各個函式庫的版本是否一致
  3. 請確認您的系統中只有fpc.cfg 這個設定檔,而不是舊版的設定檔ppc386.cfg
  4. 請確認常見問答中,與作業系統相關的問答

當我試著要編譯一個專案的時候,發生錯誤了…

編譯時出現 "Cannot find Unit interfaces" 這個錯誤訊息了,我要怎麼解決這個問題?

這個訊息是表示編譯器找不到 'interfaces.ppu' 這個檔案。或者該檔案有被找到,但檔案錯誤了,或者版本太舊了。

這個單元檔可以從以下路徑找到: {LazarusDir}\lcl\units\{TargetCPU}-{TargetOS}\{LCLWidgetSet}\interfaces.ppu. 例如在 Linux上面,應該會是在這個路徑: /home/username/lazarus/lcl/units/i386-linux/gtk/interfaces.ppu.

請務必確認該檔案只出現一次。如果您的系統中有多個版本的 interfaces.ppu,那您的設定可能有問題。(例如,您把 LCL 的路徑加到了搜尋路徑中,而LCL路徑中正好有不同版本的 interfaces.ppu) 如果是這個情形,請把所有其他的 interfaces.ppu都移除,只留下上一段所提及的路徑底下的interfaces.ppu。

如果您選用了不同的 widgetset 來重新編譯Lazarus,那麼您也必須把LCL重新編譯,以符合選用的widgetset。

如果該檔案存在上述的位置,但還是出現了這個錯誤的話,則表示您正在使用的是不同版本的編譯器或RTL,您可以嘗試以下的任一方法來處理:

  • 使用 Environment選項裡面的編譯器來重新編譯 LCL (或者重新編譯整個 Lazarus)。您可以透過Lazarus上面的選單項目來做這個動作: 點選Tools-> Build Lazarus (在重新編譯Lazarus前,您也可以先對編譯動作進行設定: Tools -> Configure Build Lazarus,這個設定在使用第三方套件時尤其有用,例如使用KOL-CE時,就需要重新編譯Lazarus,也需要先設定)
  • 把 Environment 選項中的編譯器設定為您用來重新編譯Lazarus的編譯器執行檔。也請您仔細的確認一下 Environment選項中的 Lazarus Directory 跟 FPC Source directory 這兩個路徑是正確的。請確認系統中只有存在一個 fpc.cfg,fpc.cfg 這個檔案應該要出現在 /etc/ 目錄下 (當您使用Linux 作業系統時),或者跟fpc編譯器在同一個目錄裡面(當您使用Windows作業系統時)。 您可以執行 "fpc -vt bogus" 這個指令,來確認 Free Pascal 編譯器正在使用的fpc.cfg的路徑。

隨便亂放檔案是會造成很多問題的,如果您已經把編譯器更新為較新的版本,新版的編譯器可能還是會在您的Home目錄裡面,或者您用來擺放舊版編譯器的路徑當中找到相關的單元檔,並用舊的單元檔來編譯您的新版編譯器。所以!!! 再更新之前,把這些舊版檔案殺了吧。 當然,刪除前也請您先備份喔,免得更新失敗兩頭落空,那會讓人想罵髒話的。

  • 您可能也會想要目前的專案中使用的 widgetset。例如,在Lazarus的程式碼中所使用的“objectinspector”專案 (就是我們用來看每個元件的屬性、事件的那個視窗),是預設使用GTK的。如果您在Windows系統下,對這個專案進行重新編譯的話,那就一定會出現 "Can't find unit interfaces" 這個錯誤訊息。 此時就需要把widgetset 變更為 Win32版本才能解決這個問題了,方法是: 點選選單上的 Project選項: Project | Compiler Options... | LCL Widget Type (various) 把它改為 default(Win32),即可在 Windows作業系統裡面正確的編譯該專案了。

我想在 Lazarus裡面編譯 Delphi 的專案,可是出錯了,怎麼辦?

錯誤發生在這一行:{$R *.DFM} 我該怎麼解決這問題?

Lazarus (更正確的說法,是 Linux 作業系統) 並不認得資源檔,所以您不能直接把Delphi/Win32 環境裡面的用法直接拿過來用。不過 Lazarus 套用了一個跟這很像的方法,所以只要您依照以下的步驟,就仍然可以使用 Delphi 裡頭對表單的編排設計:

  • 您得先準備好文字模式的 .dfm 檔。(Delphi 5 與之後的版本都把 .dfm 檔預設存為文字模式) 如果您的 .dfm檔是 Delphi 5 以前的版本所建立的,請在Delphi中按下 ALT-F12 把整個表單切換為文字模式顯示,然後您就可以用複製/貼上的方式把文字模式的 .dfm檔保留下來了。準備好文字模式的 .dfm檔之後,請把它複製成 .lfm檔案(複製檔案後變更副檔名即可)。
  • 用 lazres 這個工具產生對應的資源檔( lazres 放在 lazarus/tools 目錄中),指令為: lazres yourform.lrs yourform.lfm
  • 將以下的程式碼加到對應該表單的 Unit裡面,加入到 initialization 程式區段 (如果您的 Unit 本來並沒有 initialization 區段, 請直接將以下的程式碼貼在 Unit 檔的最後,”end.” 這一行之前):
     initialization
     {$I yourform.lrs}

請小心! Lazarus到目前都還沒有保證完全支援Delphi程式放在 dfm 檔裡面的所有元件與屬性喔,所以如果您是直接進行轉換與編譯,執行的時候仍然有可能無法正確運作您的程式。

'Identifier not found LazarusResources' (找不到 LazarusResources 這個識別字)

Lazarus在建立表單的時候,會自動把一些額外的單元檔加入到 uses 的宣告區段,不過在對Delphi的單元進行轉換的時候,這些額外的單元檔並不會被自動補進去,所以您必須在您的表單對應的單元檔的 uses 區段裡面加入 LResources這個單元。 (使用 LResources)

當我想從ObjectInspector 裡面透過雙擊某個元件的事件,來加入事件處理方法的時候,例如雙擊 OnClick事件,Lazarus 告訴我這個錯誤: ERROR unit not found: stdCtrls

請先確認在您的Lazarus裡,Project 選項的 Project -> Project Inspector 畫面中,”Required Packages”是否有包含LCL? 另外,則是您是否已經安裝了 Free Pascal Compiler 的原始程式碼?

Lazarus 只包含了 IDE 和最核心的視覺元件函式庫 LCL,其他的功能,例如輸入輸出控制、資料庫、FCL與RTL都是由Free Pascal 編譯器所提供的,所以IDE會需要這些函式庫原始碼的完整路徑。

FPC 原始碼的路徑可以從這裡設定: Environment -> Environment Options -> Files -> FPC source directory

要怎麼做才能把一個小檔案內嵌在執行檔裡面,而不用分成多個檔案呢? 要如何把資源內嵌呢?

範例:

/your/lazarus/path/tools/lazres sound.lrs sound1.wav sound2.wav ...

上面這個命令,會把sound1.wav 跟 sound2.wav 包裝成 sound.lrs這個資源檔。

然後我們就可以把 lrs 檔進行內嵌了:

...
initialization
{$i unit1.lrs} // 這是主要的資源檔,所以預設會放在第一行
{$i sound.lrs} // 這是我們剛剛建立的聲音檔,當成第二個要內嵌的資源 
end.

然後,在程式裡面,就可以這樣使用資源了:

Sound1AsString:=LazarusResources.Find('sound1').Value;

我要怎麼樣才能看到偵錯模式的輸出值呢?

在 LCL 函式庫裡面,提供了一個名為 LCLProc 的單元,可以把偵錯資料輸出:

  • DebugLn: 這個函式的輸出效果跟 WriteLn一樣,但只能接受字串。
  • DbgOut: 這個函式的輸出效果跟 Write一樣,但只能接受字串。

在一般情形下,輸出值是用stdout來輸出的,如果stdout已經被關閉了,就沒有任何輸出值會顯示出來。(例如應用程式被設定為圖形介面應用程式:{$AppType Gui},或者在Windows系統中以 –WG 為參數進行編譯。

偵錯模式的輸出值也可以被寫入到檔案裡面。LCLProc單元會在程式的initialization區段裡面檢查在命令列裡面是否有debug-log這個參數: '--debug-log=<file>',如果有的話,就會把偵錯資料寫到<file>這個檔案裡面去。

如果命令列裡面沒有 –debug-log 參數的話,則程式會尋找是否有環境變數叫做 xxx_debuglog的,xxx是這個程式執行檔的主檔名。 以Lazarus為例,這個偵錯的環境變數應該要命名為lazarus_debuglog,如果這個環境變數存在,則程式就會使用這個環境變數的值(字串)來當成一個檔案,並把偵錯的輸出值寫進去。 範例: 如果您這樣來設定環境變數:

set lazarus_debuglog=c:\lazarus\debug.txt

偵錯的輸出值就會被寫到c:\lazarus\debug.txt 這個檔案裡面去。

因為這個功能是在 lclproc單元裡面實現的, 所以只要有在 uses 區段引入 lclproc 單元的應用程式就都能使用這個功能。

為 Lazarus 偵錯
大多數偵錯功能都能在視窗上看到: 如果您想在命令字元模式下偵錯的話,請在 lazarus.pp加入 {$APPTYPE console},然後再重新編譯 Lazarus。

Lazarus 用到的各種不同副檔名各有什麼涵義呢?

Lazarus 教學裡的Lazarus檔案 部分用了一個例子來說明這些副檔名的意思。 在這裡擷取幾個作簡單的說明:

*.lpi
Lazarus 專案資訊檔 (以XML格式儲存; 包含該專案的各項設定)
*.lpr
Lazarus 程式專案檔; 包含該專案的Pascal主程式碼
*.lfm
Lazarus 表單檔案; 包含該表單裡面的所有元件與設定(以Lazarus特有的格式儲存; 表單對應的程式碼,則使用同一個主檔名,副檔名則是*.pas)
*.pas*.pp
Pascal程式單元檔案 (如果有對應表單的話,則表單會使用同一個主檔名,表單的副檔名則是*.lfm file)
*.lrs
Lazarus 資源檔 (這是Lazarus產生的資源檔; 不要跟Windows的資源檔搞混喔).
這個檔案也可以透過 lazres 這個工具來產生 (這個程式位於Lazarus/Tools 目錄) 指令為: lazres myfile.lrs myfile.lfm
*.ppu
編譯過的二進位單元檔
*.lpk
Lazarus 套件資訊檔 (以XML格式儲存; 包含該套件專案裡的設定)

我已經修正/改進了Lazarus. 要怎麼把我修改的部分加入到官方的 Lazarus原始碼裡呢 ?

請建立修補程式,並把它寄給Lazarus開發者,詳情請見 建立修補程式.

當我做了這樣的宣告,宣告一個文字檔時: var mytext: text;,出現了這樣的錯誤 "Unit1.pas(32,15) Error: Error in type definition". 我該怎麼修正呢?

TControl 類別包含了一個名為 Text 的屬性。在表單的方法裡,這會有較高的優先性(如果您不理解何謂變數的優先性,請您先閱讀一些關於 Pascal 變數生命週期與優先性的文章),Text這個變數型別是在System這個單元內定義的。您也可以使用TextFile型別,TextFile只是Text型別的別名而已,或者您也可以直接把單元名稱加在宣告的變數型別前,就可以解決這個問題了。 var

  MyTextFile: TextFile;
  MyText: System.Text;

另外一個類似的方法命名衝突,則是在使用AssignFileCloseFile對檔案作開啟或關閉的動作時發生,因為TForm這個類別也有名為assignClose 的方法,所以如果要對檔案作開啟跟關閉的動作時,請您考慮一下,使用AssignFileCloseFile,或者在這兩個函式前加上定義他們的單元名稱”System”: System.Assign 跟 System.Close 這樣就能避免跟 TForm的兩個同名方法產生混淆。


當我使用 Printer.BeginDoc 的時候發生錯誤

首先請確認您在 uses 區段有把Printers 這個單元引入。

另外,您也必須在IDE裡面把Printer4Lazarus 這個套件組加入: Project|Project Inspector|Add|New Requirement|Package Name:

如果 Printer4Lazarus 這個套件組沒有被列在上述的套件清單裡,那麼就得來安裝它了。這個套件組是 Lazarus安裝程式的一部分,您可以在下面這個路徑找到Printer4Lazarus套件組:

[您安裝lazarus 的目錄]\components\printers

如果您安裝時是使用預設的路徑的話,[您安裝lazarus 的目錄]會是:

  • Windows作業系統: c:\lazarus
  • Linux作業系統: /usr/lib/lazarus

如果您引入了 “Printer.Printers” 而發生了例外事件,也可以使用上述的方法來解決。

為什麼 TForm.ClientWidth/ClientHeight 這兩個屬性會跟 TForm.Width/Height 一模一樣呢?

TForm.Width/Height 這兩個屬性不包含框架,因為在任何作業系統上面,都無法得知框架的大小。就因為沒有可靠的方法可以取得框架的大小,LCL目前只能讓表單在螢幕上面移動,或改變表單的大小。

最後,當總算有可靠的方法可以在所有作業系統上面,取得視窗上面框架的大小時,這個問題就會被修正了。為了要保持跟舊版的LCL表單相容,所以會加入版本號碼跟一些額外的方法。

這些東西是在哪裡定義的呢?

虛擬的鍵盤按鍵常數

鍵盤按鍵的常數值是定義在 LCLType這個單元裡的,請記得在您的單元檔中的uses區段把 LCLType 引入.

使用 Lazarus IDE

我要如何使用”自動完成”的功能呢? (跟Delphi裡面按下 “.”的動作一樣,會出現下拉式選單,讓我們可以直接選擇方法或屬性,不用全部輸入完畢)

您可以按下[ctrl][space]來觸發自動完成的功能。(顯然跟Delphi在中文系統上是一樣的,因為 [ctrl][space]已經是系統切換中英文輸入法的熱鍵了) 在Environment選項裡面,您可以從 Environment -> Editor Options -> Code Tools -> Automatic Features 來設定自動完成的功能要多快出現。


Linux

我在Linux上面要如何不透過 IDE來進行偵錯?

首先,您需要一個偵錯程式。GNU的偵錯程式 gdb是Linux作業系統中標準的偵錯程式,而且有幾種可以搭配的圖形介面可以選用。其中一個很常見的偵錯工具是 ddd,大多數的 Linux當中應該都有包含它。要編譯包含偵錯資訊的 Lazarus/LCL,您應該使用下列的指令來進行偵錯的程序:

 $ make clean; make OPT=-dDEBUG
 $ ddd lazarus

不過在這裡要先警告大家一下,ddd跟很多程式是不相容的,例如它跟Lazarus的偵錯器就不相容。特別是在它要進去檢視某個變數的值的時候,由於ddd/gdb是有分大小寫的,而Pascal是不分大小寫的,所以這時候就會有問題。 因此,在這種狀況下,如果您還要用ddd或gdb來做偵錯,那您就得在偵錯程式裡面把所有變數都使用大寫,這樣看任何一個變數的值都不會有問題了。如果您需要關於偵錯程式更詳細的資訊,請參閱fpc使用手冊。

我已經可以偵錯了,但ddd找不到我的程式原始碼,或提示我的程式沒有原始碼? 為甚麼會這樣呢?

這個問題是跟gdb/ddd路徑相關的,您可以透過以下方法來避免:

  • 透過ddd程式目錄選項裡面的 "Change directory" 功能,定義在ddd程式啟動時要匯入的程式路徑。換句話說,當您透過ddd進行偵錯的時候,原始碼的檔案就不能被其他的程式使用(例如原始碼檔案就不能被 Lazarus開啟),所以甚至可能要修改很多次載入目錄的設定。
  • 請在ddd 的畫面中,選擇 [Edit] [gdb-settings] 來設定搜尋路徑。
  • 請建立 $(HOME)/.gdbinit 這個檔案,內容像是:
     directory /your/path/to/lazarus
     directory /your/path/to/lazarus/lcl
     directory /your/path/to/lazarus/lcl/include

在程式進行連結的時候,發生了這個錯誤: /usr/bin/ld can't find -l<some lib>

導因於少了某些套件應有的函式庫
您需要安裝有提供lib<somelib>.so 或 lib<somelib>.a檔案的 Linux 函式庫套件。在Liunx作業系統中,動態連結函式庫的副檔名是 .so,而靜態連結函式庫的副檔名則是 .a。當您使用某些Linux的安裝光碟或是安裝光碟Image時,要安裝套件可能是透過RPM或DEB這兩種套件組管理程式來安裝不同的函式庫,雖然您已經安裝了正常函式庫,但還得裝上該函式庫的開發版本,例如您已經安裝了 libpacp.so,但還要再安裝 libpacp-dev.so才能使 Lazarus 正常運作。開發版本的函式庫在名稱上會比一般版本的函式庫多”-dev”這幾個字,您可以很容易的在 RPM 或是 DEB的套件管理程式裡面找到的。
導因於程式原始碼找不到,或是手動編譯時的設定錯誤 (LFS)
請先檢查一下錯誤訊息,看看ld錯誤訊息回報中找不到的 lib<函式庫名稱>.a 所在的路徑,是否有包含在您的環境變數 Path 裡面。如果該檔案存在,路徑也正確的話,就請檢查一下檔案的版本是否為Lazarus系統所要求的正確版本? 如果版本正確,而只是檔名不對的話,為了讓連結程式能夠找到動態連結函式庫,您可以建立一個連結(symlink),讓lib<some lib>.so 能連結到 lib<some lib><version>-x,y.so,把版本號碼加到新的連結作為主檔名的一部分,通常這樣就能解決問題。如果這樣做了以後變成找不到靜態連結函式庫,那就還要把靜態連結函式庫也做個連結: lib<some lib>.a 連結到 lib<some lib><version>-x,y.a。(這個連結的建立,可以透過Linux 的 ln 指令來完成)
FreeBSD
先確定上述的情形已經不存在,並且確定在您的 fpc.cfg 設定檔裡面也包含了 -Fl/usr/local/lib 這行設定 (把 /usr/local/lib 包含到尋找函式庫的路徑中) 與 Lazarus 的函式庫路徑。請注意,在FreeBSD裡面,GTK1.2套件的名稱會是gtk12,glib也一樣,所以套件的正確安裝與否也要確認一下。同時,更新版的FreeBSD也有些是把GTK1.2套件的名稱命名為gtk-12,而glib則命名為glib-12,因為FPC會要求這幾個套件存在,所以要請您注意一下這些套件的正確性,如果需要的話,用連結的方式把這些套件的連結鍵立起來。
[]# cd /usr/local/lib && ln -s libglib-12.so libglib12.so
[]# cd /usr/X11R6/lib && ln -s libgtk-12.so libgtk12.so
[]# cd /usr/X11R6/lib && ln -s libgdk-12.so libgdk12.so
NetBSD
同樣要請您確認上述第二項,並且確認在fpc.cfg裡面是否正確的包含了 -Fl/usr/pkg/lib 這行設定跟 Lazarus的函式路徑。

怎樣才能讓我用 kylix 2 製作的專案轉換為 lazarus 的專案呢?

要把 Kylix的專案轉換為 Lazarus的專案,方法跟把Delphi專案轉換過來幾乎一樣。

LCL (Lazarus 元件庫) 在設計時已經盡量要做到與Delphi的VCL (視覺元件庫)相容了。 Kylix 的CLX 則是可以和 QT 相容。 以下是一些有用的提示:

  • 先把Kylix裡面使用的CLX以Q開頭的單元檔宣告,像是 QForms, QControls, QGraphics, ... 改成在VCL裡面對應的單元檔宣告: Forms, Controls, Graphics, ...
  • 在每個單元檔的uses區段裡加入使用LResources 的宣告。
  • 把所有表單的 .xfm 檔案改名或複製為 .lfm。
  • 把專案檔 .dpr 更名或複製為 .lpr。
  • 在lpr專案檔裡面的uses區段加入使用 "Interfaces" 這個單元的宣告。
  • 移除掉原來使用資源檔的 {$R *.res} 宣告
  • 移除掉原來使用表單檔的 {$R *.xfm} 宣告
  • 在每個 .pas檔跟 .lpr檔裡面加入 {$mode objfpc}{$H+} 或{$mode delphi}{$H+} 的宣告,讓Lazarus能知道要用object pascal相容語法還是Delphi相容語法。
  • 在每個表單的單元檔的結尾加入initialization區段,把lrs檔 (Lazarus的資源檔)引入:
 initialization
   {$I unit1.lrs}
要建立 .lrs 資源檔,可以使用 lazres 這個工具來轉換原來的資源檔,lazres可以在這個目錄中找到: (lazarusdir)/tools/lazres.
例如要把lfm表單檔中的資源轉換為 lrs資源檔: ./lazres unit1.lrs unit1.lfm
  • 把LCL還不支援的部分修正。因為LCL還沒有支援VCL跟CLX元件的每個屬性,所以我們得花些人工,自己把不完全相容的部分找出來,將之修正。

在編譯 Lazarus的時候,編譯器回報找不到單元檔的錯誤,例如: gtkint.pp(17,16) Fatal: Can't find unit GLIB

1. 先把編譯結果全部清除: 'make clean all'

2. 檢查編譯器的版本是否正確 (FPC 必須是2.0.4 以後的版本才行)

3. 檢查一下編譯器是否使用了正確的編譯器設定檔? 一般正常安裝的話,會是使用 /etc/fpc.cfg這個設定檔,但是 fpc 也會搜尋 ~/.ppc386.cfg, ~/.fpc.cfg,或是/etc/ppc386.cfg 而且,只會套用第一個被找到的設定檔,所以請按照本網頁前面的提示,在系統裡面只留下一個設定檔,其餘的都移除掉吧。

提示: 想知道編譯器到底用了哪個設定檔嗎? 請執行這個指令: 'ppc386 -vt bogus'
並且把您不會用到的其他所有的 ppc386.cfg 都刪掉吧。

4. 檢查您的設定檔 (/etc/fpc.cfg) 裡面是否包含了fpc函式庫的正確路徑,至少應該包含下列三行:

   -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget
   -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/rtl
   -Fu/usr/lib/fpc/$fpcversion/units/$fpctarget/*
這幾個路徑裡面的第一部分 (/usr/lib/fpc) 要根據您的系統而定,主要是看您把系統函式庫放在哪個路徑裡。部分的系統可能是把系統函式庫放在這個路徑裡面:/usr/local/lib/fpc/... .
提示: 您可以透過 'ppc386 -vt bogus' 這個指令來列出搜尋函式庫的路徑。

5. 請檢查您的設定檔 (/etc/fpc.cfg),裡頭或許是沒把這幾個 lcl 的原始碼檔案的路徑所在 (.pp, .pas)包含進去:

 forbidden: -Fu(lazarus_source_directory)/lcl
 forbidden: -Fu(lazarus_source_directory)/lcl/interfaces/gtk
如果您要手動把 lcl 加入您所有的 fpc 專案裡,請確定以下這兩個路徑要放在上述那兩個路徑之後:
 -Fu(lazarus_source_directory)/lcl/units/$fpctarget
 -Fu(lazarus_source_directory)/lcl/units/$fpctarget/gtk

6. 確認找不到的單元檔 (glib.ppu) 是否存在您 fpc 函式庫的目錄中。舉例來說,在系統的 /usr/lib/fpc/$fpcversion/units/i386-linux/gtk/ 目錄中找不到 gtk.ppu,而如果這個檔案找不到的話,fpc函式庫就會出問題,您也應該重新安裝它。

7. 檢查一下這些原始碼是否放在 NFS 網路檔案系統的目錄中。某些情形下,NFS網路檔案系統在更新檔案的時候會發生錯誤的,所以請您務必把放在 NFS網路檔案系統裡面的原始碼檔案搬到一般檔案系統裡去,然後再進行編譯。

8. 如果還是無法成功編譯,請試著使用 samplecfg 這個腳本程式,指令如下:

# cd /usr/lib/fpc/version/

# sudo ./samplecfg /usr/lib/fpc/\$version /etc

請記得! 在上面列出的第二個指令裡, /etc 後面不要再加上目錄符號 “/”,不然的話,檔案的路徑會變成這樣: /etc/fpc.cfg/fpc.cfg。事實上,我們是希望 samplecfg建立 /etc/fpc.cfg,而不是建立 /etc/fpc.cfg/fpc.cfg 喔。

我已經安裝了二進位安裝版本,但是在編譯簡單的專案時,Lazarus跑出這個錯誤訊息: Fatal: Can't find unit CONTROLS

可能是因為您使用了新的二進位格式的 fpc 套件,而這些新的 fpc 套件就被用來編譯Lazarus 的執行檔。如果您是這個情形的話,建議您把 fpc 跟 Lazarus 的原始碼下載回來,都用手動編譯的方式在您的系統上面重新編譯,您可以在這裡透過 svn 取得原始碼的最新狀態版本:

 $ bash
 $ svn checkout http://svn.freepascal.org/svn/lazarus/trunk lazarus
 $ cd lazarus
 $ make clean all

並確認 Lazarus 裡的原始碼目錄已經是正確的指到您下載的原始碼的路徑: Environment->General Options->Files->Lazarus Directory Top

Lazarus 編譯部分成功了,但連結的部分出現這個錯誤訊息: libgdk-pixbuf not found

請您安裝 gtk1.x版的 gdk-pixbuf 函式庫或不要使用它:

您可以在這裡照到 gdk-pixbuf 函式庫:

RPMs: http://rpmfind.net/linux/rpm2html/search.php?query=gdk-pixbuf&submit=Search+...&system=&arch=

Debian 格式的函式庫套件: libgdk-pixbuf-dev

函式庫原始碼: ftp://ftp.gnome.org/pub/gnome/unstable/sources/gdk-pixbuf/


要如何不使用這個函式庫呢: 從Lazarus的目錄選項裡來設定: Tools->Configure "Build Lazarus" 加入這個選項 '-dNoGdkPixBufLib' 或者在命令列裡面下這個指令: "make clean all OPT=-dNoGdkPixBufLib".

我使用的是 SuSE,在我的系統上出現這個錯誤訊息 /usr/bin/ld: cannot find -lgtk Error: Error while linking

SuSE 把 gtk devel 函式庫安裝在 /opt/gnome/lib 這個目錄裡 (如果是 64位元版的 SuSE 則是安裝在 /opt/gnome/lib64 目錄), 而這個目錄不在標準的函式庫路徑裡面,所以請把它加入到 fpc.cfg 設定檔中: (-Fl/opt/gnome/lib).

我裝了一個元件以後,執行了Lazarus 卻發生執行錯誤,還回報給我這個錯誤訊息: runtime error 211

我裝完元件以後,Lazarus 執行發生錯誤,還給我這些錯誤訊息:

Threading has been used before cthreads was initialized.
Make cthreads one of the first units in your uses clause.
Runtime error 211 at $0066E188

這要怎麼修正呢?

您新裝的元件使用了多執行緒。在Unix/Linux系列作業系統上面,FPC不會自動支援多執行緒的,所以我們得自己進行初始化。這個初始動作是在 cthreads這個單元檔裡面完成的。所以每個要使用多執行緒功能的應用程式都得在主程式的 uses 區段裡面加入使用 cthreads 的宣告。Lazarus本身是不會出現問題的,您可以透過以下兩個方式來完成加入宣告的動作:

1) 先修正 ide/lazarus.pp 這個原始碼檔案: 把 cthreads 加入該檔案的 uses 區段,看起來會像這樣:

uses
  //cmem,
  cthreads, 
  {$IFDEF IDE_MEM_CHECK}
...

然後重新編譯 Lazarus。

2) 如果您要避免修改 lazarus.pp 原始碼,您就必須在 fpc 編譯器執行時加上一個參數。等使用多執行緒的套件編譯完成,請點選Lazarus的選項 Tools->Configure "build Lazarus"。則設定 "build Lazarus" 的對話框就會出現,在"Options:" 這個欄位裡輸入-Facthreads,按下OK按鍵,然後再安裝新的套件。因為安裝新套件的時候會重新編譯 Lazarus,而重新編譯的時候就會套用-Facthreads這個選項,這個選項的效果,就會跟在主程式的原始碼裡頭加入使用 cthreads 的效果一樣。

提示: 或許您的舊版 lazarus 執行檔(不會出現執行錯誤的版本) 可能會被保留在同一個目錄中,被命名為 lazarus.old 喔。

當我執行具備多執行緒功能的程式時,出現 runtime error 232 這個錯誤

編譯時的錯誤訊息是:

This binary has no thread support compiled in.
Recompile the application with a thread-driver in the program uses
clause before other units using thread.
Runtime error 232

解決方法: 把cthreads 加入到您的專案檔案主檔案的原始碼 uses 區段裡面,就是 .lpr 檔案。

我使用的是 Ubuntu Breezy,在Lazarus的IDE裡面,字體看起來太大了,怎麼辦?

如果 Lazarus 是使用 Gtk 1.2 編譯的,您只要在 Gnome Preferences/Font 裡頭設定字型大小即可,不用多做甚麼動作 您也可以試著用這個方法來試著解決看看: 在您的 home 目錄裡面建立一個名為 .gtkrc.mine 的檔案,然後把以下這幾行加到這個檔案裡面:

style "default-text" {
       fontset = "-*-arial-medium-r-normal--*-100-*-*-*-*-iso8859-1,\
                  -*-helvetica-medium-r-normal--*-100-*-*-*-*-*-*"
}

class "GtkWidget" style "default-text"

我的 gtk程式要怎樣才能使用自訂的 rc 設定檔?

選項一) 把rc檔的檔名命名為 您程式的主檔名.gtkrc 然後把這個 rc 檔跟您的執行檔放在同一個目錄裡面。

選項二) 在您的程式碼裡加入使用 GtkInt 這個單元檔的宣告,並且呼叫 GTKWidgetSet.SetRCFilename('您要使用的 rc 檔檔名'); 最好在專案的 .lpr 檔案原始碼裡面 “Application.Initialize” 這個動作前面加入{$IFDEF LCLGtk}這行宣告。

我的作業系統是Ubuntu,使用Gtk2套件進行編譯卻失敗了,發生了因為找不到函式庫的錯誤

Ubuntu 系統裡面有個錯誤,會因為沒有建立函式庫的連結檔(symbolic links)而找不到該函式庫,就算您已經安裝了該函式庫也一樣,所以您得手動建立這些連結。首先,請您確定編譯時回報找不到的函式庫您的確已經裝在系統裡面了,接著,再幫這些函式庫的檔案建立連結,舉個例子,您要為 libgdk-x11-2.0.so.0這個檔案建立一個連結,好讓系統能找到 libgtk-x11-2.0.so:

cd /usr/lib
sudo ln -s libgdk-x11-2.0.so.0 libgtk-x11-2.0.so

請確定 [回報找不到的函式庫].so 這個連結已經建立,並且指向到正確的函式庫檔案裡面了。

我要怎麼編譯程式給 Gtk2 用呢?

截至目前,用Gtk2 開發函式庫建立出來的IDE還不太穩定,但您如果只是想編譯程式給 Gtk2環境使用,不牽涉到IDE 的話,您可以使用 Gtk1 編譯出來的 IDE 來做。

要使用Gtk2重新編譯過的 LCL搭配Lazarus 進行啟動,您可以從Lazarus的選項來做: "Tools"->"Configure Build Lazarus",然後設定 LCL 為 clean+build,其他選項都不需要點選(其他選項設定為 X 記號就行了)。

按下 OK按鍵,把設定視窗關掉,然後再從 Lazarus 的選項中選擇 "Tools"->"Build Lazarus" 就可以把 LCL 套件作重新編譯了。

編譯完畢以後,您就可以編譯在Gtk2 環境裡面使用的程式了,當然,您還得先把編譯器選項裡的 widgetset 設定為 Gtk2: “Project” -> “Compiler Options” -> “Path” 分頁的最下方,用下拉式選單把 LCL Widget Type (various) 設定為 gtk2 以後,按OK即可。

Lazarus回報了這個訊息: "[WARNING] ** Multibyte character encodings (like UTF8) are not supported at the moment."

從10535 (0.9.21) 版本以後,這個訊息就沒再使用過了。 在那之前的版本,這個訊息是用來警告使用者使用了 UTF-8 字元編碼的。在 gtk1 視窗元件用來處理按鍵的內部程式碼無法處理這種編碼的按鍵訊息,因而在舊版本中,按鍵事件發生時(OnKeyPressed)會發生處理錯誤的狀況,例如無法刪除或顯示正確的字元。

(舊版的 Lazarus文件中原本是這麼寫的)
這個訊息是用來指出您的系統編碼被設定為 UFT-8了。如果您使用了 Gtk1,則這個情形會讓Lazarus或使用Lazarus開發的程式在使用的時候發生不少問題。

要修正這個問題,就請您在執行程式前,從命令列視窗把系統編碼改為 UTF-8 以外的編碼:

export LC_CTYPE="pt_BR"
export LANG="pt_BR"
export LANGUAGE="pt_BR"
./lazarus

請將上面這段程式碼中的 pt_BR 改為您的國碼,您也可以把這段程式寫成一個Shell腳本程式,以後就可以很方便的做這個修正了。

Windows 作業系統

當我執行編譯器的時候,出現了這個錯誤訊息:The name specified is not recognized as an internal or external command, operable program or batch file.>& 在這個時候是不應該出現的.

如果在編譯器的目錄中存在一個名為 make.cmd 的 OS2作業系統用的腳本程式,Windows NT 也會把它當作可以用的腳本程式,所以請把這個程式刪除,因為在Windows NT作業系統中,我們不會用到它。

當我執行編譯器的時候,出現了這個錯誤訊息: make[3]: ./ppc1.exe: Command not found

這個問題發生的原因目前還不清楚,但有時候 make 程式會搞不清楚自己所在的路徑,請試著在進行 make 的時候,加上您編譯器的路徑: “make cycle BASEDIR=您的FPC原始碼所在的路徑” (假設您要 make 的專案名稱是cycle)

當我在編譯 Lazarus 的時候,出現這樣的錯誤訊息:

make.exe: * * * interfaces: No such file or directory (ENOENT). Stop.make.exe: * * * [interfaces_all] Error 2

您需要更新您的 make 程式了。

makefile:27: *** You need the GNU utils package to use this Makefile. Stop.

請確認您安裝 FPC 的完整路徑中,所有目錄的名稱都沒有包含空格,Makefile不支援路徑中包含空格的狀況。


我要怎麼做才能讓我的程式看起來像 XP 的程式外觀,就像 Lazarus看起來的樣子?

如果您有個程式叫做 myprogram.exe,則請您先新增一個文字檔案叫做myprogram.exe.manifest,然後把以下這整段複製到新增的檔案裡頭:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity processorArchitecture="*" version="1.0.0.0" type="win32" name="myprogram"/>
<description>programom</description>
<dependency>
  <dependentAssembly>
   <assemblyIdentity
     type="win32"
     name="Microsoft.Windows.Common-Controls"
     version="6.0.0.0"
     publicKeyToken="6595b64144ccf1df"
     language="*"
     processorArchitecture="*" />
  </dependentAssembly>
  </dependency>
</assembly>

好啦,看起來像XP的程式了吧。

當我執行用Lazarus建立的程式時,為什麼還多跑出一個 DOS 視窗呢?

請在編譯該程式的時候,在編譯的命令裡面加上 –WG 這個參數 (表示這個程式是 Windows 圖形介面程式),或者在Lazarus的IDE裡面,找到Compiler Option,確定 “Windows GUI”這個項目有被勾選了 (Project menu -> Compiler Options -> Linking -> target OS Specific options)

Mac OS X

為什麼我在編譯一個專案的時候,出現了這個錯誤訊息呢: 'unknown section attribute: no_dead_strip'?

“Dead code stripping”這個選項在 Max OS X 10.4.0 以前的assembler跟linker程式都不支援,所以請您在Compiler options裡面把它移除:

  • Code > Unit style > Smart linkable (-CX)
  • and Linking > Link Style > Link smart (-XX)

授權

我可以用 Lazarus 來製作商業程式嗎?

當然可以,LCL 的授權是以LGPL 為基礎,但多包含了一個排除條款,這個排除條款是允許您可以把二進位檔直接發佈,而不強制規定您非把原始程式碼一起發佈不可。(LGPL的授權是您一定得把原始碼跟執行檔一起發佈才行的) 但如果您對LCL做了加強或修正,您就必須連同原始碼一起散佈,因為Lazarus的IDE授權是以 GPL為基礎的。

換句話說,用Lazarus作的程式,您可以像一般商業程式一樣,只發佈執行檔與二進位格式的函式庫,不用強制分享原始碼。但如果您改了LCL或Lazarus,則LCL跟Lazarus的修正部分必須要強制跟大家分享。

Why are some components restricted from usage in commercial application ?

Lazarus comes with additional components, that were developed by third parties. Those are under various other Licenses. If you wish to use them you need to see the License within the source files of those packages. Most of those 3rd party components are in the directory "components".

How do I know if a Component is part of the LCL ?

All LCL units are in the directory "lcl". A List of units belonging to the LCL can be found here http://lazarus-ccr.sourceforge.net/docs/lcl/ . If you code uses units not listed on this page, you may have used a component that is not part of the LCL.

我可以為Lazarus做商業化的外掛程式嗎?

當然可以。Lazarus的IDE加強介面 “IDEIntf” 授權也是以LGPL為基礎,並且跟LCL的排除條款相同,所以透過這個介面來加強 Lazarus的共享資料結構並不強制要求您製作的外掛程式或 design-time套件要符合 GPL 授權。

因此您可以自由的選擇您製作出來的外掛程式要怎麼進行授權,我們並不希望限制您的選擇。因此就算是採用不與 GPL 相容的商業授權,也是被允許的。但是請注意,這並不表示您可以把編譯好的Lazarus搭配您的外掛程式一起販售,因為我們並不樂見 Lazarus 的 IDE服務受到侷限,畢竟要重新編譯 Lazarus 是很簡單的。

建立這個網頁的人與附註

這個網頁是從維基百科的原始版本轉換過來的。 初版正體中文翻譯 - 由元智大學 資訊傳播學系兼任講師張子仁 (Dennies Chang)製作 User:Dennies