198 lines
6.5 KiB
TypeScript
198 lines
6.5 KiB
TypeScript
import path from "path";
|
|
import { GeneralVariable, LLVMVariable, command, variable } from "../commands/cmake.js";
|
|
import { projectRoot } from "../environment/index.js";
|
|
import { PackagePlatform, PackageTask } from "./build.js";
|
|
import { promisifySpawn } from "../cli.js";
|
|
import os from "os";
|
|
import { SpawnOptions, spawn } from "child_process";
|
|
|
|
export interface LLVMPackageOverrides {
|
|
cmakeDefinitionOverrides?: {
|
|
llvm?: Object,
|
|
libpgmath?: Object,
|
|
cflang?: Object,
|
|
};
|
|
|
|
spawnOverrides?: (old: SpawnOptions) => SpawnOptions,
|
|
}
|
|
|
|
/**
|
|
* Make sysroot options suitable for LLVM build.
|
|
*/
|
|
export function llvmBuildSysroot(prefix: string): LLVMPackageOverrides {
|
|
return {
|
|
cmakeDefinitionOverrides: {
|
|
llvm: {
|
|
CMAKE_C_COMPILER: path.resolve(prefix, 'usr', 'bin', 'gcc'),
|
|
CMAKE_CXX_COMPILER: path.resolve(prefix, 'usr', 'bin', 'g++'),
|
|
CMAKE_SYSROOT: prefix,
|
|
},
|
|
libpgmath: {
|
|
CMAKE_SYSROOT: prefix,
|
|
},
|
|
cflang: {
|
|
|
|
CMAKE_SYSROOT: prefix,
|
|
},
|
|
},
|
|
spawnOverrides: o => ({
|
|
...o,
|
|
env: {
|
|
...o.env,
|
|
LD_LIBRARY_PATH: [
|
|
path.resolve(prefix, 'lib'),
|
|
path.resolve(prefix, 'usr', 'lib'),
|
|
].join(':')
|
|
}
|
|
}),
|
|
|
|
};
|
|
}
|
|
|
|
|
|
export interface LLVMPackageOptions {
|
|
src: string;
|
|
installPrefix: string;
|
|
|
|
/**
|
|
* Build directories suitable for these three packages.
|
|
*/
|
|
buildDir: (packageName: 'llvm' | 'libpgmath' | 'cflang') => string,
|
|
|
|
platform: PackagePlatform;
|
|
};
|
|
|
|
export function llvmPackages({
|
|
src,
|
|
installPrefix,
|
|
platform,
|
|
buildDir,
|
|
cmakeDefinitionOverrides,
|
|
spawnOverrides,
|
|
}: LLVMPackageOptions & LLVMPackageOverrides): PackageTask[] {
|
|
const rm = "rm";
|
|
const cmake = "cmake";
|
|
|
|
const llvmVar: LLVMVariable = {
|
|
LLVM_ENABLE_PROJECTS: ["clang", "clang-tools-extra", "lld", "openmp"],
|
|
LLVM_TARGETS_TO_BUILD: ["Sw64"],
|
|
LLVM_ENABLE_CLASSIC_FLANG: true,
|
|
LIBOMP_ARCH: "Sw64",
|
|
LIBOMP_USE_ITT_NOTIFY: false,
|
|
};
|
|
|
|
const general: GeneralVariable = {
|
|
CMAKE_BUILD_TYPE: "Release",
|
|
CMAKE_INSTALL_PREFIX: installPrefix,
|
|
};
|
|
|
|
const env = {
|
|
...process.env,
|
|
MAKEFLAGS: ["-j", os.cpus().length].join(" "),
|
|
};
|
|
|
|
const spawnOptions: SpawnOptions = (spawnOverrides || (o => o))({
|
|
stdio: "inherit",
|
|
env,
|
|
cwd: src,
|
|
});
|
|
|
|
const mkBuildPhase = (build: string) => (async () => {
|
|
await promisifySpawn(spawn(cmake, ["--build", build], spawnOptions));
|
|
});
|
|
|
|
const mkInstallPhase = (build: string) => (async () => {
|
|
await promisifySpawn(spawn(cmake, ["--build", build, "--target", "install"], spawnOptions));
|
|
});
|
|
|
|
function mkLLVMPackage(): PackageTask {
|
|
const build = buildDir('llvm');
|
|
return {
|
|
name: "llvm",
|
|
platform,
|
|
configurePhase: async () => {
|
|
// Configure
|
|
await promisifySpawn(spawn(cmake, command({
|
|
definitions: variable({
|
|
...llvmVar,
|
|
...general,
|
|
...cmakeDefinitionOverrides?.llvm || {},
|
|
}),
|
|
generator: "Ninja",
|
|
// LLVM cmake root is under /llvm directory
|
|
pathToSource: path.join(src, "llvm"),
|
|
pathToBuild: build,
|
|
}), spawnOptions));
|
|
},
|
|
buildPhase: mkBuildPhase(build),
|
|
installPhase: mkInstallPhase(build),
|
|
};
|
|
}
|
|
|
|
function mkLibpgmathPackage(): PackageTask {
|
|
const build = buildDir('libpgmath');
|
|
return {
|
|
name: "libpgmath",
|
|
configurePhase: async () => {
|
|
await promisifySpawn(spawn(rm, ["-rf", build], spawnOptions));
|
|
|
|
// Configure libpgmath.
|
|
await promisifySpawn(spawn(cmake, command({
|
|
definitions: variable({
|
|
...general,
|
|
...{
|
|
CMAKE_C_FLAGS: "-msimd -mlong-double-64",
|
|
CMAKE_CXX_FLAGS: "-msimd -mlong-double-64",
|
|
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
|
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
|
} as GeneralVariable,
|
|
...cmakeDefinitionOverrides?.libpgmath || {},
|
|
}),
|
|
generator: "Ninja",
|
|
pathToSource: path.join(src, "cflang", "runtime", "libpgmath"),
|
|
pathToBuild: build,
|
|
}), spawnOptions));
|
|
},
|
|
buildPhase: mkBuildPhase(build),
|
|
installPhase: mkInstallPhase(build),
|
|
};
|
|
}
|
|
|
|
function mkCflangPackage(): PackageTask {
|
|
const build = buildDir('cflang');
|
|
return {
|
|
name: "cflang",
|
|
configurePhase: async () => {
|
|
await promisifySpawn(spawn(rm, ["-rf", build], spawnOptions));
|
|
|
|
// Configure cflang.
|
|
await promisifySpawn(spawn(cmake, command({
|
|
definitions: variable({
|
|
...general,
|
|
...{
|
|
CMAKE_C_COMPILER: path.join(installPrefix, "bin", "clang"),
|
|
CMAKE_CXX_COMPILER: path.join(installPrefix, "bin", "clang++"),
|
|
CMAKE_Fortran_COMPILER: path.join(installPrefix, "bin", "flang"),
|
|
CMAKE_Fortran_COMPILER_ID: "Flang",
|
|
} as GeneralVariable,
|
|
// Flang specific variables.
|
|
FLANG_INCLUDE_DOCS: true,
|
|
FLANG_LLVM_EXTENSIONS: true,
|
|
WITH_WERROR: false,
|
|
LLVM_CONFIG: path.join(installPrefix, "bin", "llvm-config"),
|
|
...cmakeDefinitionOverrides?.cflang || {},
|
|
}),
|
|
generator: "Unix Makefiles",
|
|
pathToSource: path.join(src, "cflang"),
|
|
pathToBuild: build,
|
|
}), spawnOptions));
|
|
},
|
|
buildPhase: mkBuildPhase(build),
|
|
installPhase: mkInstallPhase(build),
|
|
};
|
|
}
|
|
|
|
return [mkLLVMPackage(), mkLibpgmathPackage(), mkCflangPackage()];
|
|
|
|
}
|