Skip to content

Commit 97af51f

Browse files
committed
fix: set the cmake generator platform for cross-compile
1 parent e13d197 commit 97af51f

File tree

4 files changed

+81
-68
lines changed

4 files changed

+81
-68
lines changed

src/argumentBuilder.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ export class ArgumentBuilder {
117117
const targetArch = getMsvcArch(this.config.arch)
118118
const msvcArch = hostArch === targetArch ? hostArch : `${hostArch}_${targetArch}`
119119
setupMSVCDevCmd(msvcArch)
120+
121+
// set the CMake generator platform to the target architecture
122+
retVal.push(["CMAKE_GENERATOR_PLATFORM", cmakeArch])
120123
}
121124
}
122125

src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { join, resolve } from "path"
22
import { readJson } from "fs-extra"
33
import which from "which"
4-
import { getCmakeGenerator } from "./util.js"
4+
import { getCmakeGenerator } from "./generator.js"
55

66
/**
77
* The options of cmake-ts that includes the command to run and the global options
@@ -335,7 +335,7 @@ async function addMissingBuildConfigurationFields(
335335

336336
config.cmakeToUse ??= globalConfig.cmakeToUse ?? (await which("cmake", { nothrow: true })) ?? "cmake"
337337

338-
const { generator, binary } = await getCmakeGenerator(config.cmakeToUse, process.arch)
338+
const { generator, binary } = await getCmakeGenerator(config.cmakeToUse, config.arch)
339339
config.generatorToUse ??= globalConfig.generatorToUse ?? generator
340340
config.generatorBinary ??= globalConfig.generatorBinary ?? binary
341341

src/generator.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import which from "which"
2+
import { logger } from "./logger.js"
3+
import { execCapture } from "./util.js"
4+
5+
export async function getCmakeGenerator(
6+
cmake: string,
7+
arch: string,
8+
): Promise<{
9+
generator: string | undefined
10+
binary: string | undefined
11+
}> {
12+
// use ninja if available
13+
if (process.platform !== "win32") {
14+
const ninja = await which("ninja", { nothrow: true })
15+
if (ninja !== null) {
16+
return {
17+
generator: "Ninja",
18+
binary: ninja,
19+
}
20+
}
21+
}
22+
23+
// use the MSVC generator on Windows
24+
if (process.platform === "win32" && ["x64", "x86"].includes(arch)) {
25+
try {
26+
const archString = arch === "x64" ? "Win64" : arch === "x86" ? "" : <never>undefined
27+
28+
const generators = await execCapture(`"${cmake}" -G`)
29+
logger.debug(generators)
30+
const hasCR = generators.includes("\r\n")
31+
const output = hasCR ? generators.split("\r\n") : generators.split("\n")
32+
let found = false
33+
let useVSGen = ""
34+
35+
for (const line of output) {
36+
if (!found && line.trim() === "Generators") {
37+
found = true
38+
continue
39+
}
40+
const genParts = line.split("=")
41+
if (genParts.length <= 1) {
42+
// Some descriptions are multi-line
43+
continue
44+
}
45+
/** Current MSVS compiler selected in Windows generally is prefixed with "* " */
46+
genParts[0] = genParts[0].replace(/^(\* )/, "").trim()
47+
48+
// eslint-disable-next-line optimize-regex/optimize-regex
49+
if (genParts[0].match(/Visual\s+Studio\s+\d+\s+\d+(\s+\[arch\])?/)) {
50+
// The first entry is usually the latest entry
51+
useVSGen = genParts[0]
52+
break
53+
}
54+
}
55+
const useSwitch = !useVSGen.match(/.*\[arch]/)
56+
if (useSwitch) {
57+
useVSGen += " -A" // essentially using this as a flag
58+
} else {
59+
useVSGen = useVSGen.replace("[arch]", archString).trim()
60+
}
61+
logger.debug("Using generator: ", useVSGen)
62+
return {
63+
generator: useVSGen,
64+
binary: undefined,
65+
}
66+
} catch (e) {
67+
logger.warn("Failed to find valid VS gen, using native.")
68+
// fall back to native
69+
}
70+
}
71+
72+
return {
73+
generator: "native",
74+
binary: undefined,
75+
}
76+
}

src/util.ts

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import * as cp from "child_process"
22
import { type PathLike, type StatOptions, type Stats, type StatsBase, stat as rawStat } from "fs-extra"
33
import splitargs from "splitargs2"
4-
import which from "which"
5-
import { logger } from "./logger.js"
64

75
export function getEnvVar(name: string) {
86
const value = process.env[name]
@@ -12,70 +10,6 @@ export function getEnvVar(name: string) {
1210
return undefined
1311
}
1412

15-
export async function getCmakeGenerator(
16-
cmake: string,
17-
arch: string,
18-
): Promise<{
19-
generator: string | undefined
20-
binary: string | undefined
21-
}> {
22-
// use ninja if available
23-
const ninja = await which("ninja", { nothrow: true })
24-
if (ninja !== null) {
25-
return {
26-
generator: "Ninja",
27-
binary: ninja,
28-
}
29-
}
30-
31-
const archString = arch === "x64" ? "Win64" : arch === "x86" ? "" : null
32-
if (archString === null) {
33-
logger.error("Failed to find valid VS gen, using native. Good Luck.")
34-
return {
35-
generator: "native",
36-
binary: undefined,
37-
}
38-
}
39-
40-
const generators = await execCapture(`"${cmake}" -G`)
41-
const hasCR = generators.includes("\r\n")
42-
const output = hasCR ? generators.split("\r\n") : generators.split("\n")
43-
let found = false
44-
let useVSGen = ""
45-
46-
for (const line of output) {
47-
if (!found && line.trim() === "Generators") {
48-
found = true
49-
continue
50-
}
51-
const genParts = line.split("=")
52-
if (genParts.length <= 1) {
53-
// Some descriptions are multi-line
54-
continue
55-
}
56-
/** Current MSVS compiler selected in Windows generally is prefixed with "* " */
57-
genParts[0] = genParts[0].replace(/^(\* )/, "").trim()
58-
59-
// eslint-disable-next-line optimize-regex/optimize-regex
60-
if (genParts[0].match(/Visual\s+Studio\s+\d+\s+\d+(\s+\[arch\])?/)) {
61-
logger.debug("Found generator: ", genParts[0])
62-
// The first entry is usually the latest entry
63-
useVSGen = genParts[0]
64-
break
65-
}
66-
}
67-
const useSwitch = !useVSGen.match(/.*\[arch]/)
68-
if (useSwitch) {
69-
useVSGen += " -A" // essentially using this as a flag
70-
} else {
71-
useVSGen = useVSGen.replace("[arch]", archString).trim()
72-
}
73-
return {
74-
generator: useVSGen,
75-
binary: undefined,
76-
}
77-
}
78-
7913
export function execCapture(command: string): Promise<string> {
8014
return new Promise((resolve) => {
8115
cp.exec(command, (_, stdout, stderr) => {

0 commit comments

Comments
 (0)