build/llvmPackages: support mathlib configuration / mcpuVariant
This commit is contained in:
@@ -5,8 +5,10 @@ import path from 'path';
|
||||
import { buildPackage } from '../build/build.js';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { arch } from 'os';
|
||||
import * as sunway from '../sunway.js';
|
||||
import chalk from 'chalk';
|
||||
|
||||
const args = await yargs(hideBin(process.argv))
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.version("0.0.0")
|
||||
.option("src", {
|
||||
describe: "Source directory to llvm-project",
|
||||
@@ -21,20 +23,31 @@ const args = await yargs(hideBin(process.argv))
|
||||
describe: "Install prefix",
|
||||
type: "string",
|
||||
})
|
||||
.option("msimd-math", {
|
||||
.option("math-simd", {
|
||||
describe: "Add -msimd for libpgmath",
|
||||
type: "boolean",
|
||||
demandOption: true,
|
||||
})
|
||||
.option('mcpu', {
|
||||
type: 'string',
|
||||
description: '-mcpu option for compilers',
|
||||
choices: ['8a', '6b', 'host'],
|
||||
default: 'host',
|
||||
})
|
||||
.help()
|
||||
.parse();
|
||||
|
||||
const src = path.resolve(args.src);
|
||||
const build = args.build ?? path.resolve(src, "build");
|
||||
const prefix = args.prefix ?? path.resolve(src, "install", randomUUID());
|
||||
const src = path.resolve(argv.src);
|
||||
const build = argv.build ?? path.resolve(src, "build");
|
||||
const prefix = argv.prefix ?? path.resolve(src, "install", randomUUID());
|
||||
|
||||
const cpuVariant = argv.mcpu === "host" ? sunway.getHostGeneration() : argv.platform as sunway.SunwayGeneration;
|
||||
|
||||
console.log(`prefix: ${chalk.red(prefix)}`);
|
||||
console.log(`mcpu: ${cpuVariant}`);
|
||||
|
||||
const packages = llvmPackages({
|
||||
src: args.src,
|
||||
src: argv.src,
|
||||
buildDir(packageName) {
|
||||
return path.join(build, packageName);
|
||||
},
|
||||
@@ -44,7 +57,8 @@ const packages = llvmPackages({
|
||||
buildPlatform: { arch: arch() },
|
||||
hostPlatform: { arch: arch() },
|
||||
},
|
||||
enableLibpgmathSIMD: args['msimd-math']
|
||||
mathSIMD: argv['math-simd'],
|
||||
cpuVariant,
|
||||
});
|
||||
|
||||
for (const pkg of packages) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import path from "path";
|
||||
import { GeneralVariable, LLVMVariable, command, variable } from "../commands/cmake.js";
|
||||
import { GeneralVariable, LLVMVariable, buildCompilerFlags, command, variable } from "../commands/cmake.js";
|
||||
import { PackagePlatform, PackageTask } from "./build.js";
|
||||
import { promisifySpawn } from "../cli.js";
|
||||
import os from "os";
|
||||
import { SpawnOptions, spawn } from "child_process";
|
||||
import * as sunway from '../sunway.js';
|
||||
|
||||
export interface LLVMPackageOverrides {
|
||||
cmakeDefinitionOverrides?: {
|
||||
@@ -60,7 +61,9 @@ export interface LLVMPackageOptions {
|
||||
|
||||
platform: PackagePlatform;
|
||||
|
||||
enableLibpgmathSIMD: boolean;
|
||||
mathSIMD: boolean;
|
||||
|
||||
cpuVariant: sunway.SunwayGeneration;
|
||||
};
|
||||
|
||||
export function llvmPackages({
|
||||
@@ -70,7 +73,8 @@ export function llvmPackages({
|
||||
buildDir,
|
||||
cmakeDefinitionOverrides,
|
||||
spawnOverrides,
|
||||
enableLibpgmathSIMD = false,
|
||||
mathSIMD,
|
||||
cpuVariant,
|
||||
}: LLVMPackageOptions & LLVMPackageOverrides): PackageTask[] {
|
||||
const rm = "rm";
|
||||
const cmake = "cmake";
|
||||
@@ -107,6 +111,16 @@ export function llvmPackages({
|
||||
await promisifySpawn(spawn(cmake, ["--build", build, "--target", "install"], spawnOptions));
|
||||
});
|
||||
|
||||
const mcpuFlag = sunway.mcpu(cpuVariant);
|
||||
|
||||
// Shared flags for compiling libpgmath & cflang.
|
||||
// The toolchain of these targets are clang.
|
||||
const clangCXFlags = [
|
||||
"-Wno-sign-compare",
|
||||
mcpuFlag,
|
||||
];
|
||||
|
||||
|
||||
function mkLLVMPackage(): PackageTask {
|
||||
const build = buildDir('llvm');
|
||||
return {
|
||||
@@ -139,18 +153,19 @@ export function llvmPackages({
|
||||
await promisifySpawn(spawn(rm, ["-rf", build], spawnOptions));
|
||||
|
||||
// Flags shared between C and C++ compiler.
|
||||
const cxFlags = ["-mlong-double-64"];
|
||||
if (enableLibpgmathSIMD) {
|
||||
cxFlags.push("-msimd");
|
||||
}
|
||||
const cxFlags = [
|
||||
...clangCXFlags,
|
||||
"-mlong-double-64",
|
||||
...mathSIMD ? ["-msimd"] : [],
|
||||
];
|
||||
|
||||
// Configure libpgmath.
|
||||
await promisifySpawn(spawn(cmake, command({
|
||||
definitions: variable({
|
||||
...general,
|
||||
...{
|
||||
CMAKE_C_FLAGS: cxFlags.join(" "),
|
||||
CMAKE_CXX_FLAGS: cxFlags.join(" "),
|
||||
CMAKE_C_FLAGS: buildCompilerFlags(cxFlags),
|
||||
CMAKE_CXX_FLAGS: buildCompilerFlags(cxFlags),
|
||||
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
||||
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
||||
} as GeneralVariable,
|
||||
@@ -172,12 +187,17 @@ export function llvmPackages({
|
||||
name: "cflang",
|
||||
configurePhase: async () => {
|
||||
await promisifySpawn(spawn(rm, ["-rf", build], spawnOptions));
|
||||
|
||||
const cxFlags = [
|
||||
...clangCXFlags,
|
||||
];
|
||||
// Configure cflang.
|
||||
await promisifySpawn(spawn(cmake, command({
|
||||
definitions: variable({
|
||||
...general,
|
||||
...{
|
||||
CMAKE_C_FLAGS: buildCompilerFlags(cxFlags),
|
||||
CMAKE_CXX_FLAGS: buildCompilerFlags(cxFlags),
|
||||
CMAKE_Fortran_FLAGS: buildCompilerFlags([mcpuFlag]),
|
||||
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
||||
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
||||
CMAKE_Fortran_COMPILER: path.join(installPrefix, "bin", "flang"),
|
||||
|
||||
@@ -130,3 +130,27 @@ export function command(o: CMakeGenerateOptions): string[] {
|
||||
...optFlag('-C', o.preloadCache),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escapes a single C compiler flag argument to ensure CMake can parse it correctly.
|
||||
* Handles spaces and double quotes by wrapping the argument in double quotes and escaping internal double quotes.
|
||||
*/
|
||||
function escapeCmakeFlag(arg: string): string {
|
||||
// Escape internal double quotes as \"
|
||||
let escaped = arg.replace(/"/g, '\\"');
|
||||
// If the argument contains spaces or originally has double quotes, wrap it in double quotes
|
||||
if (escaped.includes(' ') || arg.includes('"')) {
|
||||
escaped = `"${escaped}"`;
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of strings into a single string suitable for CMAKE_C_FLAGS.
|
||||
* @param flags The original array of compiler flags, e.g., ["-O2", "-DNAME=Hello World"]
|
||||
* @returns The escaped string that can be directly passed to CMake
|
||||
*/
|
||||
export function buildCompilerFlags(flags: string[]): string {
|
||||
return flags.map(escapeCmakeFlag).join(' ');
|
||||
}
|
||||
Reference in New Issue
Block a user