高見知英の技術ログ

技術関係のログをQiitaから移行してきました。プログラミングのほか、使っているアプリの細かい仕様についてなど書いていきます。

Lazarusプロジェクトのビルドをコマンドラインで行なう

このブログはLazarus(FreePascal)アドベントカレンダー14日目の記事です。

qiita.com

たとえばリリースパッケージを作りたいときなど、Lazarusのコンパイル以外にも複数の処理を行ないたいのでIDE以外からコンパイル操作を行いたい ということはときどきあります。

そのようなときに、Lazarusのビルド処理だけを行なうツールとして、Lazarusにはlazbuildというツールが存在します。

Lazbuildの在処と使い方

このツールは、Lazarusをインストールしたディレクトリにあります。

このツールに、Lazarusのプロジェクトファイル(*.lpi)を指定すると、コンパイル処理が走って、ファイルで定義した場所に実行ファイルが出力されます。

このパスをヒント無しで探したい場合…。レジストリのインストール時情報にパスに書き込まれているので、そこから読み取るくらいでしょうか・・・*1

LazBuildでいつもと違う構築モードのコンパイルを行なう

このlazbuildには、--build-modeというオプションがあり、これを指定すれば、構築モードを切り替えてのコンパイルも可能。

たとえば普段のコンパイルでは構築モード「Debug」を使っているが、このときは「Release」を使いたい という場合はlazbuild .\application.lpi --build-mode=Releaseなどというコードを書いておけばOKです。

なお、この処理を行なうと*.lpsファイルが書き換えられてアクティブな構築モードが「Release」に変わってしまうので、それが気になる場合は、--no-write-projectオプションを加えます。

ビルドスクリプトを書く

また、同梱物がほかにもある場合は、コンパイル用のスクリプトを作っておくと良いです。

ZIPファイルにまとめる場合など、PowerShellを使っても良いですが、Pythonあたりで作って置くとバンバン呼び出せて良いですね。

lpiファイルはXMLファイルなので、Pythonからいじりたい場合はxml.etree.ElementTreeあたりを使うとよいでしょう。

ただし、xml.etree.ElementTree#writeで作成できるXMLはLazarusが出力するlpiファイルとは若干書式が異なるのでご注意ください*2

github.com

*1:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\lazarus_is1\InstallLocation

*2:わたしはXMLファイルを作成したあと、ファイルを読み込んで直接編集しました

ClipboardMonitor作りました

このブログはLazarus(FreePascal)アドベントカレンダー13日目の記事です。

qiita.com

13日目はそもそもLazarusを触るきっかけにもなったアプリ、ClipboardMonitorについて。

github.com

このアプリは、クリップボードを常に監視し、テキストがコピーされたらその文字数やURLの指し示すページのタイトルなどを表示するツールです。

クリップボード内の内容を確認する処理はPythonスクリプトで実装されているので、自分で追加することで自由に処理を追加することもできます。

f:id:TakamiChie:20211212161756p:plain
動作風景

また、変換スクリプトメニューからテキストを変換するスクリプトを呼び出すことも可能です。

こちらもPythonスクリプトなので、好きな処理を追加することができます。

f:id:TakamiChie:20211212162731p:plain
変換スクリプト

個人的にはクリップボードの履歴や引用記号をつけるなどのテキスト処理はClipboard Historyというツールを使っているのでちょっと少なめですが、ぼちぼち増やしていこうかなーと。

作成動機

作成動機はなにより、とくにクリップボード履歴ツールなどを使っていると「今クリップボードに何がコピーされているのか」が分かりづらいから。

とくにClipboard Historyにはスタッククリップボードという機能があり、これを使っていると特に「今何がクリップボードにコピーされているのか」は分かりづらい。

とくに配信中など、「今クリップボードに入っているテキストを配信画面に出して良いか」が分かりづらいのが個人的に悩みでした。

そのために作成したのがこのツールです。

Lazarusを使った理由

Lazarusを使った理由については、以前にもちょっと触れましたが、GUIがデザイナーで作れて、コンパイルができ(そこそこに早く起動でき)て、開発環境もそこそこに軽く使いやすいこと。

GUIがデザイナーで作れると言えばVisual Studioもありますが、開発環境が十数GBと重いのもあるし、久しぶりに触ったとき開発環境のアップデートなどで時間を食い潰されるのがいやだったので選びませんでした。たぶん今後そんなに頻繁には触れないということを考えると、その度にアップデート というのはしんどいですし。

まあ、Delphiっぽい環境に懐かしさを感じて というのもあるにはありますが。

今後の予定

今後は、まだまだ機能的に足りないなと思う部分もありますし、改善したいところものこっているので、それらの修正や、スクリプトの追加は行ないたいと思っています。ただ、しばらく忙しいのもありそんなに積極的には弄れないかも。

もともとクリップボードまわりのアプリは使い勝手が良く便利には使っていたのですが、アプリが途中で開発停止になってしまうことが多く、そんなときでも最低限他の人が関われるようにと思ってオープンソースにしています。なので、もしできる人がいれば、プルリクエストなどなんらかの形で関わっていただけると嬉しいなあ と。

いちおうリリースにはベータをつけていますが、ベータがとれるところまでは少なくとも開発を進めたいですねー。

github.com

PascalPad作ってみた

このブログはLazarus(FreePascal)アドベントカレンダー12日目の記事です。

qiita.com

ちょこっとしたプログラムの動作検証を行なうときにいちいちコードを書き込める場所を探すのが面倒なので、PascalPadというツールを作ってみました。

github.com

とりあえず機能的にはとりあえず使える段階なので、リリースを作っています。Windowsの実行バイナリも添付しておりますので良ければどうぞ。

github.com

Pascal Script

Lazarusには、初期状態でPascal Scriptというコンポーネントがインストールされています。Inno Setupの内部で使われているらしい*1

wiki.lazarus.freepascal.org

これを使うとPascalコードを読み込んでそのまま実行 なんてことが可能です。Script といいつつCompileメソッドを使ってコンパイルを行なったあと、Executeメソッドで実行できる というものですが、別に両方のメソッドを一つのメソッド内で呼び出せばスクリプト言語のような感覚で利用が可能です。

また、プラグインを追加して内部で使える関数を増やしたり、OnCompileイベントでTPSScript.AddMethodメソッドやTPSScript.AddFunctionメソッドで関数を追加するなど、結構使い道はありそうです。

まあ多種多様なプログラム言語に気軽に触れられるようになった今、なぜわざわざPascalをユーザーに使わせるのか という問題もありますが、たとえばプログラムの内部処理をPascalで補うとか、ゲームなどの細かい挙動をスクリプトで制御するとか、使い道はありそう。

*1:そういえばPascalスクリプトと言えばPPAなんてものもあったな・・・ 今はどうなっているのだろう?

Lazarusで拡張メソッド?

このブログはLazarus(FreePascal)アドベントカレンダー11日目の記事です。

qiita.com

Lazarusには(というかPascalには)、他の言語でいう拡張メソッド的な書き方を実現する仕組みがあります。

それがヘルパークラスです。

wiki.freepascal.org

えっ、そんな機能昔使ってたDelphiにはなかった・・・!と思ってたらDelphiにも(編集履歴を見る限り2015年には?)ある機能みたい。

docwiki.embarcadero.com

このあたりでとても気軽に使えるのが、TStringHelper。

www.freepascal.org

最近の言語であれば比較的自然な、文字列リテラルのあとに.を書いてメソッドを呼び出す なんてことが可能になります。

'%sのバージョン情報'.Format([Application.ExeName]);

みたいな感じで。

いくつか自分のところで使っている感じとしては、シチュエーションにもよりますがとても書きやすいので、どんどん活用していきましょう。

LazarusのGUIデザイナーでコンポーネントをコピーすると…

このブログはLazarus(FreePascal)アドベントカレンダー10日目の記事です。

qiita.com

今日は小ネタ・・・ですが、意外と重要な小ネタ。

LazarusでGUIデザイナー上よりコンポーネントをコピーしようとすると、lfmファイルに書き込まれているのとおなじテキスト形式で、GUIコンポーネントの情報がクリップボードに書き込まれます。

object FMonitor: TMemo
  Left = 0
  Height = 97
  Top = 0
  Width = 320
  Align = alTop
  Anchors = [akTop, akLeft, akRight, akBottom]
  BorderStyle = bsNone
  Color = clBtnFace
  Lines.Strings = (
    'FMonitor'
  )
  PopupMenu = FPopupMenu
  ReadOnly = True
  TabOrder = 0
end

なお、デフォルト値のまま変更していない値は表示されません。

プロジェクトインスペクタ上だと案外プロパティの状態が一覧しづらく、うっかり重要な情報を見落としてしまう ということが多々あります。

そんなときにとりあえずクリップボードコンポーネントをコピーしてみると、案外見落としていた問題に気付く なんてことがあるかもしれません。

Lazarusアプリのバージョン情報を取得する

このブログはLazarus(FreePascal)アドベントカレンダー9日目の記事です。

qiita.com

Delphiでアプリケーションのバージョン情報を取得するには、FileInfoユニットにあるTVersionInfoクラスを用います。

procedure TAboutDialog.FormCreate(Sender: TObject);
var
  VersionInfo: TVersionInfo;
begin
  VersionInfo := TVersionInfo.Create;
  try
    VersionInfo.Load(HINSTANCE);
    Self.VersionString.Caption:=Format('Version %d.%d.%d.%d', 
      [VersionInfo.FixedInfo.FileVersion[0],
        VersionInfo.FixedInfo.FileVersion[1],
        VersionInfo.FixedInfo.FileVersion[2],
        VersionInfo.FixedInfo.FileVersion[3]]);
  finally
    VersionInfo.Free;
  end;
end;

もちろん事前にプロジェクトのオプションより、バージョン番号を設定しておく必要があります。

f:id:TakamiChie:20211206101714p:plain
プロジェクトのオプション

TVersionInfo.VersionInfo.FixedInfo.FileVersionプロパティにバージョン番号が入っています。配列の要素は頭からメジャーバージョン、マイナーバージョン、リビジョン、ビルド番号となっています。

Lazarusにはコンパイルの度にビルド番号をインクリメントするというオプションがあります。これをチェックしておくと実行メニューの構築を実行したときに1インクリメントされます(コンパイルや実行ではダメなようです)。

個人的にはMicrosoft風に日付に関連する値にしてみたいところですが、このへんはツールを作るなりなんなりして対応するしかなさそうですね。

Lazarusのfor文

このブログはLazarus(FreePascal)アドベントカレンダー8日目の記事です。

qiita.com

8日目はアッサリ目にfor文の話し。

Lazarusでのfor文はfor [カウンタ] := [開始値] to [終了値] do ...です。他の言語のように増分を指定するStep値の指定はできません。常に開始値~終了値まで1ずつカウントがインクリメントされていきます。

ただし、-1は可能です。for [カウンタ] := [開始値] downto [終了値] do ...という構文となります。

wiki.freepascal.org

あれDelphiってこんな仕様だっけ・・・ と思ったら、Delphiもそんな仕様だった。

ただし、最近のPascalにはちゃんとfor each文的な構文も用意されています。for [カウンタ変数] in [配列等イテレータブルなオブジェクト] do文です。これを使えば配列を走査したりStep値を設定したfor文のようなことも可能ではあります。

なお、Lazarusは変数の宣言が必須な言語ですし、他の言語と違って変数宣言部と実装部が分離された言語なので、カウンタ変数の宣言はメソッドの先頭で行なう必要があります。ちょっとややこしいですがそこがPascalなので慣れるしかない。

procedure Method;
var
  i: Integer;
begin
  for i := 0 to 5 do ...
end;

という感じになります。