From 9f238a9b0e8994ce98b40064e1c369ef3ac8d9bc Mon Sep 17 00:00:00 2001 From: Rui Moreira Mendes Date: Wed, 29 Apr 2026 12:38:37 +0100 Subject: [PATCH 1/4] fix: add cSettings support for compiler flags in generated Package.swift --- cli/src/ios/update.ts | 44 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 14bab0da6..8ceb67751 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -98,6 +98,9 @@ async function generateCordovaPackageFile(p: Plugin, config: Config) { ); await writeFile(packageSwiftPath, content); } else { + const sourceFiles = getPlatformElement(p, platform, 'source-file'); + const cSettingsText = buildCSettingsText(sourceFiles); + const content = `// swift-tools-version: 5.9 import PackageDescription @@ -120,7 +123,7 @@ let package = Package( dependencies: [ .product(name: "Cordova", package: "capacitor-swift-pm") ], - path: "."${headersText} + path: "."${headersText}${cSettingsText} ) ] )`; @@ -129,6 +132,45 @@ let package = Package( } } +function buildCSettingsText(sourceFiles: any[]): string { + const allFlags = new Set(); + for (const sourceFile of sourceFiles) { + const flags = sourceFile.$?.['compiler-flags']; + if (flags) { + flags + .split(/\s+/) + .map((f: string) => f.trim()) + .filter((f: string) => f.length > 0) + .forEach((f: string) => allFlags.add(f)); + } + } + + if (allFlags.size === 0) { + return ''; + } + + const entries: string[] = []; + + for (const flag of allFlags) { + if (flag.startsWith('-D')) { + const definition = flag.slice(2); + const eqIndex = definition.indexOf('='); + if (eqIndex !== -1) { + const name = definition.slice(0, eqIndex); + const value = definition.slice(eqIndex + 1); + entries.push(` .define("${name}", to: "${value}")`); + } else { + entries.push(` .define("${definition}")`); + } + } + } + + return `, + cSettings: [ +${entries.join(',\n')} + ]`; +} + export async function installCocoaPodsPlugins(config: Config, plugins: Plugin[], deployment: boolean): Promise { await runTask(`Updating iOS native dependencies with ${c.input(`${await config.ios.podPath} install`)}`, () => { return updatePodfile(config, plugins, deployment); From b105c14f313e846f64e57eb66dec8c5a0e557d43 Mon Sep 17 00:00:00 2001 From: Rui Moreira Mendes Date: Thu, 30 Apr 2026 15:38:26 +0100 Subject: [PATCH 2/4] warn when unsupported compiler flags are found in plugin.xml and not added to Package.swift --- cli/src/ios/update.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 8ceb67751..f46fac94f 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -99,7 +99,7 @@ async function generateCordovaPackageFile(p: Plugin, config: Config) { await writeFile(packageSwiftPath, content); } else { const sourceFiles = getPlatformElement(p, platform, 'source-file'); - const cSettingsText = buildCSettingsText(sourceFiles); + const cSettingsText = buildCSettingsText(p, sourceFiles); const content = `// swift-tools-version: 5.9 @@ -132,7 +132,8 @@ let package = Package( } } -function buildCSettingsText(sourceFiles: any[]): string { +function buildCSettingsText(p: Plugin, sourceFiles: any[]): string { + const pluginId = p.id; const allFlags = new Set(); for (const sourceFile of sourceFiles) { const flags = sourceFile.$?.['compiler-flags']; @@ -150,6 +151,7 @@ function buildCSettingsText(sourceFiles: any[]): string { } const entries: string[] = []; + const unsupportedFlags: string[] = []; for (const flag of allFlags) { if (flag.startsWith('-D')) { @@ -162,9 +164,18 @@ function buildCSettingsText(sourceFiles: any[]): string { } else { entries.push(` .define("${definition}")`); } + } else { + unsupportedFlags.push(flag); } } + if (unsupportedFlags.length > 0) { + logger.warn( + `${pluginId}: the following compiler flags are not supported in SPM and were ignored: ${unsupportedFlags.join(', ')}. ` + + `This may cause the plugin to fail to compile.`, + ); + } + return `, cSettings: [ ${entries.join(',\n')} From e380d507583a936f9439d3d8955e6c4d6225bdda Mon Sep 17 00:00:00 2001 From: Rui Moreira Mendes Date: Thu, 30 Apr 2026 16:15:59 +0100 Subject: [PATCH 3/4] move buildCSettingsText call inside writeGeneratedPackageSwift --- cli/src/ios/update.ts | 72 ++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index f46fac94f..15153354c 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -98,37 +98,7 @@ async function generateCordovaPackageFile(p: Plugin, config: Config) { ); await writeFile(packageSwiftPath, content); } else { - const sourceFiles = getPlatformElement(p, platform, 'source-file'); - const cSettingsText = buildCSettingsText(p, sourceFiles); - - const content = `// swift-tools-version: 5.9 - -import PackageDescription - -let package = Package( - name: "${p.name}", - platforms: [.iOS(.v${iosVersion})], - products: [ - .library( - name: "${p.name}", - targets: ["${p.name}"] - ) - ], - dependencies: [ - .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "${iosPlatformVersion}") - ], - targets: [ - .target( - name: "${p.name}", - dependencies: [ - .product(name: "Cordova", package: "capacitor-swift-pm") - ], - path: "."${headersText}${cSettingsText} - ) - ] -)`; - - await writeFile(join(config.ios.cordovaPluginsDirAbs, 'sources', p.name, 'Package.swift'), content); + await writeGeneratedPackageSwift(p, config, iosVersion, iosPlatformVersion, headersText); } } @@ -182,6 +152,46 @@ ${entries.join(',\n')} ]`; } +async function writeGeneratedPackageSwift( + p: Plugin, + config: Config, + iosVersion: string, + iosPlatformVersion: string, + headersText: string, +) { + const sourceFiles = getPlatformElement(p, platform, 'source-file'); + const cSettingsText = buildCSettingsText(p, sourceFiles); + + const content = `// swift-tools-version: 5.9 + +import PackageDescription + +let package = Package( + name: "${p.name}", + platforms: [.iOS(.v${iosVersion})], + products: [ + .library( + name: "${p.name}", + targets: ["${p.name}"] + ) + ], + dependencies: [ + .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "${iosPlatformVersion}") + ], + targets: [ + .target( + name: "${p.name}", + dependencies: [ + .product(name: "Cordova", package: "capacitor-swift-pm") + ], + path: "."${headersText}${cSettingsText} + ) + ] +)`; + + await writeFile(join(config.ios.cordovaPluginsDirAbs, 'sources', p.name, 'Package.swift'), content); +} + export async function installCocoaPodsPlugins(config: Config, plugins: Plugin[], deployment: boolean): Promise { await runTask(`Updating iOS native dependencies with ${c.input(`${await config.ios.podPath} install`)}`, () => { return updatePodfile(config, plugins, deployment); From f4e7a9ef264d0206a2455e9abd774d2b3c955b0e Mon Sep 17 00:00:00 2001 From: Rui Moreira Mendes Date: Thu, 30 Apr 2026 17:37:22 +0100 Subject: [PATCH 4/4] address PR review comments on compiler flags SPM support --- cli/src/ios/update.ts | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/cli/src/ios/update.ts b/cli/src/ios/update.ts index 15153354c..551198039 100644 --- a/cli/src/ios/update.ts +++ b/cli/src/ios/update.ts @@ -77,13 +77,6 @@ async function generateCordovaPackageFiles(cordovaPlugins: Plugin[], config: Con async function generateCordovaPackageFile(p: Plugin, config: Config) { const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name); - const iosVersion = getMajoriOSVersion(config); - const headerFiles = getPlatformElement(p, platform, 'header-file'); - let headersText = ''; - if (headerFiles.length > 0) { - headersText = `, - publicHeadersPath: "."`; - } const platformTag = getPluginPlatform(p, platform); if (platformTag.$?.package) { @@ -98,7 +91,7 @@ async function generateCordovaPackageFile(p: Plugin, config: Config) { ); await writeFile(packageSwiftPath, content); } else { - await writeGeneratedPackageSwift(p, config, iosVersion, iosPlatformVersion, headersText); + await writeGeneratedPackageSwift(p, config, iosPlatformVersion); } } @@ -142,23 +135,28 @@ function buildCSettingsText(p: Plugin, sourceFiles: any[]): string { if (unsupportedFlags.length > 0) { logger.warn( `${pluginId}: the following compiler flags are not supported in SPM and were ignored: ${unsupportedFlags.join(', ')}. ` + - `This may cause the plugin to fail to compile.`, + `This might cause the plugin to fail to compile.`, ); } + if (entries.length === 0) { + return ''; + } + return `, cSettings: [ ${entries.join(',\n')} ]`; } -async function writeGeneratedPackageSwift( - p: Plugin, - config: Config, - iosVersion: string, - iosPlatformVersion: string, - headersText: string, -) { +async function writeGeneratedPackageSwift(p: Plugin, config: Config, iosPlatformVersion: string) { + const iosVersion = getMajoriOSVersion(config); + const headerFiles = getPlatformElement(p, platform, 'header-file'); + const headersText = + headerFiles.length > 0 + ? `, + publicHeadersPath: "."` + : ''; const sourceFiles = getPlatformElement(p, platform, 'source-file'); const cSettingsText = buildCSettingsText(p, sourceFiles); @@ -467,6 +465,7 @@ function getLinkerFlags(config: Config) { } async function copyPluginsNativeFiles(config: Config, cordovaPlugins: Plugin[]) { + const isSPM = (await config.ios.packageManager) === 'SPM'; for (const p of cordovaPlugins) { const platformTag = getPluginPlatform(p, platform); if (platformTag.$?.package) { @@ -477,7 +476,7 @@ async function copyPluginsNativeFiles(config: Config, cordovaPlugins: Plugin[]) const codeFiles = sourceFiles.concat(headerFiles); const frameworks = getPlatformElement(p, platform, 'framework'); let sourcesFolderName = 'sources'; - if ((await config.ios.packageManager) !== 'SPM' && needsStaticPod(p)) { + if (!isSPM && needsStaticPod(p)) { sourcesFolderName += 'static'; } const sourcesFolder = join(config.ios.cordovaPluginsDirAbs, sourcesFolderName, p.name); @@ -488,7 +487,7 @@ async function copyPluginsNativeFiles(config: Config, cordovaPlugins: Plugin[]) fileName = 'lib' + fileName; } let destFolder = sourcesFolderName; - if (codeFile.$['compiler-flags'] && codeFile.$['compiler-flags'] === '-fno-objc-arc') { + if (!isSPM && codeFile.$['compiler-flags'] && codeFile.$['compiler-flags'] === '-fno-objc-arc') { destFolder = 'noarc'; } const filePath = getFilePath(config, p, codeFile.$.src);