mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
Guard every x86 intrinsic header in the toolchain probe, and declare mkdtemp on macOS (#2313)
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
#ifndef _WIN32
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
/* macOS declares mkdtemp only with the Darwin extensions visible. */
|
||||
#if defined(__APPLE__) && !defined(_DARWIN_C_SOURCE)
|
||||
#define _DARWIN_C_SOURCE 1
|
||||
#endif
|
||||
#include "ts7-process.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
compileLibArchive,
|
||||
executableSectionEliminationFlags,
|
||||
executableNativeEnvironmentFingerprint,
|
||||
implicitDependencyIncludeDirective,
|
||||
implicitDependencyProbeIncludes,
|
||||
parseLinkTraceFiles,
|
||||
resolveBuildCacheRoot,
|
||||
@@ -624,6 +625,46 @@ test("implicit dependency seeds include separately compiled vendor system header
|
||||
expect(includes).toContain("<stdatomic.h>");
|
||||
});
|
||||
|
||||
test.skipIf(clangExecutable === undefined)(
|
||||
"the implicit toolchain probe guards target-specific compiler headers",
|
||||
async () => {
|
||||
// clang ships its x86 intrinsic headers (<emmintrin.h>, ...) for every
|
||||
// target, so __has_include finds them on arm64, where including them is
|
||||
// an #error, and the same holds for the ARM headers on x86. The probe
|
||||
// must guard them by target. Only the compiler's own freestanding
|
||||
// headers are visible here, so the result does not depend on the host's
|
||||
// C library.
|
||||
const includes = (await implicitDependencyProbeIncludes(runtimeSrcDir())).filter(
|
||||
(include) =>
|
||||
include !== "<intrin.h>" && /intrin\.h>$|^<cpuid\.h>$|^<arm_(neon|acle)\.h>$/.test(include),
|
||||
);
|
||||
expect(includes).toContain("<emmintrin.h>");
|
||||
const resourceDir = execFileSync(clangExecutable!, ["-print-resource-dir"], {
|
||||
encoding: "utf8",
|
||||
}).trim();
|
||||
const source = includes.map(implicitDependencyIncludeDirective).join("");
|
||||
for (const target of ["aarch64-unknown-linux-gnu", "x86_64-unknown-linux-gnu"]) {
|
||||
const result = spawnSync(
|
||||
clangExecutable!,
|
||||
[
|
||||
`--target=${target}`,
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-isystem",
|
||||
join(resourceDir, "include"),
|
||||
"-fsyntax-only",
|
||||
"-x",
|
||||
"c",
|
||||
"-",
|
||||
],
|
||||
{ input: source, encoding: "utf8" },
|
||||
);
|
||||
expect(result.stderr, target).toBe("");
|
||||
expect(result.status, target).toBe(0);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
test.skipIf(
|
||||
process.platform === "win32" ||
|
||||
clangExecutable === undefined ||
|
||||
|
||||
@@ -26,7 +26,10 @@ export {
|
||||
export { CcCompileError, subprocessFailureDetail } from "./native/process.js";
|
||||
export { compileLibArchive } from "./native/library.js";
|
||||
export { localizeLibraryObjects } from "./native/object-merge.js";
|
||||
export { implicitDependencyProbeIncludes } from "./native/compiler-fingerprint.js";
|
||||
export {
|
||||
implicitDependencyIncludeDirective,
|
||||
implicitDependencyProbeIncludes,
|
||||
} from "./native/compiler-fingerprint.js";
|
||||
export { parseLinkTraceFiles, nativeLinkerDependencyPaths } from "./native/linker-fingerprint.js";
|
||||
export { clearCcCaches, stageRuntimeObjects } from "./native/runtime-objects.js";
|
||||
export {
|
||||
|
||||
@@ -195,15 +195,25 @@ export async function implicitDependencyProbeIncludes(rtDir: string): Promise<st
|
||||
return [...includes].sort();
|
||||
}
|
||||
|
||||
function implicitDependencyIncludeDirective(include: string): string {
|
||||
const targetCondition =
|
||||
include === "<cpuid.h>" || include === "<immintrin.h>"
|
||||
? " && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64))"
|
||||
: include === "<intrin.h>"
|
||||
? " && defined(_WIN32)"
|
||||
: include === "<arm64_neon.h>" || include === "<arm_acle.h>" || include === "<arm_neon.h>"
|
||||
? " && (defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64))"
|
||||
: "";
|
||||
/** Compiler-provided x86 headers: clang ships them for every target, so
|
||||
* __has_include finds them on arm64 too, where including them is an
|
||||
* #error. Covers the SSE/AVX intrinsic families (<emmintrin.h>,
|
||||
* <immintrin.h>, ...), <x86intrin.h>, <x86gprintrin.h> and <cpuid.h>. */
|
||||
function x86OnlyHeader(include: string): boolean {
|
||||
return include === "<cpuid.h>" || /^<(x86|x86gpr|[a-z]*mm)intrin\.h>$/.test(include);
|
||||
}
|
||||
|
||||
/** One guarded line of the implicit-toolchain probe source: the header is
|
||||
* included only when the compiler can find it and it belongs to the target
|
||||
* being probed. */
|
||||
export function implicitDependencyIncludeDirective(include: string): string {
|
||||
const targetCondition = x86OnlyHeader(include)
|
||||
? " && (defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64))"
|
||||
: include === "<intrin.h>"
|
||||
? " && defined(_WIN32)"
|
||||
: include === "<arm64_neon.h>" || include === "<arm_acle.h>" || include === "<arm_neon.h>"
|
||||
? " && (defined(__arm__) || defined(__aarch64__) || defined(_M_ARM) || defined(_M_ARM64))"
|
||||
: "";
|
||||
return `#if __has_include(${include})${targetCondition}\n#include ${include}\n#endif\n`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user