diff --git a/packages/gyp-to-cmake/src/gyp.test.ts b/packages/gyp-to-cmake/src/gyp.test.ts index e948937e..afaeafb8 100644 --- a/packages/gyp-to-cmake/src/gyp.test.ts +++ b/packages/gyp-to-cmake/src/gyp.test.ts @@ -81,4 +81,47 @@ describe("gyp.assertRoot", () => { }); }, /Expected all cflags to be strings/); }); + + it("should accept target ldflags", () => { + assert.doesNotThrow(() => { + assertBinding( + { + targets: [ + { + target_name: "addon", + sources: ["addon.cc"], + ldflags: ["-Wl,-dead_strip"], + }, + ], + }, + true, + ); + }); + }); + + it("should reject malformed target ldflags", () => { + assert.throws(() => { + assertBinding({ + targets: [ + { + target_name: "addon", + sources: ["addon.cc"], + ldflags: "-Wl,-dead_strip", + }, + ], + }); + }, /Expected 'ldflags' to be an array/); + + assert.throws(() => { + assertBinding({ + targets: [ + { + target_name: "addon", + sources: ["addon.cc"], + ldflags: ["-Wl,-dead_strip", 42], + }, + ], + }); + }, /Expected all ldflags to be strings/); + }); }); diff --git a/packages/gyp-to-cmake/src/gyp.ts b/packages/gyp-to-cmake/src/gyp.ts index 37f650f2..fec03789 100644 --- a/packages/gyp-to-cmake/src/gyp.ts +++ b/packages/gyp-to-cmake/src/gyp.ts @@ -9,6 +9,7 @@ export type GypTarget = { include_dirs?: string[]; defines?: string[]; cflags?: string[]; + ldflags?: string[]; }; export type GypBinding = { @@ -58,12 +59,21 @@ export function assertTarget( "Expected all cflags to be strings", ); } + if ("ldflags" in target) { + const { ldflags } = target; + assert(Array.isArray(ldflags), "Expected 'ldflags' to be an array"); + assert( + ldflags.every((flag) => typeof flag === "string"), + "Expected all ldflags to be strings", + ); + } if (disallowUnknownProperties) { assertNoExtraProperties(target, [ "target_name", "sources", "include_dirs", "cflags", + "ldflags", ]); } } diff --git a/packages/gyp-to-cmake/src/transformer.test.ts b/packages/gyp-to-cmake/src/transformer.test.ts index 2f20a50b..b86fc300 100644 --- a/packages/gyp-to-cmake/src/transformer.test.ts +++ b/packages/gyp-to-cmake/src/transformer.test.ts @@ -170,6 +170,52 @@ describe("bindingGypToCmakeLists", () => { }); }); + describe("ldflags", () => { + it("should add ldflags as target-specific link options", () => { + const output = bindingGypToCmakeLists({ + projectName: "some-project", + gyp: { + targets: [ + { + target_name: "foo", + sources: ["foo.cc"], + ldflags: ["-Wl,-dead_strip", "-framework CoreFoundation"], + }, + ], + }, + }); + + assert( + output.includes( + "target_link_options(foo PRIVATE -Wl,-dead_strip -framework\\ CoreFoundation)", + ), + `Expected output to include target_link_options:\n${output}`, + ); + }); + + it("should expand ldflags command output into link options", () => { + const output = bindingGypToCmakeLists({ + projectName: "some-project", + gyp: { + targets: [ + { + target_name: "foo", + sources: ["foo.cc"], + ldflags: [" { const gyp = { targets: [{ target_name: "addon", sources: ["addon.cc"] }], diff --git a/packages/gyp-to-cmake/src/transformer.ts b/packages/gyp-to-cmake/src/transformer.ts index d55643c8..4048337f 100644 --- a/packages/gyp-to-cmake/src/transformer.ts +++ b/packages/gyp-to-cmake/src/transformer.ts @@ -95,10 +95,14 @@ export function bindingGypToCmakeLists({ } for (const target of gyp.targets) { - const { target_name: targetName, defines = [], cflags = [] } = target; + const { + target_name: targetName, + defines = [], + cflags = [], + ldflags = [], + } = target; // TODO: Handle "conditions" - // TODO: Handle "ldflags" const escapedSources = target.sources .flatMap(mapExpansion) @@ -116,6 +120,7 @@ export function bindingGypToCmakeLists({ .map(escapeSpaces); const escapedCflags = cflags.flatMap(mapExpansion).map(escapeSpaces); + const escapedLdflags = ldflags.flatMap(mapExpansion).map(escapeSpaces); const libraries = []; if (weakNodeApi) { @@ -223,6 +228,12 @@ export function bindingGypToCmakeLists({ ); } + if (escapedLdflags.length > 0) { + lines.push( + `target_link_options(${actualTargetName} PRIVATE ${escapedLdflags.join(" ")})`, + ); + } + if (compileFeatures.length > 0) { lines.push( `target_compile_features(${actualTargetName} PRIVATE ${compileFeatures.join(" ")})`,