Files
scriptc/native/llvm-codegen/src/target.cpp
Chris Tate c41f1a8be9 Expand LLVM native output targets (#280)
* Expand LLVM native output targets

- Add owned helper and runtime-pack contracts for macOS x64, Linux glibc/musl, Windows x64, and WASI.
- Generalize LLVM target selection, package validation, linker plans, and release/CI matrices.
- Document linker boundaries and add focused native-output and runtime-pack coverage.

* Pin Windows LLVM helper CI to VS 2022

The official LLVM archive needs the Visual Studio 2022 CMake generator, which is not guaranteed by windows-latest.

* Align bootstrap cache with LLVM runtime-pack builds

Use the same target-specific helper and linker identity before and after compiler loading so routed executable cache hits remain lightweight.

* Install Windows LLVM CI tools with Chocolatey

windows-2022 includes Visual Studio but not winget; use its available Chocolatey bootstrap for CMake and Ninja.

* Prevent Zig version probes from leaving runtime-pack objects

Run runtime-pack compiler version probes in a private temporary directory and remove the accidental tracked WASI a.o file.

* Use 7-Zip for Windows LLVM setup

Extract the official LLVM development archive with two-stage 7-Zip instead of Windows tar.exe, which timed out while materializing the toolchain tree.

* Define ssize_t for the MSVC runtime pack

Clang's MSVC target does not expose POSIX ssize_t through sys/types.h; define the pointer-sized runtime type without affecting MinGW.

* Build the Windows runtime pack with Zig

Use the MinGW-compatible Windows sysroot required by the runtime while retaining COFF helper output and installing Zig in the Windows native CI lane.

* Give macOS LLVM differential shard time to finish

Shard 1 passed its setup and focused contracts but was cancelled during its cold LLVM differential slice at the 20-minute job limit.
2026-09-01 13:41:34 -05:00

127 lines
3.4 KiB
C++

#include "target.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Triple.h"
using namespace llvm;
#if defined(SCRIPTC_ENABLE_AARCH64)
extern "C" {
void LLVMInitializeAArch64TargetInfo();
void LLVMInitializeAArch64Target();
void LLVMInitializeAArch64TargetMC();
void LLVMInitializeAArch64AsmPrinter();
}
#endif
#if defined(SCRIPTC_ENABLE_X86)
extern "C" {
void LLVMInitializeX86TargetInfo();
void LLVMInitializeX86Target();
void LLVMInitializeX86TargetMC();
void LLVMInitializeX86AsmPrinter();
}
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
extern "C" {
void LLVMInitializeWebAssemblyTargetInfo();
void LLVMInitializeWebAssemblyTarget();
void LLVMInitializeWebAssemblyTargetMC();
void LLVMInitializeWebAssemblyAsmPrinter();
}
#endif
namespace scriptc {
void initializeTargets() {
static bool Initialized = false;
if (Initialized)
return;
#if defined(SCRIPTC_ENABLE_AARCH64)
LLVMInitializeAArch64TargetInfo();
LLVMInitializeAArch64Target();
LLVMInitializeAArch64TargetMC();
LLVMInitializeAArch64AsmPrinter();
#endif
#if defined(SCRIPTC_ENABLE_X86)
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
LLVMInitializeX86AsmPrinter();
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
LLVMInitializeWebAssemblyTargetInfo();
LLVMInitializeWebAssemblyTarget();
LLVMInitializeWebAssemblyTargetMC();
LLVMInitializeWebAssemblyAsmPrinter();
#endif
Initialized = true;
}
bool supportsTarget(StringRef TripleName) {
bool Allowed = false;
StringRef Remaining = AllowedTargets;
while (!Remaining.empty()) {
auto Split = Remaining.split(',');
if (Split.first == TripleName) {
Allowed = true;
break;
}
Remaining = Split.second;
}
if (!Allowed)
return false;
Triple Triple(TripleName);
switch (Triple.getArch()) {
#if defined(SCRIPTC_ENABLE_AARCH64)
case Triple::aarch64:
case Triple::aarch64_be:
return Triple.isOSBinFormatMachO() || Triple.isOSBinFormatELF();
#endif
#if defined(SCRIPTC_ENABLE_X86)
case Triple::x86_64:
case Triple::x86:
return Triple.isOSBinFormatMachO() || Triple.isOSBinFormatELF() ||
Triple.isOSBinFormatCOFF();
#endif
#if defined(SCRIPTC_ENABLE_WEBASSEMBLY)
case Triple::wasm32:
return Triple.isOSBinFormatWasm();
#endif
default:
return false;
}
}
static CodeGenOptLevel codeGenLevel(StringRef Level) {
if (Level == "0")
return CodeGenOptLevel::None;
if (Level == "1")
return CodeGenOptLevel::Less;
if (Level == "3")
return CodeGenOptLevel::Aggressive;
return CodeGenOptLevel::Default;
}
std::unique_ptr<TargetMachine> createTargetMachine(StringRef TripleName,
StringRef OptLevel,
std::string &Error) {
initializeTargets();
if (!supportsTarget(TripleName)) {
Error = (Twine("target '") + TripleName + "' was not compiled into this helper").str();
return nullptr;
}
Triple TargetTriple(TripleName);
const Target *Definition = TargetRegistry::lookupTarget(TargetTriple, Error);
if (Definition == nullptr)
return nullptr;
TargetOptions Options;
return std::unique_ptr<TargetMachine>(Definition->createTargetMachine(
TargetTriple, "generic", "", Options, Reloc::PIC_, CodeModel::Small,
codeGenLevel(OptLevel)));
}
} // namespace scriptc