Skip to content

Commit fc3a281

Browse files
fix: prepare xcconfig files for all conigurations
Currently CLI merges and prepares xcconfig files only for the current build configuration, i.e. debug or release. However, the `pod install` command works with both configurations. This leads to problem when some property is set in the project's (plugin's) build.xcconfig file as CLI will prepare the native iOS project only for one configuration. When `pod install` is executed, if the Pods project uses the property set in the build.xcconfig file, it will fail with error, as the value for debug and release will be different (i.e. it will be set only for one of them). Pods project does not support this behavior, so the build operation fails. So, ensure CLI merges all xcconfig files for both debug and release configurations. This way, the Pods project will be in sync, so it should continue its execution. This is important when using Cocoapods 1.6.0+ where some changes are applied for Swift support, which can be workarounded by setting SWIFT_VERSION in project's build.xcconfig file.
1 parent 85843c6 commit fc3a281

File tree

5 files changed

+75
-60
lines changed

5 files changed

+75
-60
lines changed

lib/declarations.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ interface IXcconfigService {
895895
* @param opts
896896
* @returns {string}
897897
*/
898-
getPluginsXcconfigFilePath(projectRoot: string, opts: IRelease): string;
898+
getPluginsXcconfigFilePaths(projectRoot: string): IStringDictionary;
899899

900900
/**
901901
* Returns the value of a property from a xcconfig file.

lib/services/cocoapods-service.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,16 @@ export class CocoaPodsService implements ICocoaPodsService {
5555
return podInstallResult;
5656
}
5757

58-
public async mergePodXcconfigFile(projectData: IProjectData, platformData: IPlatformData, opts: IRelease) {
58+
public async mergePodXcconfigFile(projectData: IProjectData, platformData: IPlatformData) {
5959
const podFilesRootDirName = path.join("Pods", "Target Support Files", `Pods-${projectData.projectName}`);
6060
const podFolder = path.join(platformData.projectRoot, podFilesRootDirName);
6161
if (this.$fs.exists(podFolder)) {
62-
const podXcconfigFilePath = opts && opts.release ? path.join(podFolder, `Pods-${projectData.projectName}.release.xcconfig`)
63-
: path.join(podFolder, `Pods-${projectData.projectName}.debug.xcconfig`);
64-
const pluginsXcconfigFilePath = this.$xcconfigService.getPluginsXcconfigFilePath(platformData.projectRoot, opts);
65-
await this.$xcconfigService.mergeFiles(podXcconfigFilePath, pluginsXcconfigFilePath);
62+
const pluginsXcconfigFilePaths = this.$xcconfigService.getPluginsXcconfigFilePaths(platformData.projectRoot);
63+
for (const configuration in pluginsXcconfigFilePaths) {
64+
const pluginsXcconfigFilePath = pluginsXcconfigFilePaths[configuration];
65+
const podXcconfigFilePath = path.join(podFolder, `Pods-${projectData.projectName}.${configuration}.xcconfig`);
66+
await this.$xcconfigService.mergeFiles(podXcconfigFilePath, pluginsXcconfigFilePath);
67+
}
6668
}
6769
}
6870

lib/services/ios-project-service.ts

+32-21
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
799799
public async processConfigurationFilesFromAppResources(projectData: IProjectData, opts: IRelease): Promise<void> {
800800
await this.mergeInfoPlists(projectData, opts);
801801
await this.$iOSEntitlementsService.merge(projectData);
802-
await this.mergeProjectXcconfigFiles(projectData, opts);
802+
await this.mergeProjectXcconfigFiles(projectData);
803803
for (const pluginData of await this.getAllInstalledPlugins(projectData)) {
804804
await this.$pluginVariablesService.interpolatePluginVariables(pluginData, this.getPlatformData(projectData).configurationFilePath, projectData.projectDir);
805805
}
@@ -1216,43 +1216,54 @@ We will now place an empty obsolete compatability white screen LauncScreen.xib f
12161216
this.$fs.writeFile(path.join(headersFolderPath, "module.modulemap"), modulemap);
12171217
}
12181218

1219-
private async mergeProjectXcconfigFiles(projectData: IProjectData, opts: IRelease): Promise<void> {
1219+
private async mergeProjectXcconfigFiles(projectData: IProjectData): Promise<void> {
12201220
const platformData = this.getPlatformData(projectData);
1221-
const pluginsXcconfigFilePath = this.$xcconfigService.getPluginsXcconfigFilePath(platformData.projectRoot, opts);
1222-
this.$fs.deleteFile(pluginsXcconfigFilePath);
1221+
const pluginsXcconfigFilePaths = _.values(this.$xcconfigService.getPluginsXcconfigFilePaths(platformData.projectRoot));
1222+
1223+
for (const pluginsXcconfigFilePath of pluginsXcconfigFilePaths) {
1224+
this.$fs.deleteFile(pluginsXcconfigFilePath);
1225+
}
12231226

12241227
const pluginsService = <IPluginsService>this.$injector.resolve("pluginsService");
12251228
const allPlugins: IPluginData[] = await pluginsService.getAllInstalledPlugins(projectData);
12261229
for (const plugin of allPlugins) {
12271230
const pluginPlatformsFolderPath = plugin.pluginPlatformsFolderPath(IOSProjectService.IOS_PLATFORM_NAME);
12281231
const pluginXcconfigFilePath = path.join(pluginPlatformsFolderPath, BUILD_XCCONFIG_FILE_NAME);
12291232
if (this.$fs.exists(pluginXcconfigFilePath)) {
1230-
await this.$xcconfigService.mergeFiles(pluginXcconfigFilePath, pluginsXcconfigFilePath);
1233+
for (const pluginsXcconfigFilePath of pluginsXcconfigFilePaths) {
1234+
await this.$xcconfigService.mergeFiles(pluginXcconfigFilePath, pluginsXcconfigFilePath);
1235+
}
12311236
}
12321237
}
12331238

12341239
const appResourcesXcconfigPath = path.join(projectData.appResourcesDirectoryPath, this.getPlatformData(projectData).normalizedPlatformName, BUILD_XCCONFIG_FILE_NAME);
12351240
if (this.$fs.exists(appResourcesXcconfigPath)) {
1236-
await this.$xcconfigService.mergeFiles(appResourcesXcconfigPath, pluginsXcconfigFilePath);
1241+
for (const pluginsXcconfigFilePath of pluginsXcconfigFilePaths) {
1242+
await this.$xcconfigService.mergeFiles(appResourcesXcconfigPath, pluginsXcconfigFilePath);
1243+
}
12371244
}
12381245

1239-
if (!this.$fs.exists(pluginsXcconfigFilePath)) {
1240-
// We need the pluginsXcconfig file to exist in platforms dir as it is required in the native template:
1241-
// https://github.com/NativeScript/ios-runtime/blob/9c2b7b5f70b9bee8452b7a24aa6b646214c7d2be/build/project-template/__PROJECT_NAME__/build-debug.xcconfig#L3
1242-
// From Xcode 10 in case the file is missing, this include fails and the build itself fails (was a warning in previous Xcode versions).
1243-
this.$fs.writeFile(pluginsXcconfigFilePath, "");
1246+
for (const pluginsXcconfigFilePath of pluginsXcconfigFilePaths) {
1247+
if (!this.$fs.exists(pluginsXcconfigFilePath)) {
1248+
// We need the pluginsXcconfig file to exist in platforms dir as it is required in the native template:
1249+
// https://github.com/NativeScript/ios-runtime/blob/9c2b7b5f70b9bee8452b7a24aa6b646214c7d2be/build/project-template/__PROJECT_NAME__/build-debug.xcconfig#L3
1250+
// From Xcode 10 in case the file is missing, this include fails and the build itself fails (was a warning in previous Xcode versions).
1251+
this.$fs.writeFile(pluginsXcconfigFilePath, "");
1252+
}
12441253
}
12451254

1246-
// Set Entitlements Property to point to default file if not set explicitly by the user.
1247-
const entitlementsPropertyValue = this.$xcconfigService.readPropertyValue(pluginsXcconfigFilePath, constants.CODE_SIGN_ENTITLEMENTS);
1248-
if (entitlementsPropertyValue === null && this.$fs.exists(this.$iOSEntitlementsService.getPlatformsEntitlementsPath(projectData))) {
1249-
temp.track();
1250-
const tempEntitlementsDir = temp.mkdirSync("entitlements");
1251-
const tempEntitlementsFilePath = path.join(tempEntitlementsDir, "set-entitlements.xcconfig");
1252-
const entitlementsRelativePath = this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(projectData);
1253-
this.$fs.writeFile(tempEntitlementsFilePath, `CODE_SIGN_ENTITLEMENTS = ${entitlementsRelativePath}${EOL}`);
1254-
1255-
await this.$xcconfigService.mergeFiles(tempEntitlementsFilePath, pluginsXcconfigFilePath);
1255+
for (const pluginsXcconfigFilePath of pluginsXcconfigFilePaths) {
1256+
// Set Entitlements Property to point to default file if not set explicitly by the user.
1257+
const entitlementsPropertyValue = this.$xcconfigService.readPropertyValue(pluginsXcconfigFilePath, constants.CODE_SIGN_ENTITLEMENTS);
1258+
if (entitlementsPropertyValue === null && this.$fs.exists(this.$iOSEntitlementsService.getPlatformsEntitlementsPath(projectData))) {
1259+
temp.track();
1260+
const tempEntitlementsDir = temp.mkdirSync("entitlements");
1261+
const tempEntitlementsFilePath = path.join(tempEntitlementsDir, "set-entitlements.xcconfig");
1262+
const entitlementsRelativePath = this.$iOSEntitlementsService.getPlatformsEntitlementsRelativePath(projectData);
1263+
this.$fs.writeFile(tempEntitlementsFilePath, `CODE_SIGN_ENTITLEMENTS = ${entitlementsRelativePath}${EOL}`);
1264+
1265+
await this.$xcconfigService.mergeFiles(tempEntitlementsFilePath, pluginsXcconfigFilePath);
1266+
}
12561267
}
12571268
}
12581269

lib/services/xcconfig-service.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import * as path from "path";
2+
import { Configurations } from "../common/constants";
23

34
export class XcconfigService implements IXcconfigService {
45
constructor(
56
private $childProcess: IChildProcess,
67
private $fs: IFileSystem,
78
private $xcprojService: IXcprojService) { }
89

9-
public getPluginsXcconfigFilePath(projectRoot: string, opts: IRelease): string {
10-
if (opts && opts.release) {
11-
return this.getPluginsReleaseXcconfigFilePath(projectRoot);
12-
}
13-
14-
return this.getPluginsDebugXcconfigFilePath(projectRoot);
10+
public getPluginsXcconfigFilePaths(projectRoot: string): IStringDictionary {
11+
return {
12+
[Configurations.Debug.toLowerCase()]: this.getPluginsDebugXcconfigFilePath(projectRoot),
13+
[Configurations.Debug.toLowerCase()]: this.getPluginsReleaseXcconfigFilePath(projectRoot)
14+
};
1515
}
1616

1717
private getPluginsDebugXcconfigFilePath(projectRoot: string): string {

test/ios-project-service.ts

+29-27
Original file line numberDiff line numberDiff line change
@@ -1178,17 +1178,19 @@ describe("Merge Project XCConfig files", () => {
11781178

11791179
// run merge for all release: debug|release
11801180
for (const release in [true, false]) {
1181-
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData, { release });
1181+
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData);
11821182

1183-
const destinationFilePath = xcconfigService.getPluginsXcconfigFilePath(projectRoot, { release: !!release });
1183+
const destinationFilePaths = xcconfigService.getPluginsXcconfigFilePaths(projectRoot);
11841184

1185-
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1186-
const expected = {
1187-
'ASSETCATALOG_COMPILER_APPICON_NAME': 'AppIcon',
1188-
'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME': 'LaunchImage',
1189-
'CODE_SIGN_IDENTITY': 'iPhone Distribution'
1190-
};
1191-
assertPropertyValues(expected, destinationFilePath, testInjector);
1185+
_.each(destinationFilePaths, destinationFilePath => {
1186+
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1187+
const expected = {
1188+
'ASSETCATALOG_COMPILER_APPICON_NAME': 'AppIcon',
1189+
'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME': 'LaunchImage',
1190+
'CODE_SIGN_IDENTITY': 'iPhone Distribution'
1191+
};
1192+
assertPropertyValues(expected, destinationFilePath, testInjector);
1193+
});
11921194
}
11931195
});
11941196

@@ -1206,13 +1208,15 @@ describe("Merge Project XCConfig files", () => {
12061208

12071209
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData, { release });
12081210

1209-
const destinationFilePath = xcconfigService.getPluginsXcconfigFilePath(projectRoot, { release: !!release });
1211+
const destinationFilePaths = xcconfigService.getPluginsXcconfigFilePaths(projectRoot);
12101212

1211-
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1212-
const expected = {
1213-
'CODE_SIGN_ENTITLEMENTS': iOSEntitlementsService.getPlatformsEntitlementsRelativePath(projectData)
1214-
};
1215-
assertPropertyValues(expected, destinationFilePath, testInjector);
1213+
_.each(destinationFilePaths, destinationFilePath => {
1214+
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1215+
const expected = {
1216+
'CODE_SIGN_ENTITLEMENTS': iOSEntitlementsService.getPlatformsEntitlementsRelativePath(projectData)
1217+
};
1218+
assertPropertyValues(expected, destinationFilePath, testInjector);
1219+
});
12161220
}
12171221
});
12181222

@@ -1222,34 +1226,32 @@ describe("Merge Project XCConfig files", () => {
12221226
const xcconfigEntitlements = appResourceXCConfigContent + `${EOL}CODE_SIGN_ENTITLEMENTS = ${expectedEntitlementsFile}`;
12231227
fs.writeFile(appResourcesXcconfigPath, xcconfigEntitlements);
12241228

1225-
// run merge for all release: debug|release
1226-
for (const release in [true, false]) {
1227-
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData, { release });
1229+
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData);
12281230

1229-
const destinationFilePath = xcconfigService.getPluginsXcconfigFilePath(projectRoot, { release: !!release });
1231+
const destinationFilePaths = xcconfigService.getPluginsXcconfigFilePaths(projectRoot);
12301232

1231-
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1233+
_.each(destinationFilePaths, destinationFilePath => {
1234+
assert.isTrue(fs.exists(destinationFilePath), `Target build xcconfig ${destinationFilePath} is missing.`);
12321235
const expected = {
12331236
'ASSETCATALOG_COMPILER_APPICON_NAME': 'AppIcon',
12341237
'ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME': 'LaunchImage',
12351238
'CODE_SIGN_IDENTITY': 'iPhone Distribution',
12361239
'CODE_SIGN_ENTITLEMENTS': expectedEntitlementsFile
12371240
};
12381241
assertPropertyValues(expected, destinationFilePath, testInjector);
1239-
}
1242+
});
12401243
});
12411244

12421245
it("creates empty plugins-<config>.xcconfig in case there are no build.xcconfig in App_Resources and in plugins", async () => {
1243-
// run merge for all release: debug|release
1244-
for (const release in [true, false]) {
1245-
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData, { release });
1246+
await (<any>iOSProjectService).mergeProjectXcconfigFiles(projectData);
12461247

1247-
const destinationFilePath = xcconfigService.getPluginsXcconfigFilePath(projectRoot, { release: !!release });
1248+
const destinationFilePaths = xcconfigService.getPluginsXcconfigFilePaths(projectRoot);
12481249

1249-
assert.isTrue(fs.exists(destinationFilePath), 'Target build xcconfig is missing for release: ' + release);
1250+
_.each(destinationFilePaths, destinationFilePath => {
1251+
assert.isTrue(fs.exists(destinationFilePath), `Target build xcconfig ${destinationFilePath} is missing.` );
12501252
const content = fs.readFile(destinationFilePath).toString();
12511253
assert.equal(content, "");
1252-
}
1254+
});
12531255
});
12541256
});
12551257

0 commit comments

Comments
 (0)