* initial zano commit * update checksum, fix zano patches on CI * fix monero builds * fix cmake command * fix: devcontainer on x64 ffigen: add zano zano: add missing free dart: implement zano * update boost filenames * unboost the cmakelists * fix zano boost issues * added patch into proper location * fix various build issues * [skip ci] update tor-connect * fix zano builds for ios * fix apply patches and don't fail-fast * uncomment build depends for monero * build_single.sh fix for macos native builds * disable qemu on arm64 builders from buildjet * fix boost, fix missing symbols (maybe) * fix ordering of crypto and ssl libraries * fix wownero mingw * fetch zano releases to release-bulk * build things 'the zano way' * proper cmake config * Zano.. yeah... * Update zano release to 2.0.1.367 * update zano patches * update zano builds * update zano build * fix zano build * move zlibstatic to the top (this shouldn't matter anyway) * fix patch location, update tor-connect * update ci runner * fix zano build on the CI * enable zano for other targets * nvm * don't use darwin in single release file * Increase max password length * build contrib/depends offline * zano support for macos * Update dependencies to work on multithread via rosetta2 * different way of adding .patch-applied * Improve performance of incremental builds * remove unnecessary patches * update coin-control patch * fix test * remove contrib/depends patches in wownero * chore: support fallback names in the download_deps util --------- Co-authored-by: Im-Beast <franik.mateusz@gmail.com>
279 lines
8.2 KiB
TypeScript
279 lines
8.2 KiB
TypeScript
import { join, resolve } from "jsr:@std/path";
|
|
import { Coin, getMoneroCTags } from "./utils.ts";
|
|
|
|
export type Target = `${typeof Deno["build"]["os"]}_${typeof Deno["build"]["arch"]}`;
|
|
|
|
interface FileInfo {
|
|
// List of mirrors that override DownloadInfo mirrors for this FileInfo
|
|
overrideMirrors?: [mainFilePath: string, ...fallbacks: string[]];
|
|
// List of file names that fallback if previous failed
|
|
// If first name failed and got fallbacked by another, it will get renamed to the first entry
|
|
names: string[];
|
|
sha256?: string;
|
|
}
|
|
|
|
interface DownloadInfo {
|
|
mirrors: string[];
|
|
file:
|
|
| FileInfo
|
|
| { [os in Target]?: FileInfo };
|
|
outDir?: string;
|
|
}
|
|
|
|
export function getFileInfo(
|
|
downloadInfo: DownloadInfo,
|
|
target: Target = `${Deno.build.os}_${Deno.build.arch}`,
|
|
): FileInfo {
|
|
const fileInfo = "names" in downloadInfo.file ? downloadInfo.file : downloadInfo.file[target];
|
|
if (!fileInfo) {
|
|
throw new Error(`No fileInfo set for target: ${target}`);
|
|
}
|
|
return fileInfo;
|
|
}
|
|
|
|
async function sha256(buffer: Uint8Array): Promise<string> {
|
|
const hashed = new Uint8Array(await crypto.subtle.digest("SHA-256", buffer));
|
|
return Array.from(hashed).map((i) => i.toString(16).padStart(2, "0")).join("");
|
|
}
|
|
|
|
export async function downloadDependencies(...infos: DownloadInfo[]): Promise<void> {
|
|
return await downloadFiles("./tests/dependencies", `${Deno.build.os}_${Deno.build.arch}`, ...infos);
|
|
}
|
|
|
|
async function tryToDownloadFile(
|
|
mirror: string,
|
|
fileInfo: FileInfo,
|
|
fileName: string,
|
|
): Promise<Uint8Array | undefined> {
|
|
const url = `${mirror}/${fileName}`;
|
|
|
|
const response = await fetch(url);
|
|
if (!response.ok) {
|
|
console.warn(`Could not reach file ${fileName} on mirror: ${mirror}`);
|
|
await response.body?.cancel();
|
|
return;
|
|
}
|
|
|
|
const responseBuffer = await response.bytes();
|
|
|
|
if (fileInfo.sha256) {
|
|
const responseChecksum = await sha256(responseBuffer);
|
|
if (responseChecksum !== fileInfo.sha256) {
|
|
console.warn(
|
|
`Checksum mismatch on file ${fileName} on mirror: ${mirror} (${responseChecksum} != ${fileInfo.sha256})`,
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
return responseBuffer;
|
|
}
|
|
|
|
async function validFileExists(filePath: string, fileInfo: FileInfo): Promise<boolean> {
|
|
const [mainFileName] = fileInfo.names;
|
|
|
|
let fileBuffer: Uint8Array;
|
|
try {
|
|
fileBuffer = await Deno.readFile(filePath);
|
|
} catch {
|
|
return false;
|
|
}
|
|
|
|
// File exists, make sure checksum matches
|
|
if (fileInfo.sha256) {
|
|
const fileChecksum = await sha256(fileBuffer);
|
|
if (fileChecksum !== fileInfo.sha256) {
|
|
console.log(
|
|
`File ${mainFileName} already exists, but checksum is mismatched (${fileChecksum} != ${fileInfo.sha256}), redownloading`,
|
|
);
|
|
await Deno.remove(filePath);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
console.log(`File ${mainFileName} already exists, skipping`);
|
|
return true;
|
|
}
|
|
|
|
export async function downloadFiles(outDir: string, target: Target, ...infos: DownloadInfo[]): Promise<void> {
|
|
try {
|
|
await Deno.mkdir(outDir, { recursive: true });
|
|
} catch (error) {
|
|
if (!(error instanceof Deno.errors.AlreadyExists)) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
for (const info of infos) {
|
|
const fileInfo = getFileInfo(info, target);
|
|
const [mainFileName] = fileInfo.names;
|
|
|
|
if (
|
|
await validFileExists(
|
|
join(outDir, info.outDir || ""),
|
|
fileInfo,
|
|
)
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
let buffer: Uint8Array | undefined;
|
|
outer: for (const mirror of fileInfo.overrideMirrors ?? info.mirrors) {
|
|
for (const fileName of fileInfo.names) {
|
|
buffer = await tryToDownloadFile(mirror, fileInfo, fileName);
|
|
|
|
if (buffer) {
|
|
break outer;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!buffer) {
|
|
throw new Error(`None of the mirrors for ${fileInfo.names} are available`);
|
|
}
|
|
|
|
const filePath = join(outDir, info.outDir ?? "", mainFileName);
|
|
|
|
await Deno.mkdir(resolve(filePath, ".."), {
|
|
recursive: true,
|
|
}).catch(() => {});
|
|
|
|
await Deno.writeFile(filePath, buffer);
|
|
console.info("Downloaded file", filePath);
|
|
}
|
|
}
|
|
|
|
export const wowneroCliInfo: DownloadInfo = {
|
|
mirrors: [
|
|
"https://static.mrcyjanek.net/download_mirror/",
|
|
"https://codeberg.org/wownero/wownero/releases/download/v0.11.2.0/",
|
|
],
|
|
file: {
|
|
linux_aarch64: {
|
|
names: ["wownero-aarch64-linux-gnu-59db3fe8d.tar.bz2"],
|
|
sha256: "07ce678302c07a6e79d90be65cbda243d843d414fbadb30f972d6c226575cfa7",
|
|
},
|
|
linux_x86_64: {
|
|
names: ["wownero-x86_64-linux-gnu-59db3fe8d.tar.bz2"],
|
|
sha256: "03880967c70cc86558d962b8a281868c3934238ea457a36174ba72b99d70107e",
|
|
},
|
|
|
|
darwin_aarch64: {
|
|
names: ["wownero-aarch64-apple-darwin11-59db3fe8d.tar.bz2"],
|
|
sha256: "25ff454a92b1cf036df5f28cdd2c63dcaf4b03da7da9403087371f868827c957",
|
|
},
|
|
darwin_x86_64: {
|
|
names: ["wownero-x86_64-apple-darwin11-59db3fe8d.tar.bz2"],
|
|
sha256: "7e9b6a84a560ed7a9ed7117c6f07fb228d77a06afac863d0ea1dbf833c4eddf6",
|
|
},
|
|
|
|
windows_x86_64: {
|
|
names: ["wownero-x86_64-w64-mingw32-59db3fe8d.zip"],
|
|
sha256: "7e0ed84afa51e3b403d635c706042859094eb6850de21c9e82cb0a104425510e",
|
|
},
|
|
|
|
android_aarch64: {
|
|
overrideMirrors: [
|
|
"https://static.mrcyjanek.net/download_mirror/",
|
|
"https://codeberg.org/wownero/wownero/releases/download/v0.11.1.0/",
|
|
],
|
|
names: ["wownero-aarch64-linux-android-v0.11.1.0.tar.bz2"],
|
|
sha256: "236188f8d8e7fad2ff35973f8c2417afffa8855d1a57b4c682fff5b199ea40f5",
|
|
},
|
|
},
|
|
};
|
|
|
|
export const moneroCliInfo: DownloadInfo = {
|
|
mirrors: [
|
|
"https://static.mrcyjanek.net/download_mirror/",
|
|
"https://downloads.getmonero.org/cli/",
|
|
],
|
|
file: {
|
|
linux_aarch64: {
|
|
names: ["monero-linux-armv8-v0.18.3.4.tar.bz2"],
|
|
sha256: "33ca2f0055529d225b61314c56370e35606b40edad61c91c859f873ed67a1ea7",
|
|
},
|
|
linux_x86_64: {
|
|
names: ["monero-linux-x64-v0.18.3.4.tar.bz2"],
|
|
sha256: "51ba03928d189c1c11b5379cab17dd9ae8d2230056dc05c872d0f8dba4a87f1d",
|
|
},
|
|
|
|
darwin_aarch64: {
|
|
names: ["monero-mac-armv8-v0.18.3.4.tar.bz2"],
|
|
sha256: "44520cb3a05c2518ca9aeae1b2e3080fe2bba1e3596d014ceff1090dfcba8ab4",
|
|
},
|
|
darwin_x86_64: {
|
|
names: ["monero-mac-x64-v0.18.3.4.tar.bz2"],
|
|
sha256: "32c449f562216d3d83154e708471236d07db7477d6b67f1936a0a85a5005f2b8",
|
|
},
|
|
|
|
windows_x86_64: {
|
|
names: ["monero-win-x64-v0.18.3.4.zip"],
|
|
sha256: "54a66db6c892b2a0999754841f4ca68511741b88ea3ab20c7cd504a027f465f5",
|
|
},
|
|
|
|
android_aarch64: {
|
|
names: ["monero-android-armv8-v0.18.3.4.tar.bz2"],
|
|
sha256: "d9c9249d1408822ce36b346c6b9fb6b896cda16714d62117fb1c588a5201763c",
|
|
},
|
|
},
|
|
};
|
|
|
|
export const dylibInfos: Record<Coin, DownloadInfo[]> = {
|
|
monero: [],
|
|
wownero: [],
|
|
};
|
|
|
|
for (const tag of await getMoneroCTags()) {
|
|
for (const coin of ["monero", "wownero"] as const) {
|
|
dylibInfos[coin].push({
|
|
mirrors: [
|
|
`https://static.mrcyjanek.net/download_mirror/libs/${tag}/`,
|
|
`https://github.com/MrCyjaneK/monero_c/releases/download/${tag}/`,
|
|
],
|
|
file: {
|
|
linux_aarch64: { names: [`${coin}_aarch64-linux-gnu_libwallet2_api_c.so.xz`] },
|
|
linux_x86_64: { names: [`${coin}_x86_64-linux-gnu_libwallet2_api_c.so.xz`] },
|
|
darwin_aarch64: {
|
|
names: [
|
|
`${coin}_aarch64-apple-darwin11_libwallet2_api_c.dylib.xz`,
|
|
`${coin}_aarch64-apple-darwin_libwallet2_api_c.dylib.xz`,
|
|
],
|
|
},
|
|
darwin_x86_64: {
|
|
names: [
|
|
`${coin}_x86_64-apple-darwin11_libwallet2_api_c.dylib.xz`,
|
|
`${coin}_x86_64-apple-darwin_libwallet2_api_c.dylib.xz`,
|
|
],
|
|
},
|
|
windows_x86_64: { names: [`${coin}_x86_64-w64-mingw32_libwallet2_api_c.dll.xz`] },
|
|
android_aarch64: { names: [`${coin}_aarch64-linux-android_libwallet2_api_c.so.xz`] },
|
|
},
|
|
outDir: `libs/${tag}`,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Download files to the download_mirror folder
|
|
// (used on mirror to keep files up to date)
|
|
if (import.meta.main) {
|
|
const supportedTargets: Target[] = [
|
|
"linux_x86_64",
|
|
"linux_aarch64",
|
|
"darwin_x86_64",
|
|
"darwin_aarch64",
|
|
"windows_x86_64",
|
|
"android_aarch64",
|
|
];
|
|
|
|
for (const target of supportedTargets) {
|
|
await downloadFiles(
|
|
"./download_mirror",
|
|
target,
|
|
moneroCliInfo,
|
|
wowneroCliInfo,
|
|
...Object.values(dylibInfos).flat(),
|
|
);
|
|
}
|
|
}
|