Embedding a system extension based on xcconfig variables

I have a host app embedding a system extension and a setup in which the bundle identifier for both is defined by expanding a variable defined in an .xcconfig file. However, when I use different configurations with different configuration files, the "Embed System Extension" step in the build phases of the host app target does not seem to get updated and tries to copy a file with a constant name, regardless of which configuration is used.

How can I embed a system extension whose bundle identifier is expanded from an .xcconfig build variable?


Steps to reproduce

  1. Create a new xcode project (with development team "None") and add a system extension to be embedded. I am using a network extension.
  2. Add configuration files configA.xcconfig and configB.xcconfig setting the variable BUNDLE_ID to com.example.a and com.example.b respectively.
  3. Duplicate the Debug configuration under Project > Info, name them DebugA and DebugB, and set them up to use the configA and configB files for the whole project.
  4. Create two schemes SchemeA and SchemeB for the main target and set them up to run the DebugA and DebugB configurations under "Run".
  5. In the build settings, set the bundle identifier of the host app to $(BUNDLE_ID) and the bundle identifier of the extension to $(BUNDLE_ID).Extension

When I do this, SchemeA will run successfully while SchemeB fails building. Looking at the build log I can see that it successfully builds the com.example.b.Extension.systemextension product file but when it gets to embedding the system extension in the host app using PBXCp it tries to copy a file with the wrong name based on the bundle id value of the other configuration, hence

error: /Users/username/Library/Developer/Xcode/DerivedData/EmbedSysExt-caqirriqcwynzmdqqzniwgvzhziq/Build/Products/DebugB/com.example.a.Extension.systemextension: No such file or directory (in target 'ProjectName' from project 'ProjectName')

I am happy to provide a minimal example xcode project created using the steps above, however I am not sure how to make it available.


Some investigation

One way around this (which would be ok in my case) would be to give the system extension a constant product name in the build settings, regardless of configuration. Then the file to be copied has a fixed name so PBXCp will always copy the right thing. However, a system extension won't activate if this product name is different from the bundle id, as e.g. reported here: https://developer.apple.com/forums/thread/133499?answerId=421984022#421984022 I think it would be possible to use a constant product name and add a run script phase that will rename the folder after it has been copied. I would consider that quite hacky.

Searching for com.example.a in files on disk I can see that the bundle identifier is repeated literally (i.e. not using $(BUNDLE_ID)) inside the project.pbxproj file. Changing it manually in that file, however, does not seem to have any effect.

Cleaning the build folder and/or closing and restarting xcode didn't seem to have any effect.

I now noticed that this issue also occurs independent of using xcconfig-defined variables. Skipping step two in the "Steps to reproduce" and using hardcoded (but different) bundle identifiers for the two configurations in step five will show the same behavior.

On the other hand, if you use only a single configuration setting the bundle identifier to $(BUNDLE_ID) then the first build after changing the value of BUNDLE_ID in the xcconfig file will always fail as above, trying to copy the old bundle id - so this isn't only a matter of using different configurations either.

Embedding a system extension based on xcconfig variables
 
 
Q