ここ数日睡眠リズムが良くないから本調子でないことに加えて、根本原因探るのに行き詰まっていることもあって、気分転換にブログ書くことにしました。
どのようにbuildされるのか考察したまとめ
Python&Objective-Cをそんなに理解してないですが、メソッド名頼りに流れを追ってみた結果、おそらくこんな感じでbuildされているんじゃないかと思います
- titanium.pyで実行に必要なパラメータチェックを(たぶん)実行。問題なければiphone/builder.py(もしくはandroid/builder.py)が実行される
- builder.pyが実行されて、main.mが自動生成されているはず(builder.py1500行近くあるので後日がんばって触れたい)
- main.mの情報を参照しつつ、雛形となるファイルをプロジェクト配下の/build/iphone/Classes/以下にファイルを生成していく
※以下はまとめと関係ないですが、ちょっと戯言を※
「そもそもソースコードってどうやって読み進めるんだろう?」という漠然とした疑問がありました。
2,3年位前だとファイルを1行1行くまなく読んでいこうとしていた時期もあったのですが、それだと”木を見て森を見ず”の状態で結局概要がよくわからず、結局嫌になってしまったという苦い思い出が多々ありました。(職業プログラマとしての経験があればこのあたりのコツというのは仕事を通じて得る機会があるのかもしれませんね)
「周囲の人からソースコード嫁!って言われるけど、とっかかりが掴めない」
っていう人もいるんじゃないかと何となく思ったのと、もしかしたらTitanium勉強会を今後も継続していったとして、将来こういう話題も触れても面白いかもしれないので、どのようなことを考え、実践した結果、上記まとめにつながったのか、以下時系列に書いておこうと思います
そもそもコードを読む目的を見失わないようにした
「Titanium Mobileの内部構造理解すれば、どの部分でresourcesDirectoryの設定しているのかわかるんじゃないかなぁ」
という考えに至り、ひとまずTiFileのソースコードを追っかけてみることにしました。
と最後に触れているように、どの部分でresourcesDirectoryの設定しているのかを把握することが今回コードを読む目的として設定しました
まずはTiFile ざっくりと読んでみた
TiFileに着目した理由はファイル名からして、なんか関連ありそうと思ったので、正直根拠ないですww Objective-Cを正確に理解してないですが、ひとまずTi.File.mを開いたら以下のようなメソッドがありました
- (void)dealloc
- (id)initWithPath:(NSString*)path_
- (id)initWithTempFilePath:(NSString*)path_
- (NSString*)path
- (NSInteger)size
- (id)blob
- (id)toBlob:(id)args
- (TiFile*)createTempFile:(NSString*)extension
「メソッド名とかから推測するにdeallocはメモリ管理的な何かっぽい」
「initWithで始まるやつは、引数のpathが渡されてそれに対して何か初期化してるのかな」
「blobやとBlobは読み方がよくわからないけど、バイナリファイルを扱う時の何かかな?」
という感じで眺めてみて、
「あれ、このTi.Fileの中には見る限り、resourcesDirectoryやapplicationDirectoryのパスの情報が埋め込まれているわけじゃないんだ。そうなると、どっかで設定ファイルらしきものがあって、そのファイルを読み込む処理をこのTi.Fileが担ってるのかな」
という妄想を含まらせましたw
設定ファイルらしきものはそもそも何処にあるんだろう
今まであまり考えたことがなかったのですが、きっとそれらしいファイルがあるはずに違いないと思って少し探ってみました。
「そういえば、Titanium Studioでbuild実行するとプロジェクト配下の/build/iphone以下に色々ファイルが生成されるけど、この中のどれかが関連してそう」
と思って、チェックしていき、main.mを開くと
#import <UIKit/UIKit.h> #define _QUOTEME(x) #x #define STRING(x) _QUOTEME(x) NSString * const TI_APPLICATION_DEPLOYTYPE = @"development"; NSString * const TI_APPLICATION_ID = @"jpxxxx"; NSString * const TI_APPLICATION_PUBLISHER = @"xxx"; NSString * const TI_APPLICATION_URL = @"http://"; NSString * const TI_APPLICATION_NAME = @"asunaroViewer"; NSString * const TI_APPLICATION_VERSION = @"1.0"; NSString * const TI_APPLICATION_DESCRIPTION = @"not specified"; NSString * const TI_APPLICATION_COPYRIGHT = @"2012 by xxxx"; NSString * const TI_APPLICATION_GUID = @"03....."; BOOL const TI_APPLICATION_ANALYTICS = true; #ifdef TARGET_IPHONE_SIMULATOR NSString * const TI_APPLICATION_RESOURCE_DIR = @"/Users/xxxxx/project/Resources"; #endif
という感じで、自分が求めていた情報(NSString * const TI_APPLICATION_RESOURCE_DIR = @"/Users/xxxxx/project/Resources";)が見つかりましたー
このmain.mの先頭行に
WARNING: this is a generated file and should not be modified
とあるように、自動生成されてます。
このファイルを生成するスクリプトがどっかにあるはずで、
「あー、日頃ターミナルからtitanium -run ...とやってるわけだし、~/Library/Application Support/Titanium/mobilesdk/osx/1.7.5/titanium.pyが関係あるんだ」
とすぐわかりました。
titanium.pyを開き、自分自身Pythonそんなに知らないけど、ひとまずメソッド名を頼りにまずは全体を眺めました。
「titanium -run実行された際に該当しそうな runというそのものズバリなメソッドはない。def run_project_argsというので、引数チェックして、実際のrunに相当するのはdef dyn_run(args,project_cb,module_cbが該当しそう」
というおおまかな”あたり”をつけてif分がたくさんあるのを無視しつつ眺めていたら
if atype == 'project': script = os.path.join(template_dir,platform,'builder.py') cmdline = project_cb(args,script,project_dir,platform)
という箇所がわかり、ここでbuilder.pyが実行されるというのがわかりました
次回続くかも??
builder.pyでやってることは何となくわかるのですが、ちょっと行数多いので、この部分の処理をどのようにして追っていったのか次回まとめたいと思います。