Xcode7から**.dylibファイルが.tbd**に変わりましたが、.tdbライブラリを
Xcode Manipulation API で追加するのがなかなかうまくいかなかったため、その方法です。
Unity5.2.2f1で確認しています。
[追記]
Unity5.3.2p1からは.tbdの追加に対応され、.dylib同様に以下のコードだけでOKになりました
proj.AddFileToBuild(target, proj.AddFile("usr/lib/libsqlite3.tbd", "Frameworks/libsqlite3.tbd", PBXSourceTree.Sdk));
コード
先にコードを全部載せます。
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using System.Collections.Generic;
using System.Text;
using System.IO;
public class PostBuildProcess {
[PostProcessBuild]
public static void OnPostProcessBuild (BuildTarget buildTarget, string path) {
if (buildTarget == BuildTarget.iOS) {
processForiOS (path);
}
}
private static void processForiOS (string path) {
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";
PBXProject proj = new PBXProject ();
proj.ReadFromString (File.ReadAllText (projPath));
string target = proj.TargetGuidByName ("Unity-iPhone");
// tbd追加
string tbdName = "libsqlite3.tbd";
proj.AddFileToBuild(target, proj.AddFile("usr/lib/" + tbdName, "Frameworks/" + tbdName, PBXSourceTree.Sdk));
string projText = addTbdLibrary (target, proj.WriteToString (), tbdName);
File.WriteAllText(projPath, projText);
}
// .pbxprojファイルのtbdの記述を修正して返却
private static string addTbdLibrary(string target, string projText, string tbdName) {
string[] lines = projText.Split ('\n');
List<string> newLines = new List<string> ();
string refId = null;
bool editFinish = false;
for (int i = 0; i < lines.Length; i++) {
string line = lines [i];
if (editFinish) {
newLines.Add (line);
} else if (line.IndexOf (tbdName) > -1) {
if (refId == null && line.IndexOf ("PBXBuildFile") > -1) {
refId = line.Substring (0, line.IndexOf ("/*")).Trim ();
} else if (line.IndexOf ("lastKnownFileType") > -1) {
line = line.Replace ("lastKnownFileType = file;", "lastKnownFileType = \"sourcecode.text-based-dylib-definition\";");
}
newLines.Add (line);
} else if (line.IndexOf ("isa = PBXFrameworksBuildPhase;") > -1) {
do {
newLines.Add (line);
line = lines [++i];
} while (line.IndexOf("files = (") == -1);
while (true) {
if (line.IndexOf (")") > -1) {
newLines.Add (refId + ",");
newLines.Add (line);
break;
} else if (line.IndexOf (refId) > -1) {
newLines.Add (line);
break;
} else {
newLines.Add (line);
line = lines [++i];
}
}
editFinish = true;
} else {
newLines.Add (line);
}
}
return string.Join ("\n", newLines.ToArray ());
}
}
説明
dylibの場合は、以下の方法でいけるっぽいです。
// dylib追加
proj.AddFileToBuild(target, proj.AddFile("usr/lib/libsqlite3.dylib", "Frameworks/libsqlite3.dylib", PBXSourceTree.Sdk));
[追記]
Unity5.3.2p1からは、.tbdでも上記の書き方だけででOKになってます。
tbdで同じように書いたところ、Xcode上で「Project navigator」には追加されますが、
「Link Binary With Libraries」に追加されず、リンクが完全ではない状態でした。
そこでXcode上の操作で追加した場合と比較してみると、以下の箇所が違っているようでした。
XXXXXXXXXXXXXXXXXXXXXXXX /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = file; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
... 省略 ...
/* Begin PBXFrameworksBuildPhase section */
XXXXXXXXXXXXXXXXXXXXXXXX /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
... 省略 ...
XXXXXXXXXXXXXXXXXXXXXXXX /* libsqlite3.tbd in Resources */,
);
XXXXXXXXXXXXXXXXXXXXXXXX /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };
... 省略 ...
/* Begin PBXFrameworksBuildPhase section */
XXXXXXXXXXXXXXXXXXXXXXXX /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
... 省略 ...
);
1つ目の違いが「lastKnownFileType = file」が「"sourcecode.text-based-dylib-definition"」になっている点、
もう1つがPBXFrameworksBuildPhaseのfilesリストに追加されていない点です。
そのためこの2つを無理矢理変更しているコードが上に書いたものです。
そのうちこんなことをしなくても、もっと簡単に.tbdを追加できるようになるとは思いますが、
それまでの繋ぎで使えれば良いかと思います。
補足
PBXProjectオブジェクトをメソッドの引数に渡して処理をしようとすると、
以下のようなエラーが出ます。
FileNotFoundException: Could not load file or assembly 'UnityEditor.iOS.Extensions.Xcode, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
private static void test(PBXProject proj) {
proj.WriteToString ();
}
そのためPBXProjectの操作は、newしたメソッドの中で完結させる必要があるようです。(謎)
以上