C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

memo: install ChiliProject 3.3 to openSUSE-12.2

ChiliProject公式の以下にopenSUSE-11.3へのインストールがまとめられているが、これはやらない。

最新安定版をbundle使って入れましょう。以下の後半を参考に。

システムに必要なものを入れておく。

zypper in gcc ruby ruby-devel libxml2-devel libxslt-devel libmysqld-devel postgresql-devel ImageMagick-devel
 ...

その他必要なruby周りはbundleに任せる。この時、特にネイティブコードの開発用パッケージに不足があるとbundleが止まるので、もし何か出たらエラーを良く読んで必要なライブラリーをzypperで入れるなどすれば良い。

git clone -b stable git://github.com/chiliproject/chiliproject.git
cd chiliproject
git checkout v3.3.0

nokogiri、mysql2、pg (≈postgresql)、rmagick (≈ImageMagick)辺りで「何か足りないですぅううう」ってrubyが駄々をこねるかもね。先に示した様にzypperで入れておくと良い。

Your bundle is complete! Use bundle show [gemname] to see where a bundled gem is installed.

って表示されたら後はChiliProjectの初期設定なり設定移行なりをすれば良い。config/database.yml書いたりrakeとか言う呪文唱えたりね。

references

Qt Quick (QML) の小さなテンプレート

状況

QtCreatorでQt Quick Applicationをテンプレート(C++的な意味ではない)から作成すると、余計な飾り(QMLを扱う為にmainから1つわざわざユーザーコードの薄いラッパーをテンプレが生成して噛ませている)が付いてしまっていて、QMLアプリを試すには少々野暮ったい。

f:id:USAGI-WRP:20121230141833p:plain

提案

QMLアプリの小さなテンプレ作ったった。

テンプレートの中身はファイルが4つ、

  • qtq_small_template.cxx
  • qtq_small_template.pro
  • qtq_small_template.qml
  • test.png

QMLアプリの必要最小限という訳では無いけれど、学習用や小さな何かのテンプレとして使い易いかな、という程度にしてみた。お試しビルドや使い方についてはREADME参照。

Google Spreadsheet における indirect のTipsと concatenate の必要性

状況

Google Spreadsheet にて vlookup 等の引数に indirect を用いて別シートの範囲を参照させようとした。

しかし、

sheet1!A1 = "hoge"
sheet1!B1 = "fuga"
sheet1!C1 = vlookup( B1, indirect( A1 + "!A:B" ) )

こんな感じでは失敗する。

問題の指摘と解決策 1 (現在は無意味)

superuserに関連した指摘を発見できる。

Google Spreadsheetではindirect関数はA:Cの様な行指定の無い範囲指示に対応していないので A1:C999 とかすれば良いらしい。

※しかし、これは後に現時点では不要である事に気づいた。過去の仕様ではそうだったのだろう。

問題の指摘と解決策 2

indirect の引数が operator+(string,string) 的な演算子ではダメらしい。つまり以下はダメ。

A1 + "!A:B"

これは、

concatenate(A1, "!A:B")

とすると失敗しなくなる。

まとめ

sheet1!A1 = "hoge"
sheet1!B1 = "fuga"
sheet1!C1 = vlookup( B1, indirect( concatenate( A1, "!A:B" ) ) )

これ正解。

Qt / qmake / 簡単なリソースファイルの取り扱い方

先の記事のあーうーから、結局自前で簡単なスクリプトを qmake の .pro に書いてみる事にした。

状況

.cxxなどの通常のビルド対象の他に、 .qml とか .png とか .mp3 とかそういう外部リソースファイルがある場合に、 qmake が生成する Makefile でよしなにDESTDIRへコピーや削除が行われる様にしたい。

実装方法

qmakeに食べさせる .pro に次の様に実装する。

resources += \
  test.qml \
  test.png \

QMAKE_POST_LINK = @ 
for(t, resources) {
  QMAKE_POST_LINK += cp -rv $$PWD/$$t $$OUT_PWD/$$t ;
}
QMAKE_CLEAN += $$resources

resources に DESTDIR へ出力したいリソースファイル群を定義する。これは .pro からの相対パスで指定する。使うだけならばここだけ書き換えればOK。

QMAKE_POST_LINKはqmakeによって生成されたMakefileがリンカーを走らせた後に実行する単一のコマンド。"単一の"というのがポイントで、 += で空白文字区切りにコマンドを入れても結果的には単に1回だけのコマンドとして全体が評価される。よってはじめに @ を付けコマンド自体の出力を抑制し、 cp に v オプションを付けコピー状況が明示される様にし、かつresourcesから取り出した1つあたりにつき ; でコマンドを区切る様にしてある。

QMAKE_CLEANは空白文字区切りで make clean の際に追加で削除を指示したいパスを放り込む。

効果

qmake を行うビルドと実行用の作業ディレクトリーがソースのディレクトリーと異なる場合でも、makeによりリソースが正常にコピーされ、またmake cleanも一応程度に対応する。

余談

この記事書いてる中の人はVimで .pro .cxx .qml など書いて qmake とか make とかシェルで叩いてます。qmlのビジュアルな編集がしたいなーって時は qtcreator hoge.qml とかその為に動かす程度にはGUIも使うけどね・x・

そんな状態でも、 QtCreator に .pro を読ませればGUI環境がいいってメンバーとの連携もできて、かつ基本的な .pro とかその他ソースはテキストエディターさえあれば全く支障なく編集し、ビルドし、テストもできる。qmakeを使うとcmakeよりも定義量も少なく(特にQtを使う場合は勿論なおさらに)て楽です。一般的なライブラリーの検索とリンクなどはcmakeの方が便利な事もあるかもしれないけど、-Iとか-Lとか指示するだけの事だし、何事も割とqmakeに以降するのもいいのかなーなんて思い出してるところです。

Qt / qmake / DEPLOYMENTFOLDERS / qtcAddDeployment それは一体は何か?

まったく、下らない事に随分と時間を取られてしまった。1時間程だろうか(´・ω・`)

状況

Vim/zsh系でQtアプリを試していて、QMLを使ったアプリで遊ぼうとしていた。記述するコードは先ずは最小構成、

  • test.cxx
  • test.qml
  • test.pro

テストソースを書いてこの場で qmake して Makefile を生成し、 make する分には全く問題無い。

しかし、これをQtCreatorでロードし、QtCreatorからプロジェクトにビルド設定を作り(test.pro.user、これはXMLだ。ヒトやウサギなどの知的生命体が直接Vimる対象では無い・w・)、実行してみると問題が明らかになる。

先のVim/zsh系では簡単なテストという事もあり、ソースもビルドも実行も全て同じディレクトリーで行なっていた。しかし、QtCreatorに任せデフォルトで作成されたビルド設定ではソースのある場所に対して ../test-build-desktop-Qt_4_8_1_in_PATH__System__Release などにビルドと実行の為の作業ディレクトリーが設定される。

すると、実行時に test.qml をロード出来ないから、

file:///home/usagi/tmp/test-build-desktop-Qt_4_8_1_in_PATH__System__Release/test.qml: File not found 

とかそういうエラーが実行時に発生する。当然だ、そこに test.qml ファイルをコピーする様な設定はMakefileには自動追加されていないし、test.proにもそうした細工はまだしていないのだか。

そこで少々調べてみると、どうやら .pro に、

folder_01.source = ./test.qml
folder_01.target = ./
DEPLOYMENTFOLDERS = folder_01

とかすれば良さそうな事が分かった。この紹介は多数の人々がそうすればいいよ、とブログや掲示板に残してくれている。実際にこの記述は試しにQtCreatorで作成してみたQt Quickアプリの.proでも同様に記述されていた。

しかしこれ、自分で作成していた test.pro に書いても、書き方を変えても、ディレクトリーを掘って内包する様にしてみても、まったく追加でデプロイメントされなかった。

この問題の理由

DEPLOYMENTFOLDERS なる機能は qmake の機能では無く、実はQtCreatorがQt Quickアプリのテンプレで作成したプロジェクトの中にこっそり作成するユーザーコードにより定義される関数なのであった。

つまり、DEPLOYMENTFOLDERSなどいくら設定しても、それを実際にデプロイしてくれる関数がどこにも無いのだから何も起こらない。

気づいたきっかけ

QtCreatorで作成してみた.proにはqtcAddDeployment()なる関数呼び出しらしき記述も後方に追記されている事に気づいた。命名規則が全て大文字ではない事もあり、これはもしやユーザー定義では無いかと思い、その直前でincludeされている.priをよく見ると、関数定義されていた。

defineTest(qtcAddDeployment) {
for(deploymentfolder, DEPLOYMENTFOLDERS) {
    item = item$${deploymentfolder}
    itemsources = $${item}.sources
...

解決法

  1. 素直にQtCreatorのテンプレを使う。
  2. リソースをコピーする簡単なqmakeくらい書く。

後者については備忘録として次の記事でメモを残すことにします。

openSUSE-12.2 で .ymp をコンソールから登録する方法

CUIでも software.opensuse.org: Search などから目的のパッケージを探し openSUSEリポジトリーを登録し yast または zypper したい場合のメモ。

1. .ymp を探す

w3m "http://software.opensuse.org/search?q=darkhttpd"

darkhttpdにはもちろん自分が探したい何かに対し適当な検索キーワードを入れましょう。

f:id:USAGI-WRP:20121224143537p:plain

など適当な手段で.ympを探す。手作業でダウンロードする必要はないので、 .ymp のURLをクリップボード的なものにコピーしておく…でも良いのだけど、コンソールでは少し厄介なのでここは素直にファイルを保存しておく事に。w3mで.ympを開きsキーで保存します。

おまけ1
obs-search(){ if [ $# != 0 ]; then w3m "http://software.opensuse.org/search?q=$*"; fi; }

とか .zshrc なんかに仕込んで置くとCUIからもさっくり探せていいんじゃないかと思います。

おまけ2

f:id:USAGI-WRP:20121224143635p:plain

w3mならポインティングデバイスの右クリックでコンテキストメニューを出して保存する事も可能。というか基本的に操作全般にポインティングデバイス使用可能。

2. OCICLI

httpなURLをコマンドに渡せる状態の場合は OCICLI、 まさかの全部大文字コマンドですが実在します。

OCICLI "http://software.opensuse.org/ymp/home:USAGI-WRP/openSUSE_12.2/darkhttpd.ymp"

.ympを拾ってある場合は、

OCICLI file://`pwd`/darkhttpd.ymp

とか。OCICLIに渡すパラメーターはURL形式でなければならないので注意。

f:id:USAGI-WRP:20121224160602p:plain

.ympのロードに成功するとGPG鍵のインポートについてYaSTから尋ねられる。自己判断でTrustしましょう。

なお、OCICLIは基本的にユーザーが直接叩くコマンドとしては整備状況が悪く、エラーメッセージ等は出ません。GPG鍵のインポートについて訪ねて来る事も無く処理が戻って来たならばパラメーターが無効であるなどの理由で失敗している可能性が高いです。

おまけ3

OCICLIはOneClickInstallCLIの略。

file `which OCICLI`
/sbin/OCICLI: symbolic link to `OneClickInstallCLI'

追いかける。

file `which OneClickInstallCLI`
/sbin/OneClickInstallCLI: POSIX shell script, ASCII text executable

中身は22行の簡単なshスクリプト。

cat `which OneClickInstallCLI`
#!/bin/sh
if [ $# -ne 1 -o "$1" = "-h" -o "$1" = "--help" ]
then
        echo "Usage: <YMP URL>"
        exit 1
fi
TEMPFILE=$(mktemp)
/sbin/YaST OneClickInstallCLI prepareinstall url=$1 targetfile=$TEMPFILE
if [ $? -ne 0 ]
then
        exit $?
fi

echo "Continue? y/N"
read continue
continue=${continue:="N"}
if [ $continue == "Y" ] ||  [ $continue == "y" ]
then
        su -c "/sbin/YaST OneClickInstallCLI doinstall instructionsfile=$TEMPFILE"
else
        exit 2 
fi

yast2コマンドにモジュールOneClickInstallCLIを指示してprepareinstallとdoinstallをオプション付きで呼んでいるだけ。この中身を見てdoinstallだけでもローカルの.ympを処理できるのかなーと思ったけれどprepareinstallも必要らしく、素直にURL形式で渡すのが良いという結論となりました。ちなみにopenSUSE-12.2のyastYaSTはyast2へのシンボリックリンクです。

3. zypper したりで目的のパッケージをインストール

zypper se darkhttpd
リポジトリのデータを読み込んでいます...
インストール済みのパッケージを読み込んでいます...

S | 名前      | 概要                                   | 種類            
--+-----------+----------------------------------------+-----------------
  | darkhttpd | When you need a web server in a hurry. | ソースパッケージ

出てきましたねー^-^

zypper in darkhttpd
 ...

めでたしめでたし。これでGUIなんてコストを掛けたくない環境でも設定ファイル直接いじらずとも楽にあっさりリポジトリーの追加とパッケージの導入ができるようになりました。

Linuxの小技 sudo su -c command

/sbin のコマンドなんかは sudo で権限だけ昇格してもパスの都合使えない事もある。そんな時は、

sudo su -c command

とすると sudo の認証管理で su -c command が実行され、 su はログイン時に /etc/profile を処理するので通常管理者権限のパスも処理された状態で -c オプションのコマンドが実行される。

sudo /sbin/command

でもいいんだけどさ・w・

rootがパスワード管理されている場合は

su -c command

でもいいんだけどさ・w・

当然 alias に仕込んで置くと便利。suはrootがパスワード管理されていないと使えない事と認証の管理が基本的にコマンド打つ度になるのでダルい。sudo su -c は管理者権限の認証の管理はsudoに任せられる点が良い。

おまけ

ssh root@::1 command

という若干謎を感じる方法も有り。