mirror of
https://github.com/ziglang/zig.git
synced 2026-02-01 12:13:44 +00:00
Part of #19063. Primarily, this moves Aro from deps/ to lib/compiler/ so that it can be lazily compiled from source. src/aro_translate_c.zig is moved to lib/compiler/aro_translate_c.zig and some of Zig CLI logic moved to a main() function there. aro_translate_c.zig becomes the "common" import for clang-based translate-c. Not all of the compiler was able to be detangled from Aro, however, so it still, for now, remains being compiled with the main compiler sources due to the clang-based translate-c depending on it. Once aro-based translate-c achieves feature parity with the clang-based translate-c implementation, the clang-based one can be removed from Zig. Aro made it unnecessarily difficult to depend on with these .def files and all these Zig module requirements. I looked at the .def files and made these observations: - The canonical source is llvm .def files. - Therefore there is an update process to sync with llvm that involves regenerating the .def files in Aro. - Therefore you might as well just regenerate the .zig files directly and check those into Aro. - Also with a small amount of tinkering, the file size on disk of these generated .zig files can be made many times smaller, without compromising type safety in the usage of the data. This would make things much easier on Zig as downstream project, particularly we could remove those pesky stubs when bootstrapping. I have gone ahead with these changes since they unblock me and I will have a chat with Vexu to see what he thinks.
329 lines
10 KiB
Zig
Vendored
329 lines
10 KiB
Zig
Vendored
//! Tools for figuring out what Linux distro we're running on
|
|
|
|
const std = @import("std");
|
|
const mem = std.mem;
|
|
const Filesystem = @import("Filesystem.zig").Filesystem;
|
|
|
|
const MAX_BYTES = 1024; // TODO: Can we assume 1024 bytes enough for the info we need?
|
|
|
|
/// Value for linker `--hash-style=` argument
|
|
pub const HashStyle = enum {
|
|
both,
|
|
gnu,
|
|
};
|
|
|
|
pub const Tag = enum {
|
|
alpine,
|
|
arch,
|
|
debian_lenny,
|
|
debian_squeeze,
|
|
debian_wheezy,
|
|
debian_jessie,
|
|
debian_stretch,
|
|
debian_buster,
|
|
debian_bullseye,
|
|
debian_bookworm,
|
|
debian_trixie,
|
|
exherbo,
|
|
rhel5,
|
|
rhel6,
|
|
rhel7,
|
|
fedora,
|
|
gentoo,
|
|
open_suse,
|
|
ubuntu_hardy,
|
|
ubuntu_intrepid,
|
|
ubuntu_jaunty,
|
|
ubuntu_karmic,
|
|
ubuntu_lucid,
|
|
ubuntu_maverick,
|
|
ubuntu_natty,
|
|
ubuntu_oneiric,
|
|
ubuntu_precise,
|
|
ubuntu_quantal,
|
|
ubuntu_raring,
|
|
ubuntu_saucy,
|
|
ubuntu_trusty,
|
|
ubuntu_utopic,
|
|
ubuntu_vivid,
|
|
ubuntu_wily,
|
|
ubuntu_xenial,
|
|
ubuntu_yakkety,
|
|
ubuntu_zesty,
|
|
ubuntu_artful,
|
|
ubuntu_bionic,
|
|
ubuntu_cosmic,
|
|
ubuntu_disco,
|
|
ubuntu_eoan,
|
|
ubuntu_focal,
|
|
ubuntu_groovy,
|
|
ubuntu_hirsute,
|
|
ubuntu_impish,
|
|
ubuntu_jammy,
|
|
ubuntu_kinetic,
|
|
ubuntu_lunar,
|
|
unknown,
|
|
|
|
pub fn getHashStyle(self: Tag) HashStyle {
|
|
if (self.isOpenSUSE()) return .both;
|
|
return switch (self) {
|
|
.ubuntu_lucid,
|
|
.ubuntu_jaunty,
|
|
.ubuntu_karmic,
|
|
=> .both,
|
|
else => .gnu,
|
|
};
|
|
}
|
|
|
|
pub fn isRedhat(self: Tag) bool {
|
|
return switch (self) {
|
|
.fedora,
|
|
.rhel5,
|
|
.rhel6,
|
|
.rhel7,
|
|
=> true,
|
|
else => false,
|
|
};
|
|
}
|
|
|
|
pub fn isOpenSUSE(self: Tag) bool {
|
|
return self == .open_suse;
|
|
}
|
|
|
|
pub fn isDebian(self: Tag) bool {
|
|
return switch (self) {
|
|
.debian_lenny,
|
|
.debian_squeeze,
|
|
.debian_wheezy,
|
|
.debian_jessie,
|
|
.debian_stretch,
|
|
.debian_buster,
|
|
.debian_bullseye,
|
|
.debian_bookworm,
|
|
.debian_trixie,
|
|
=> true,
|
|
else => false,
|
|
};
|
|
}
|
|
pub fn isUbuntu(self: Tag) bool {
|
|
return switch (self) {
|
|
.ubuntu_hardy,
|
|
.ubuntu_intrepid,
|
|
.ubuntu_jaunty,
|
|
.ubuntu_karmic,
|
|
.ubuntu_lucid,
|
|
.ubuntu_maverick,
|
|
.ubuntu_natty,
|
|
.ubuntu_oneiric,
|
|
.ubuntu_precise,
|
|
.ubuntu_quantal,
|
|
.ubuntu_raring,
|
|
.ubuntu_saucy,
|
|
.ubuntu_trusty,
|
|
.ubuntu_utopic,
|
|
.ubuntu_vivid,
|
|
.ubuntu_wily,
|
|
.ubuntu_xenial,
|
|
.ubuntu_yakkety,
|
|
.ubuntu_zesty,
|
|
.ubuntu_artful,
|
|
.ubuntu_bionic,
|
|
.ubuntu_cosmic,
|
|
.ubuntu_disco,
|
|
.ubuntu_eoan,
|
|
.ubuntu_focal,
|
|
.ubuntu_groovy,
|
|
.ubuntu_hirsute,
|
|
.ubuntu_impish,
|
|
.ubuntu_jammy,
|
|
.ubuntu_kinetic,
|
|
.ubuntu_lunar,
|
|
=> true,
|
|
|
|
else => false,
|
|
};
|
|
}
|
|
pub fn isAlpine(self: Tag) bool {
|
|
return self == .alpine;
|
|
}
|
|
pub fn isGentoo(self: Tag) bool {
|
|
return self == .gentoo;
|
|
}
|
|
};
|
|
|
|
fn scanForOsRelease(buf: []const u8) ?Tag {
|
|
var it = mem.splitScalar(u8, buf, '\n');
|
|
while (it.next()) |line| {
|
|
if (mem.startsWith(u8, line, "ID=")) {
|
|
const rest = line["ID=".len..];
|
|
if (mem.eql(u8, rest, "alpine")) return .alpine;
|
|
if (mem.eql(u8, rest, "fedora")) return .fedora;
|
|
if (mem.eql(u8, rest, "gentoo")) return .gentoo;
|
|
if (mem.eql(u8, rest, "arch")) return .arch;
|
|
if (mem.eql(u8, rest, "sles")) return .open_suse;
|
|
if (mem.eql(u8, rest, "opensuse")) return .open_suse;
|
|
if (mem.eql(u8, rest, "exherbo")) return .exherbo;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
fn detectOsRelease(fs: Filesystem) ?Tag {
|
|
var buf: [MAX_BYTES]u8 = undefined;
|
|
const data = fs.readFile("/etc/os-release", &buf) orelse fs.readFile("/usr/lib/os-release", &buf) orelse return null;
|
|
return scanForOsRelease(data);
|
|
}
|
|
|
|
fn scanForLSBRelease(buf: []const u8) ?Tag {
|
|
var it = mem.splitScalar(u8, buf, '\n');
|
|
while (it.next()) |line| {
|
|
if (mem.startsWith(u8, line, "DISTRIB_CODENAME=")) {
|
|
const rest = line["DISTRIB_CODENAME=".len..];
|
|
if (mem.eql(u8, rest, "hardy")) return .ubuntu_hardy;
|
|
if (mem.eql(u8, rest, "intrepid")) return .ubuntu_intrepid;
|
|
if (mem.eql(u8, rest, "jaunty")) return .ubuntu_jaunty;
|
|
if (mem.eql(u8, rest, "karmic")) return .ubuntu_karmic;
|
|
if (mem.eql(u8, rest, "lucid")) return .ubuntu_lucid;
|
|
if (mem.eql(u8, rest, "maverick")) return .ubuntu_maverick;
|
|
if (mem.eql(u8, rest, "natty")) return .ubuntu_natty;
|
|
if (mem.eql(u8, rest, "oneiric")) return .ubuntu_oneiric;
|
|
if (mem.eql(u8, rest, "precise")) return .ubuntu_precise;
|
|
if (mem.eql(u8, rest, "quantal")) return .ubuntu_quantal;
|
|
if (mem.eql(u8, rest, "raring")) return .ubuntu_raring;
|
|
if (mem.eql(u8, rest, "saucy")) return .ubuntu_saucy;
|
|
if (mem.eql(u8, rest, "trusty")) return .ubuntu_trusty;
|
|
if (mem.eql(u8, rest, "utopic")) return .ubuntu_utopic;
|
|
if (mem.eql(u8, rest, "vivid")) return .ubuntu_vivid;
|
|
if (mem.eql(u8, rest, "wily")) return .ubuntu_wily;
|
|
if (mem.eql(u8, rest, "xenial")) return .ubuntu_xenial;
|
|
if (mem.eql(u8, rest, "yakkety")) return .ubuntu_yakkety;
|
|
if (mem.eql(u8, rest, "zesty")) return .ubuntu_zesty;
|
|
if (mem.eql(u8, rest, "artful")) return .ubuntu_artful;
|
|
if (mem.eql(u8, rest, "bionic")) return .ubuntu_bionic;
|
|
if (mem.eql(u8, rest, "cosmic")) return .ubuntu_cosmic;
|
|
if (mem.eql(u8, rest, "disco")) return .ubuntu_disco;
|
|
if (mem.eql(u8, rest, "eoan")) return .ubuntu_eoan;
|
|
if (mem.eql(u8, rest, "focal")) return .ubuntu_focal;
|
|
if (mem.eql(u8, rest, "groovy")) return .ubuntu_groovy;
|
|
if (mem.eql(u8, rest, "hirsute")) return .ubuntu_hirsute;
|
|
if (mem.eql(u8, rest, "impish")) return .ubuntu_impish;
|
|
if (mem.eql(u8, rest, "jammy")) return .ubuntu_jammy;
|
|
if (mem.eql(u8, rest, "kinetic")) return .ubuntu_kinetic;
|
|
if (mem.eql(u8, rest, "lunar")) return .ubuntu_lunar;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
fn detectLSBRelease(fs: Filesystem) ?Tag {
|
|
var buf: [MAX_BYTES]u8 = undefined;
|
|
const data = fs.readFile("/etc/lsb-release", &buf) orelse return null;
|
|
|
|
return scanForLSBRelease(data);
|
|
}
|
|
|
|
fn scanForRedHat(buf: []const u8) Tag {
|
|
if (mem.startsWith(u8, buf, "Fedora release")) return .fedora;
|
|
if (mem.startsWith(u8, buf, "Red Hat Enterprise Linux") or mem.startsWith(u8, buf, "CentOS") or mem.startsWith(u8, buf, "Scientific Linux")) {
|
|
if (mem.indexOfPos(u8, buf, 0, "release 7") != null) return .rhel7;
|
|
if (mem.indexOfPos(u8, buf, 0, "release 6") != null) return .rhel6;
|
|
if (mem.indexOfPos(u8, buf, 0, "release 5") != null) return .rhel5;
|
|
}
|
|
|
|
return .unknown;
|
|
}
|
|
|
|
fn detectRedhat(fs: Filesystem) ?Tag {
|
|
var buf: [MAX_BYTES]u8 = undefined;
|
|
const data = fs.readFile("/etc/redhat-release", &buf) orelse return null;
|
|
return scanForRedHat(data);
|
|
}
|
|
|
|
fn scanForDebian(buf: []const u8) Tag {
|
|
var it = mem.splitScalar(u8, buf, '.');
|
|
if (std.fmt.parseInt(u8, it.next().?, 10)) |major| {
|
|
return switch (major) {
|
|
5 => .debian_lenny,
|
|
6 => .debian_squeeze,
|
|
7 => .debian_wheezy,
|
|
8 => .debian_jessie,
|
|
9 => .debian_stretch,
|
|
10 => .debian_buster,
|
|
11 => .debian_bullseye,
|
|
12 => .debian_bookworm,
|
|
13 => .debian_trixie,
|
|
else => .unknown,
|
|
};
|
|
} else |_| {}
|
|
|
|
it = mem.splitScalar(u8, buf, '\n');
|
|
const name = it.next().?;
|
|
if (mem.eql(u8, name, "squeeze/sid")) return .debian_squeeze;
|
|
if (mem.eql(u8, name, "wheezy/sid")) return .debian_wheezy;
|
|
if (mem.eql(u8, name, "jessie/sid")) return .debian_jessie;
|
|
if (mem.eql(u8, name, "stretch/sid")) return .debian_stretch;
|
|
if (mem.eql(u8, name, "buster/sid")) return .debian_buster;
|
|
if (mem.eql(u8, name, "bullseye/sid")) return .debian_bullseye;
|
|
if (mem.eql(u8, name, "bookworm/sid")) return .debian_bookworm;
|
|
|
|
return .unknown;
|
|
}
|
|
|
|
fn detectDebian(fs: Filesystem) ?Tag {
|
|
var buf: [MAX_BYTES]u8 = undefined;
|
|
const data = fs.readFile("/etc/debian_version", &buf) orelse return null;
|
|
return scanForDebian(data);
|
|
}
|
|
|
|
pub fn detect(target: std.Target, fs: Filesystem) Tag {
|
|
if (target.os.tag != .linux) return .unknown;
|
|
|
|
if (detectOsRelease(fs)) |tag| return tag;
|
|
if (detectLSBRelease(fs)) |tag| return tag;
|
|
if (detectRedhat(fs)) |tag| return tag;
|
|
if (detectDebian(fs)) |tag| return tag;
|
|
|
|
if (fs.exists("/etc/gentoo-release")) return .gentoo;
|
|
|
|
return .unknown;
|
|
}
|
|
|
|
test scanForDebian {
|
|
try std.testing.expectEqual(Tag.debian_squeeze, scanForDebian("squeeze/sid"));
|
|
try std.testing.expectEqual(Tag.debian_bullseye, scanForDebian("11.1.2"));
|
|
try std.testing.expectEqual(Tag.unknown, scanForDebian("None"));
|
|
try std.testing.expectEqual(Tag.unknown, scanForDebian(""));
|
|
}
|
|
|
|
test scanForRedHat {
|
|
try std.testing.expectEqual(Tag.fedora, scanForRedHat("Fedora release 7"));
|
|
try std.testing.expectEqual(Tag.rhel7, scanForRedHat("Red Hat Enterprise Linux release 7"));
|
|
try std.testing.expectEqual(Tag.rhel5, scanForRedHat("CentOS release 5"));
|
|
try std.testing.expectEqual(Tag.unknown, scanForRedHat("CentOS release 4"));
|
|
try std.testing.expectEqual(Tag.unknown, scanForRedHat(""));
|
|
}
|
|
|
|
test scanForLSBRelease {
|
|
const text =
|
|
\\DISTRIB_ID=Ubuntu
|
|
\\DISTRIB_RELEASE=20.04
|
|
\\DISTRIB_CODENAME=focal
|
|
\\DISTRIB_DESCRIPTION="Ubuntu 20.04.6 LTS"
|
|
\\
|
|
;
|
|
try std.testing.expectEqual(Tag.ubuntu_focal, scanForLSBRelease(text).?);
|
|
}
|
|
|
|
test scanForOsRelease {
|
|
const text =
|
|
\\NAME="Alpine Linux"
|
|
\\ID=alpine
|
|
\\VERSION_ID=3.18.2
|
|
\\PRETTY_NAME="Alpine Linux v3.18"
|
|
\\HOME_URL="https://alpinelinux.org/"
|
|
\\BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
|
|
\\
|
|
;
|
|
try std.testing.expectEqual(Tag.alpine, scanForOsRelease(text).?);
|
|
}
|