Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Native compiler for Apple Silicon #258

Open
gas1cent opened this issue Feb 19, 2024 · 1 comment
Open

Native compiler for Apple Silicon #258

gas1cent opened this issue Feb 19, 2024 · 1 comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed

Comments

@gas1cent
Copy link

Description

Starting from v0.8.24, solc binaries for macos have become compatible with Apple Silicon chips. It would be very nice to add support for them at some point.

Context

You can find the related discussion here: ethereum/solidity#12291

@blitz-1306
Copy link
Contributor

blitz-1306 commented Feb 21, 2024

Greetings.

On one hand - there are WASM builds, that should run fine, aside from native. On the other hand, if we would like to support this, we need to change something in following lines:

export function getCompilerPrefixForOs(): string | undefined {
const arch = os.arch();
/**
* Only 64 bit native compilers built
*/
if (arch !== "x64") {
return undefined;
}
const type = os.type();
if (type === "Linux") {
return "linux-amd64";
}
if (type === "Windows_NT") {
return "windows-amd64";
}
if (type === "Darwin") {
return "macosx-amd64";
}
return undefined;
}

Following logic of downloading proper compiler should work as intended:

export async function getCompilerForVersion<T extends CompilerMapping>(
version: string,
kind: T[0]
): Promise<T[1] | undefined> {
assert(
isExact(version),
"Version string must contain exact SemVer-formatted version without any operators"
);
let prefix: string | undefined;
if (kind === CompilerKind.Native) {
prefix = getCompilerPrefixForOs();
} else if (kind === CompilerKind.WASM) {
prefix = "wasm";
} else {
throw new Error(`Unsupported compiler kind "${kind}"`);
}
assert(CompilerVersions.includes(version), `Unsupported ${kind} compiler version ${version}`);
if (prefix === undefined) {
return undefined;
}
const md = await getCompilerMDForPlatform(prefix, version);
const compilerFileName = md.releases[version];
if (compilerFileName === undefined) {
return undefined;
}
const compilerLocalPath = getCompilerLocalPath(prefix, compilerFileName);
if (!fse.existsSync(compilerLocalPath)) {
const build = md.builds.find((b) => b.version === version);
assert(
build !== undefined,
`Unable to find build metadata for ${prefix} compiler ${version} in "list.json"`
);
const response = await axios.get<ArrayBuffer>(
`${BINARIES_URL}/${prefix}/${compilerFileName}`,
{
responseType: "arraybuffer"
}
);
const buf = Buffer.from(response.data);
const hash = crypto.createHash("sha256");
hash.update(buf);
const digest = "0x" + hash.digest("hex");
assert(
digest === build.sha256,
`Downloaded ${prefix} compiler ${version} hash ${digest} does not match hash ${build.sha256} from "list.json"`
);
/**
* Native compilers are exeсutable files, so give them proper permissions.
* WASM compilers are loaded by NodeJS, so write them as readonly common files.
*/
const permissions = kind === CompilerKind.Native ? 0o555 : 0o444;
await fse.writeFile(compilerLocalPath, buf, { mode: permissions });
}
if (kind === CompilerKind.Native) {
return new NativeCompiler(version, compilerLocalPath);
}
if (kind === CompilerKind.WASM) {
return new WasmCompiler(version, compilerLocalPath);
}
throw new Error(`Unable to detemine compiler constructor for kind "${kind}"`);
}
export async function* downloadSupportedCompilers(kinds: CompilerKind[]): AsyncGenerator<Compiler> {
for (const compilerKind of kinds) {
for (const version of CompilerVersions) {
const compiler = await getCompilerForVersion(version, compilerKind);
assert(
compiler !== undefined,
`Expected {0} compiler v{1} to be defined`,
compilerKind,
version
);
yield compiler;
}
}
}

Running

# Locate cache with downloaded compilers:
sol-ast-compile --locate-compiler-cache

# Pre-download native compilers:
sol-ast-compile --download-compilers native

Should result downloading of proper compilers for the current platform.

Some very basic requirement is to successfully compile empty contract with native compiler:

echo 'contract Test {}' | sol-ast-compile --stdin --compiler-kind native --mode sol --tree
SourceUnit #2 -> stdin
|   ContractDefinition #1 -> contract Test

Also we do not run tests against multiple platforms due to our time and resourse constraints. I also do not have Silicon-based hardware in my reach.

Tip

We would gladly accept incoming PRs and external help.

@blitz-1306 blitz-1306 added good first issue Good for newcomers help wanted Extra attention is needed labels Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants