Skip to content

Commit

Permalink
[iOS] Ensure runpath search path contains $(inherited) to avoid build…
Browse files Browse the repository at this point in the history
… warnings/issues. Resolves dpa99c#25.
  • Loading branch information
Dave Alden authored and tom-hartz committed Nov 22, 2019
1 parent 751f0c9 commit c1359a3
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 88 deletions.
4 changes: 4 additions & 0 deletions scripts/after_prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ module.exports = function (context) {
if (platforms.indexOf('ios') !== -1 && utilities.directoryExists(IOS_DIR)) {
console.log('Preparing Firebase on iOS');
utilities.copyKey(PLATFORM.IOS);

var helper = require("./ios/helper");
var xcodeProjectPath = helper.getXcodeProjectPath(context);
helper.ensureRunpathSearchPath(context, xcodeProjectPath);
}
if (platforms.indexOf('android') !== -1 && utilities.directoryExists(ANDROID_DIR)) {
console.log('Preparing Firebase on Android');
Expand Down
208 changes: 120 additions & 88 deletions scripts/ios/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,132 +11,164 @@ var comment = "\"Crashlytics\"";

module.exports = {

/**
/**
* Used to get the path to the XCode project's .pbxproj file.
*
* @param {object} context - The Cordova context.
* @returns The path to the XCode project's .pbxproj file.
*/
getXcodeProjectPath: function (context) {
getXcodeProjectPath: function (context) {

var appName = utilities.getAppName(context);
var appName = utilities.getAppName(context);

return path.join("platforms", "ios", appName + ".xcodeproj", "project.pbxproj");
},
return path.join("platforms", "ios", appName + ".xcodeproj", "project.pbxproj");
},

/**
/**
* This helper is used to add a build phase to the XCode project which runs a shell
* script during the build process. The script executes Crashlytics run command line
* tool with the API and Secret keys. This tool is used to upload the debug symbols
* (dSYMs) so that Crashlytics can display stack trace information in it's web console.
*/
addShellScriptBuildPhase: function (context, xcodeProjectPath) {

// Read and parse the XCode project (.pxbproj) from disk.
// File format information: http://www.monobjc.net/xcode-project-file-format.html
var xcodeProject = xcode.project(xcodeProjectPath);
xcodeProject.parseSync();

// Build the body of the script to be executed during the build phase.
var script = '"' + '\\"${PODS_ROOT}/Fabric/run\\"' + '"';

// Generate a unique ID for our new build phase.
var id = xcodeProject.generateUuid();
// Create the build phase.
xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[id] = {
isa: "PBXShellScriptBuildPhase",
buildActionMask: 2147483647,
files: [],
inputPaths: ['"' + '$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)' + '"'],
name: comment,
outputPaths: [],
runOnlyForDeploymentPostprocessing: 0,
shellPath: "/bin/sh",
shellScript: script,
showEnvVarsInLog: 0
addShellScriptBuildPhase: function (context, xcodeProjectPath) {

// Read and parse the XCode project (.pxbproj) from disk.
// File format information: http://www.monobjc.net/xcode-project-file-format.html
var xcodeProject = xcode.project(xcodeProjectPath);
xcodeProject.parseSync();

// Build the body of the script to be executed during the build phase.
var script = '"' + '\\"${PODS_ROOT}/Fabric/run\\"' + '"';

// Generate a unique ID for our new build phase.
var id = xcodeProject.generateUuid();
// Create the build phase.
xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[id] = {
isa: "PBXShellScriptBuildPhase",
buildActionMask: 2147483647,
files: [],
inputPaths: ['"' + '$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)' + '"'],
name: comment,
outputPaths: [],
runOnlyForDeploymentPostprocessing: 0,
shellPath: "/bin/sh",
shellScript: script,
showEnvVarsInLog: 0
};

// Add a comment to the block (viewable in the source of the pbxproj file).
xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[id + "_comment"] = comment;
// Add a comment to the block (viewable in the source of the pbxproj file).
xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[id + "_comment"] = comment;

// Add this new shell script build phase block to the targets.
for (var nativeTargetId in xcodeProject.hash.project.objects.PBXNativeTarget) {
// Add this new shell script build phase block to the targets.
for (var nativeTargetId in xcodeProject.hash.project.objects.PBXNativeTarget) {

// Skip over the comment blocks.
if (nativeTargetId.indexOf("_comment") !== -1) {
continue;
}
// Skip over the comment blocks.
if (nativeTargetId.indexOf("_comment") !== -1) {
continue;
}

var nativeTarget = xcodeProject.hash.project.objects.PBXNativeTarget[nativeTargetId];
var nativeTarget = xcodeProject.hash.project.objects.PBXNativeTarget[nativeTargetId];

nativeTarget.buildPhases.push({
value: id,
comment: comment
});
}
nativeTarget.buildPhases.push({
value: id,
comment: comment
});
}

// Finally, write the .pbxproj back out to disk.
fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync());
},
// Finally, write the .pbxproj back out to disk.
fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync());
},

/**
/**
* This helper is used to remove the build phase from the XCode project that was added
* by the addShellScriptBuildPhase() helper method.
*/
removeShellScriptBuildPhase: function (context, xcodeProjectPath) {
removeShellScriptBuildPhase: function (context, xcodeProjectPath) {

// Read and parse the XCode project (.pxbproj) from disk.
// File format information: http://www.monobjc.net/xcode-project-file-format.html
var xcodeProject = xcode.project(xcodeProjectPath);
xcodeProject.parseSync();
// Read and parse the XCode project (.pxbproj) from disk.
// File format information: http://www.monobjc.net/xcode-project-file-format.html
var xcodeProject = xcode.project(xcodeProjectPath);
xcodeProject.parseSync();

// First, we want to delete the build phase block itself.
// First, we want to delete the build phase block itself.

var buildPhases = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase;
var buildPhases = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase;

var commentTest = comment.replace(/"/g, '');
for (var buildPhaseId in buildPhases) {
var commentTest = comment.replace(/"/g, '');
for (var buildPhaseId in buildPhases) {

var buildPhase = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[buildPhaseId];
var shouldDelete = false;
var buildPhase = xcodeProject.hash.project.objects.PBXShellScriptBuildPhase[buildPhaseId];
var shouldDelete = false;

if (buildPhaseId.indexOf("_comment") === -1) {
// Dealing with a build phase block.
if (buildPhaseId.indexOf("_comment") === -1) {
// Dealing with a build phase block.

// If the name of this block matches ours, then we want to delete it.
shouldDelete = buildPhase.name && buildPhase.name.indexOf(commentTest) !== -1;
} else {
// Dealing with a comment block.
// If the name of this block matches ours, then we want to delete it.
shouldDelete = buildPhase.name && buildPhase.name.indexOf(commentTest) !== -1;
} else {
// Dealing with a comment block.

// If this is a comment block that matches ours, then we want to delete it.
shouldDelete = buildPhase === commentTest;
}
// If this is a comment block that matches ours, then we want to delete it.
shouldDelete = buildPhase === commentTest;
}

if (shouldDelete) {
delete buildPhases[buildPhaseId];
}
}
if (shouldDelete) {
delete buildPhases[buildPhaseId];
}
}

// Second, we want to delete the native target reference to the block.
// Second, we want to delete the native target reference to the block.

var nativeTargets = xcodeProject.hash.project.objects.PBXNativeTarget;
var nativeTargets = xcodeProject.hash.project.objects.PBXNativeTarget;

for (var nativeTargetId in nativeTargets) {
for (var nativeTargetId in nativeTargets) {

// Skip over the comment blocks.
if (nativeTargetId.indexOf("_comment") !== -1) {
continue;
}
// Skip over the comment blocks.
if (nativeTargetId.indexOf("_comment") !== -1) {
continue;
}

var nativeTarget = nativeTargets[nativeTargetId];
var nativeTarget = nativeTargets[nativeTargetId];

// We remove the reference to the block by filtering out the the ones that match.
nativeTarget.buildPhases = nativeTarget.buildPhases.filter(function (buildPhase) {
return buildPhase.comment !== commentTest;
});
}
// We remove the reference to the block by filtering out the the ones that match.
nativeTarget.buildPhases = nativeTarget.buildPhases.filter(function (buildPhase) {
return buildPhase.comment !== commentTest;
});
}

// Finally, write the .pbxproj back out to disk.
fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync());
},

ensureRunpathSearchPath: function(context, xcodeProjectPath){

// Finally, write the .pbxproj back out to disk.
fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync());
}
function addRunpathSearchBuildProperty(proj, build) {
const LD_RUNPATH_SEARCH_PATHS = proj.getBuildProperty("LD_RUNPATH_SEARCH_PATHS", build);
if (!LD_RUNPATH_SEARCH_PATHS) {
proj.addBuildProperty("LD_RUNPATH_SEARCH_PATHS", "\"$(inherited) @executable_path/Frameworks\"", build);
}
if (LD_RUNPATH_SEARCH_PATHS.indexOf("@executable_path/Frameworks") == -1) {
var newValue = LD_RUNPATH_SEARCH_PATHS.substr(0, LD_RUNPATH_SEARCH_PATHS.length - 1);
newValue += ' @executable_path/Frameworks\"';
proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build);
}
if (LD_RUNPATH_SEARCH_PATHS.indexOf("$(inherited)") == -1) {
var newValue = LD_RUNPATH_SEARCH_PATHS.substr(0, LD_RUNPATH_SEARCH_PATHS.length - 1);
newValue += ' $(inherited)\"';
proj.updateBuildProperty("LD_RUNPATH_SEARCH_PATHS", newValue, build);
}
}

// Read and parse the XCode project (.pxbproj) from disk.
// File format information: http://www.monobjc.net/xcode-project-file-format.html
var xcodeProject = xcode.project(xcodeProjectPath);
xcodeProject.parseSync();

// Add search paths build property
addRunpathSearchBuildProperty(xcodeProject, "Debug");
addRunpathSearchBuildProperty(xcodeProject, "Release");

// Finally, write the .pbxproj back out to disk.
fs.writeFileSync(xcodeProjectPath, xcodeProject.writeSync());
}
};

0 comments on commit c1359a3

Please sign in to comment.