Skip to content

Commit c5990c1

Browse files
author
Roberto Andrade
committed
Adding options to make embedding of frameworks (i.e.: iOS 8 custom frameworks) as well as linking (i.e.: skipping it for header-only frameworks) optional.
1 parent 6d88702 commit c5990c1

File tree

3 files changed

+1325
-19
lines changed

3 files changed

+1325
-19
lines changed

lib/pbxProject.js

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,24 @@ pbxProject.prototype.addFramework = function(fpath, opt) {
270270

271271
if (this.hasFile(file.path)) return false;
272272

273+
var customFramework = opt && opt.customFramework == true;
274+
var link = !opt || (opt.link == undefined || opt.link); //defaults to true if not specified
275+
var embed = opt && opt.embed; //defaults to false if not specified
276+
273277
this.addToPbxBuildFileSection(file); // PBXBuildFile
274278
this.addToPbxFileReferenceSection(file); // PBXFileReference
275279
this.addToFrameworksPbxGroup(file); // PBXGroup
276-
this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
277280

278-
if (opt && opt.customFramework == true) {
281+
if (link) {
282+
this.addToPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
283+
}
284+
285+
if (customFramework) {
279286
this.addToFrameworkSearchPaths(file);
287+
288+
if (embed) {
289+
this.addToPbxEmbedFrameworksBuildPhase(file); // PBXCopyFilesBuildPhase
290+
}
280291
}
281292

282293
return file;
@@ -286,10 +297,11 @@ pbxProject.prototype.removeFramework = function(fpath, opt) {
286297
var file = new pbxFile(fpath, opt);
287298
file.target = opt ? opt.target : undefined;
288299

289-
this.removeFromPbxBuildFileSection(file); // PBXBuildFile
290-
this.removeFromPbxFileReferenceSection(file); // PBXFileReference
291-
this.removeFromFrameworksPbxGroup(file); // PBXGroup
292-
this.removeFromPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
300+
this.removeFromPbxBuildFileSection(file); // PBXBuildFile
301+
this.removeFromPbxFileReferenceSection(file); // PBXFileReference
302+
this.removeFromFrameworksPbxGroup(file); // PBXGroup
303+
this.removeFromPbxFrameworksBuildPhase(file); // PBXFrameworksBuildPhase
304+
this.removeFromPbxEmbedFrameworksBuildPhase(file); // PBXCopyFilesBuildPhase
293305

294306
if (opt && opt.customFramework) {
295307
this.removeFromFrameworkSearchPaths(path.dirname(fpath));
@@ -578,6 +590,24 @@ pbxProject.prototype.removeFromFrameworksPbxGroup = function(file) {
578590
}
579591
}
580592

593+
pbxProject.prototype.addToPbxEmbedFrameworksBuildPhase = function (file) {
594+
var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
595+
if (sources) {
596+
sources.files.push(pbxBuildPhaseObj(file));
597+
}
598+
}
599+
600+
pbxProject.prototype.removeFromPbxEmbedFrameworksBuildPhase = function (file) {
601+
var sources = this.pbxEmbedFrameworksBuildPhaseObj(file.target);
602+
if (sources) {
603+
for (i in sources.files) {
604+
if (sources.files[i].comment == longComment(file)) {
605+
sources.files.splice(i, 1);
606+
break;
607+
}
608+
}
609+
}
610+
}
581611

582612
pbxProject.prototype.addToProductsPbxGroup = function(file) {
583613
var productsGroup = this.pbxGroupByName('Products');
@@ -905,6 +935,10 @@ pbxProject.prototype.pbxFrameworksBuildPhaseObj = function(target) {
905935
return this.buildPhaseObject('PBXFrameworksBuildPhase', 'Frameworks', target);
906936
}
907937

938+
pbxProject.prototype.pbxEmbedFrameworksBuildPhaseObj = function (target) {
939+
return this.buildPhaseObject('PBXCopyFilesBuildPhase', 'Embed Frameworks', target);
940+
};
941+
908942
// Find Build Phase from group/target
909943
pbxProject.prototype.buildPhase = function(group, target) {
910944

@@ -1166,14 +1200,14 @@ pbxProject.prototype.removeFromOtherLinkerFlags = function (flag) {
11661200
var configurations = nonComments(this.pbxXCBuildConfigurationSection()),
11671201
OTHER_LDFLAGS = 'OTHER_LDFLAGS',
11681202
config, buildSettings;
1169-
1203+
11701204
for (config in configurations) {
11711205
buildSettings = configurations[config].buildSettings;
1172-
1206+
11731207
if (unquote(buildSettings['PRODUCT_NAME']) != this.productName) {
11741208
continue;
11751209
}
1176-
1210+
11771211
if (buildSettings[OTHER_LDFLAGS]) {
11781212
var matches = buildSettings[OTHER_LDFLAGS].filter(function (p) {
11791213
return p.indexOf(flag) > -1;
@@ -1192,7 +1226,7 @@ pbxProject.prototype.addToBuildSettings = function (buildSetting, value) {
11921226

11931227
for (config in configurations) {
11941228
buildSettings = configurations[config].buildSettings;
1195-
1229+
11961230
buildSettings[buildSetting] = value;
11971231
}
11981232
}
@@ -1203,7 +1237,7 @@ pbxProject.prototype.removeFromBuildSettings = function (buildSetting) {
12031237

12041238
for (config in configurations) {
12051239
buildSettings = configurations[config].buildSettings;
1206-
1240+
12071241
if (buildSettings[buildSetting]) {
12081242
delete buildSettings[buildSetting];
12091243
}
@@ -1245,22 +1279,22 @@ pbxProject.prototype.addTarget = function(name, type, subfolder) {
12451279
targetType = type,
12461280
targetSubfolder = subfolder || name,
12471281
targetName = name.trim();
1248-
1282+
12491283
// Check type against list of allowed target types
12501284
if (!targetName) {
12511285
throw new Error("Target name missing.");
1252-
}
1286+
}
12531287

12541288
// Check type against list of allowed target types
12551289
if (!targetType) {
12561290
throw new Error("Target type missing.");
1257-
}
1291+
}
12581292

12591293
// Check type against list of allowed target types
12601294
if (!producttypeForTargettype(targetType)) {
12611295
throw new Error("Target type invalid: " + targetType);
12621296
}
1263-
1297+
12641298
// Build Configuration: Create
12651299
var buildConfigurationsList = [
12661300
{

test/addFramework.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ exports.addFramework = {
128128
test.equal(buildFileEntry.fileRef, newFile.fileRef);
129129
test.equal(buildFileEntry.fileRef_comment, 'libsqlite3.dylib');
130130
test.deepEqual(buildFileEntry.settings, { ATTRIBUTES: [ 'Weak' ] });
131-
131+
132132
test.done();
133133
},
134134
'should add to the Frameworks PBXGroup': function (test) {
@@ -155,6 +155,13 @@ exports.addFramework = {
155155
test.equal(frameworks.files.length, 16);
156156
test.done();
157157
},
158+
'should not add to the PBXFrameworksBuildPhase': function (test) {
159+
var newFile = proj.addFramework('Private.framework', {link: false}),
160+
frameworks = proj.pbxFrameworksBuildPhaseObj();
161+
162+
test.equal(frameworks.files.length, 15);
163+
test.done();
164+
},
158165
'should have the right values for the Sources entry': function (test) {
159166
var newFile = proj.addFramework('libsqlite3.dylib'),
160167
frameworks = proj.pbxFrameworksBuildPhaseObj(),
@@ -188,12 +195,26 @@ exports.addFramework = {
188195
// should add path to framework search path
189196
var frameworkPaths = frameworkSearchPaths(proj);
190197
expectedPath = '"\\"/path/to\\""';
191-
198+
192199
for (i = 0; i < frameworkPaths.length; i++) {
193200
var current = frameworkPaths[i];
194201
test.ok(current.indexOf('"$(inherited)"') >= 0);
195202
test.ok(current.indexOf(expectedPath) >= 0);
196203
}
197204
test.done();
198-
}
205+
},
206+
'should add to the Embed Frameworks PBXCopyFilesBuildPhase': function (test) {
207+
var newFile = proj.addFramework('/path/to/SomeEmbeddableCustom.framework', {customFramework: true, embed: true}),
208+
frameworks = proj.pbxEmbedFrameworksBuildPhaseObj();
209+
210+
test.equal(frameworks.files.length, 1);
211+
test.done();
212+
},
213+
'should not add to the Embed Frameworks PBXCopyFilesBuildPhase by default': function (test) {
214+
var newFile = proj.addFramework('/path/to/Custom.framework', {customFramework: true}),
215+
frameworks = proj.pbxEmbedFrameworksBuildPhaseObj();
216+
217+
test.equal(frameworks.files.length, 0);
218+
test.done();
219+
},
199220
}

0 commit comments

Comments
 (0)