Skip to content

Commit

Permalink
wip: more
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Apr 21, 2024
1 parent 03ba642 commit e50ebd6
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 99 deletions.
138 changes: 45 additions & 93 deletions bin/cmake-js2.mjs
Expand Up @@ -12,15 +12,27 @@ const packageJson = JSON.parse(packageJsonStr.toString())

function parseOptions(args) {
const config = args.config || 'Release'
const generator = args.generator
const sourceDir = (args.directory && path.resolve(args.directory)) || process.cwd()
const buildDir = path.join(
(args.out && (path.isAbsolute(args.out) ? args.out : path.join(sourceDir, path.resolve(args.out)))) ||
path.join(sourceDir, 'build'),
config,
)

const preferMake = !!args['prefer-make']
const preferXcode = !!args['prefer-xcode']

console.log('dirs', sourceDir, buildDir)
return { sourceDir, buildDir, config }
return {
sourceDir,
buildDir,
config,
generator,

preferMake,
preferXcode,
}
}

async function runCmake(args) {
Expand Down Expand Up @@ -61,7 +73,6 @@ async function runBuild(args) {
await buildSystem.ensureConfigured(args._.slice(1))
await buildSystem.build({
target: args.target,
config: options.config,
})
}

Expand All @@ -81,6 +92,19 @@ async function runListGenerators(args) {
console.log(generators.map((g) => ' - ' + g).join('\n'))
}

async function runSelectGenerators(args) {
const options = parseOptions(args)
const buildSystem = new BuildSystem(options)
const bestGenerator = await buildSystem.selectGeneratorAndPlatform(args)

if (!bestGenerator) {
console.error('No suitable generator found')
process.exit(1)
} else {
console.log(bestGenerator.generator + (bestGenerator.platform ? ' ' + bestGenerator.platform : ''))
}
}

const args = await yargs(hideBin(process.argv))
// .parserConfiguration({ // TODO - this would be nice to have
// 'unknown-options-as-args': true,
Expand All @@ -96,6 +120,7 @@ const args = await yargs(hideBin(process.argv))
// .command('rebuild', 'Clean the project directory then build the project')
// .command('compile', 'Build the project, and if build fails, try a full rebuild')
.command('list-generators', 'List available generators', {}, runListGenerators)
.command('select-generator', 'Select the best available generators', {}, runSelectGenerators)
.demandCommand()
.options({
// l: {
Expand All @@ -104,54 +129,30 @@ const args = await yargs(hideBin(process.argv))
// describe: 'set log level (' + logLevels.join(', ') + '), default is info',
// type: 'string',
// },
// D: {
// alias: 'debug',
// demand: false,
// describe: 'build debug configuration',
// type: 'boolean',
// },
config: {
// alias: 'B',
demand: false,
describe: "specify build configuration (Debug, RelWithDebInfo, Release), will ignore '--debug' if specified",
type: 'string',
},
// c: {
// alias: 'cmake-path',
// demand: false,
// describe: 'path of CMake executable',
// type: 'string',
// },
// m: {
// alias: 'prefer-make',
// demand: false,
// describe: 'use Unix Makefiles even if Ninja is available (Posix)',
// type: 'boolean',
// },
// x: {
// alias: 'prefer-xcode',
// demand: false,
// describe: 'use Xcode instead of Unix Makefiles',
// type: 'boolean',
// },
// g: {
// alias: 'prefer-gnu',
// demand: false,
// describe: 'use GNU compiler instead of default CMake compiler, if available (Posix)',
// type: 'boolean',
// },
// G: {
// alias: 'generator',
// demand: false,
// describe: 'use specified generator',
// type: 'string',
// },
// t: {
// alias: 'toolset',
// demand: false,
// describe: 'use specified toolset',
// type: 'string',
// },
'prefer-make': {
// alias: 'm',
demand: false,
describe: 'use Unix Makefiles generator even if Ninja is available (Posix)',
type: 'boolean',
},
'prefer-xcode': {
// alias: 'x',
demand: false,
describe: 'use Xcode generator instead of Unix Makefiles',
type: 'boolean',
},
generator: {
// alias: 'G',
demand: false,
describe: 'use specified generator',
type: 'string',
},
// A: {
// alias: 'platform',
// demand: false,
Expand All @@ -164,22 +165,6 @@ const args = await yargs(hideBin(process.argv))
describe: 'only build the specified target',
type: 'string',
},
// C: {
// alias: 'prefer-clang',
// demand: false,
// describe: 'use Clang compiler instead of default CMake compiler, if available (Posix)',
// type: 'boolean',
// },
// cc: {
// demand: false,
// describe: 'use the specified C compiler',
// type: 'string',
// },
// cxx: {
// demand: false,
// describe: 'use the specified C++ compiler',
// type: 'string',
// },
// a: {
// alias: 'arch',
// demand: false,
Expand Down Expand Up @@ -226,53 +211,20 @@ const args = await yargs(hideBin(process.argv))
// }
// }

// const yargs = require('yargs')
// .usage('CMake.js ' + version + '\n\nUsage: $0 [<command>] [options]')
// .version(version)
// const argv = yargs.argv

// // If help, then print and exit:

// if (argv.h) {
// console.info(yargs.help())
// process.exit(0)
// }

// // Setup log level:

// if (argv.l && logLevels.includes(argv.l)) {
// log.level = argv.l
// log.resume()
// }

// log.silly('CON', 'argv:')
// log.silly('CON', util.inspect(argv))

// log.verbose('CON', 'Parsing arguments')

// const options = {
// directory: argv.directory || null,
// debug: argv.debug,
// cmakePath: argv.c || null,
// generator: argv.G,
// toolset: argv.t,
// platform: argv.A,
// target: argv.T,
// preferMake: argv.m,
// preferXcode: argv.x,
// preferGnu: argv.g,
// preferClang: argv.C,
// cCompilerPath: argv.cc,
// cppCompilerPath: argv.cxx,
// arch: argv.a,
// silent: argv.i,
// out: argv.O,
// config: argv.B,
// }

// function clean() {
// exitOnError(buildSystem.clean())
// }
// function reconfigure() {
// exitOnError(buildSystem.reconfigure())
// }
Expand Down
15 changes: 15 additions & 0 deletions lib/import/find-visualstudio.d.ts
@@ -0,0 +1,15 @@
export interface FindVisualStudioResult {
version: string
versionMajor: number
versionMinor: number

path: string
msBuild: string
toolset: string
sdk: string
}

export function findVisualStudio(
nodeSemver: string,
configMsvsVersion: string | undefined,
): Promise<FindVisualStudioResult>
92 changes: 86 additions & 6 deletions rewrite/src/buildSystem.ts
@@ -1,11 +1,23 @@
import fs from 'fs/promises'
import path from 'path'
import os from 'os'
import { runCommand } from './processHelpers'
import { findCmake, getGenerators } from './toolchain'
import {
findCmake,
getGenerators,
getTopSupportedVisualStudioGenerator,
isMakeAvailable,
isNinjaAvailable,
} from './toolchain'

export interface BuildSystemOptions {
sourceDir: string
buildDir: string
config: string
generator: string | undefined

preferMake: boolean
preferXcode: boolean
}

export class BuildSystem {
Expand Down Expand Up @@ -33,6 +45,13 @@ export class BuildSystem {
async configure(args: string[]): Promise<void> {
const cmakePath = await this.findCmake()

const forcedArgs: string[] = []

const generator = this.#options.generator || (await this.selectGeneratorAndPlatform())?.generator
if (generator) {
forcedArgs.push('-G', generator)
}

// Make sure the project looks valid
const listPath = path.join(this.#options.sourceDir, 'CMakeLists.txt')
try {
Expand All @@ -48,7 +67,7 @@ export class BuildSystem {
// Ignore
}

await runCommand([cmakePath, this.#options.sourceDir, ...args], {
await runCommand([cmakePath, this.#options.sourceDir, ...forcedArgs, ...args], {
cwd: this.#options.buildDir,
})
}
Expand All @@ -68,21 +87,21 @@ export class BuildSystem {
}
}

async build(buildOptions: { config: string; target?: string }): Promise<void> {
async build(buildOptions: { target?: string }): Promise<void> {
if (!(await this.isConfigured())) {
throw new Error('Project not configured')
}

const cmakePath = await this.findCmake()

const buildCommand = [cmakePath, '--build', this.#options.buildDir, '--config', buildOptions.config]
const buildCommand = [cmakePath, '--build', this.#options.buildDir, '--config', this.#options.config]
if (buildOptions.target) {
buildCommand.push('--target', buildOptions.target)
}

// TODO --parallel should be driven from some environment variable
// if (this.options.parallel) {
// command.push('--parallel', this.options.parallel)
// if (this.#options.parallel) {
// command.push('--parallel', this.#options.parallel)
// }

console.log(buildCommand)
Expand All @@ -103,4 +122,65 @@ export class BuildSystem {
const cmakePath = await this.findCmake()
return getGenerators(cmakePath, null)
}

async selectGeneratorAndPlatform(): Promise<{ generator: string; platform: string | null } | null> {
if (os.platform() === 'win32') {
const targetArch: string = 'x64' // TODO

const cmakePath = await this.findCmake() // TODO - this should not be done here...
const foundVsInfo = await getTopSupportedVisualStudioGenerator(cmakePath, targetArch as any, null)

if (foundVsInfo) {
let platform: string | null = null
// The CMake Visual Studio Generator does not support the Win64 or ARM suffix on
// the generator name. Instead the generator platform must be set explicitly via
// the platform parameter
const isAboveVS16 = foundVsInfo.versionMajor >= 16
if (isAboveVS16) {
switch (targetArch) {
case 'ia32':
case 'x86':
platform = 'Win32'
break
case 'x64':
platform = 'x64'
break
case 'arm':
platform = 'ARM'
break
case 'arm64':
platform = 'ARM64'
break
default:
// TODO - log?
// this.log.warn('TOOL', 'Unknown NodeJS architecture: ' + this.targetOptions.arch)
break
}
}

return { generator: foundVsInfo.generator, platform }
} else {
// TODO: mysys/mingw
return null
}
} else if (os.platform() === 'darwin') {
if (this.#options.preferXcode) {
return { generator: 'Xcode', platform: null }
} else if (this.#options.preferMake && isMakeAvailable()) {
return { generator: 'Unix Makefiles', platform: null }
} else if (isNinjaAvailable()) {
return { generator: 'Ninja', platform: null }
} else {
return { generator: 'Unix Makefiles', platform: null }
}
} else {
if (this.#options.preferMake && isMakeAvailable()) {
return { generator: 'Unix Makefiles', platform: null }
} else if (isNinjaAvailable()) {
return { generator: 'Ninja', platform: null }
} else {
return { generator: 'Unix Makefiles', platform: null }
}
}
}
}

0 comments on commit e50ebd6

Please sign in to comment.