Repository navigation
Description
Split out of #200, as suggested there: this is its removeSourceFile half.
Summary
removeSourceFile deletes the file's PBXBuildFile by the file's name, but finds its entry in the Sources build phase by comment: longComment(file), "<name> in <group>", with the group the running version detects for the file's type. An entry commented any other way stays in the build phase, pointing at a PBXBuildFile that no longer exists.
An upgrade is enough to get there. 4.0.0 doesn't map .mm, so it comments a .mm's build file in Resources; master, which maps it since #199, looks for in Sources. So a plugin's .mm that cordova-ios added with 4.0.0 and removes with a release that includes #199 leaves its entry in the Sources build phase. Once #201 lands, the same happens to a .c, .cpp, .cc or .cxx that 4.0.0 added.
Steps to reproduce
- Download the gist https://gist.github.com/YevheniiKotyrlo/83e2ad5c1e82e506fe82cea69371b9d2 into an empty folder:
package.json, which depends onxcodefrom this repository at 354a163 and onxcode@4.0.0asxcode-4.0.0, andrepro.js. - Add the repository's test project beside them and install:
npm 12 fetches the git dependency only with
curl -sSfLO https://raw.githubusercontent.com/apache/cordova-node-xcode/354a1631d0a448531e4cc0aee8ca60c89262d1f1/test/parser/projects/full.pbxproj npm install
--allow-git=root. - Run
node repro.js full.pbxproj. It addsPlugins/com.example.plugin/Plain.mmwithaddSourceFile(path, {})and removes it withremoveSourceFile(path), as cordova-ios does for a plugin's<source-file>(install, uninstall): first withmasterfor both, then adding with 4.0.0. It prints the build file and build phase lines each addition wrote, and every line still namingPlain.mmafter the removal.
Expected: nothing names Plain.mm after the removal, whichever version added it.
Actual: when 4.0.0 added it, the Sources build phase keeps Plain.mm in Resources, whose uuid is defined nowhere:
== added by master, removed by master
added: F27FAA5682EF4239A600E77C /* Plain.mm in Sources */ = {isa = PBXBuildFile; fileRef = 72327B084AD0454E92716875 /* Plain.mm */; };
added: F27FAA5682EF4239A600E77C /* Plain.mm in Sources */,
removed: nothing names Plain.mm
== added by xcode@4.0.0, removed by master
added: F6903D0DF1184805B24735FB /* Plain.mm in Resources */ = {isa = PBXBuildFile; fileRef = 6B24BFC6BB1E4C748A7A0220 /* Plain.mm */; };
added: F6903D0DF1184805B24735FB /* Plain.mm in Resources */,
removed: F6903D0DF1184805B24735FB /* Plain.mm in Resources */, <- F6903D0DF1184805B24735FB is defined nowhere
The uuids are random, so they differ from run to run. Node 26.12.1 on Windows 11; xcode from master at 354a163. What Xcode does with the leftover entry I haven't checked.
Reading
lib/pbxProject.js at 354a163: removeSourceFile calls removeFromPbxBuildFileSection, which deletes every PBXBuildFile whose fileRef_comment is the file's basename and records its uuid on file.uuid, then removeFromPbxSourcesBuildPhase, which splices the first entry whose comment === longComment(file). Matching the entry by the uuid removeFromPbxBuildFileSection just found would remove it whatever its comment says. removeFromPbxResourcesBuildPhase, removeFromPbxFrameworksBuildPhase, removeFromPbxCopyfilesBuildPhase and removeFromPbxEmbedFrameworksBuildPhase match by longComment the same way.
Activity
breautek commentedon Nov 6, 2026
If I understand correctly, sources that was added pre #199 were sources that was not mapped, so they defaulted to the Resource Group.
Post #199 attempting to remove these sources attempt to remove them from the Sources group and because these extensions are now properly mapped to the Sources group it will not find the file reference to remove, as the actual file reference is in the Resources group.
YevheniiKotyrlo commentedon Nov 6, 2026
Yes, except that the file reference is found and removed, and so is its
PBXBuildFile. What it misses is the file's entry in the Sources build phase: 4.0.0 added it there with the commentPlain.mm in Resources, and since #199removeSourceFilelooks forPlain.mm in Sources, so the entry stays, pointing at aPBXBuildFilethat no longer exists.