shonen.hateblo.jp

やったこと,しらべたことを書く.

Linux版OpenSiv3dプロジェクト作成メモ

環境

Ubuntu 19.04

でもArchLinuxの方が導入楽そうな気がしました。

前提

リポジトリはclone済み。

公式のreadme.mdを読んで、一通りビルドして、OpenSiv3D/Linux/Release/libSiv3D.a がある。

やりかた(事前準備なしで)

カレントディレクトリは、今から作業しようと思っているプロジェクトディレクトリとします。

環境変数を定義しておきます。/path/to/opensiv3drepositoryroot は、 opensiv3d の repository のルートディレクトリで、直下にLICENSEや、README.mdがある場所です。

export SIV3D_PATH=/path/to/opensiv3drepositoryroot

以下のファイル・ディレクトリをコピーします。

  • $SIV3D_PATH/Linux/App/CMakeLists.txt
  • $SIV3D_PATH/Linux/App/resources
  • $SIV3D_PATH/Linux/App/Main.cpp

CMakeLists.txt に以下のパッチを当てます。

@@ -26,8 +26,8 @@
 include_directories(
    "/usr/include"
 
-  "../../Siv3D/include"
-  "../../Siv3D/include/ThirdParty"
+   "$ENV{SIV3D_PATH}/Siv3D/include"
+   "$ENV{SIV3D_PATH}/Siv3D/include/ThirdParty"
 )
 
 set(SOURCE_FILES
@@ -61,6 +61,6 @@
    -lvorbisfile
    -lboost_filesystem
 
-  ${PROJECT_SOURCE_DIR}/../Build/libSiv3D.a
+   $ENV{SIV3D_PATH}/Linux/Release/libSiv3D.a
 )

ビルドします。

cmake .
make

hello world!

./Siv3D_App

やりかた(事前準備ありでもっとお手軽に)

事前準備

bashrcに環境変数を書き込んでおきます。

echo 'export SIV3D_PATH=/path/to/opensiv3drepositoryroot' >> ~/.bashrc
source ~/.bashrc

スクリプトを作っておきます。~/make_siv3dproj.sh とします。

#!/bin/sh

cp $SIV3D_PATH/Linux/App/CMakeLists.txt ./
cp $SIV3D_PATH/Linux/App/resources ./ -r
cp $SIV3D_PATH/Linux/App/Main.cpp ./

patch CMakeLists.txt <<EOL
@@ -26,8 +26,8 @@
 include_directories(
        "/usr/include"
 
-       "../../Siv3D/include"
-       "../../Siv3D/include/ThirdParty"
+       "\$ENV{SIV3D_PATH}/Siv3D/include"
+       "\$ENV{SIV3D_PATH}/Siv3D/include/ThirdParty"
 )
 
 set(SOURCE_FILES
@@ -61,6 +61,6 @@
        -lvorbisfile
        -lboost_filesystem
 
-       \${PROJECT_SOURCE_DIR}/../Build/libSiv3D.a
+       \$ENV{SIV3D_PATH}/Linux/Release/libSiv3D.a
 )
 
EOL

cmake .

お手軽な方法

わずか3ステップ

cd your/nice/project
sh ~/make_siv3dproj.sh
make
./Siv3D_App

Github Actions を nodejs(npm) の repository で試してみた。

Github Actions とは?

ソフトウェアの品質を担保するために、定期的にビルドを行ったり、git push する前に自動的に単体テストを実行したりする 環境を整えている開発チームは少なくないと思います。

こういう環境はローカルに構築することは出来なくは無いのですが、複数人で開発しているとか、 repositoryが外部(Github)にあるとかだと、常時起動するサーバを準備して、jenkins等のCIツールを構築するのが一般的ではないでしょうか。

Github の Pull Request と連動したい場合は、Github の Webhook が便利ですが、Github から jenkins に POST できるよう、 サーバを公開しなければなりません。 趣味でさくらVPSを持っている人ならともかく、CI環境を構築するためだけにサーバを買ったり、 jenkinsをインストールしたりするのはオーバーキル感があります。

Github Actions は、上記に挙げた例をすべてGithub側で行うことが出来ます。 しかも公開repositoryなら無料で出来ます。つよい

現状

記事を書いている時点でBeta版であり、申請のようなものが必要で(といっても個人情報を入力するようなことは無いです)、 今すぐに利用開始は出来ません。

続きを読む

文字列・シンボルからクラスインスタンスを取得する

こういうコードがあるとする。

class Hoge
  def initialize
    puts 'init Hoge'
  end
end

c = Hoge
c.new

c = Hoge しているんだけれども、Hogeというのをコードに直接書くのではなく、 Hogeという文字列やシンボルからHogeクラスのインスタンスを取りたい。

eval 使えば済むんだけど、ちょっと抵抗あるよね。

sym = :Hoge
c = eval(sym.to_s)
c.new

Hoge がクラス名ではなく、ただの定数であることに気づくと、Module#const_get を使えば良いことが分かる。 自身のクラスインスタンスを取得するメソッドは Object#class だから、

sym = :Hoge
c = class.const_get(sym)
c.new

としたい所だけれども、classはキーワードなので、syntax errorとなる。 selfを噛ませると回避できた。

sym = :Hoge
c = self.class.const_get(sym)
c.new

Procを受けるところにメソッドを与える

やりたいこと

def f(x)
  x+2
end
p [1,2,4,8].map{|e| f(e)}

を効率よく書きたい。

Object#method を使う

Object#method を使うことでmethodのオブジェクトが取れる。

def f(x)
  x+2
end
p [1,2,4,8].map(&method(:f))

モジュールの場合

モジュールをmethodメソッドのレシーバとすれば出来る。

module M
  def self.f(x)
    x+2
  end
end
p [1,2,4,8].map(&M.method(:f))