464 lines
21 KiB
HTML
464 lines
21 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html lang="en" class="sidebar-visible no-js light">
|
||
|
|
||
|
<head>
|
||
|
<meta charset="utf-8">
|
||
|
<title>Hitch Hiker Linux</title>
|
||
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||
|
<meta name="description" content="">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
|
<meta name="theme-color" content="#ffffff" />
|
||
|
|
||
|
<link rel="icon" href="/favicon.svg">
|
||
|
<link rel="shortcut icon" href="/favicon.png">
|
||
|
|
||
|
<link rel="stylesheet" href="/handbook/css/variables.css">
|
||
|
<link rel="stylesheet" href="/handbook/css/general.css">
|
||
|
<link rel="stylesheet" href="/handbook/css/chrome.css">
|
||
|
|
||
|
<link rel="stylesheet" href="/handbook/css/print.css" media="print">
|
||
|
|
||
|
<!-- Fonts -->
|
||
|
<link rel="stylesheet" href="/handbook/FontAwesome/css/font-awesome.css">
|
||
|
|
||
|
<link rel="stylesheet" href="/handbook/fonts/fonts.css">
|
||
|
|
||
|
<!-- Highlight.js Stylesheets -->
|
||
|
<link rel="stylesheet" href="/handbook/highlight.css">
|
||
|
<link rel="stylesheet" href="/handbook/tomorrow-night.css">
|
||
|
<link rel="stylesheet" href="/handbook/ayu-highlight.css">
|
||
|
|
||
|
<!-- Custom Stylesheets -->
|
||
|
<link rel="stylesheet" href="/hhl.css">
|
||
|
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<!-- Provide site root to javascript -->
|
||
|
<script type="text/javascript">
|
||
|
var path_to_root = "/handbook";
|
||
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
||
|
</script>
|
||
|
|
||
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
|
<script type="text/javascript">
|
||
|
try {
|
||
|
var theme = localStorage.getItem('mdbook-theme');
|
||
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
|
||
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
|
}
|
||
|
|
||
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
|
}
|
||
|
} catch (e) { }
|
||
|
</script>
|
||
|
|
||
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
|
<script type="text/javascript">
|
||
|
var theme;
|
||
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
|
var html = document.querySelector('html');
|
||
|
html.classList.remove('no-js')
|
||
|
html.classList.remove('light')
|
||
|
html.classList.add(theme);
|
||
|
html.classList.add('js');
|
||
|
</script>
|
||
|
|
||
|
<!-- Hide / unhide sidebar before it is displayed -->
|
||
|
<script type="text/javascript">
|
||
|
var html = document.querySelector('html');
|
||
|
var sidebar = 'hidden';
|
||
|
if (document.body.clientWidth >= 1080) {
|
||
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
|
sidebar = sidebar || 'visible';
|
||
|
}
|
||
|
html.classList.remove('sidebar-visible');
|
||
|
html.classList.add("sidebar-" + sidebar);
|
||
|
</script>
|
||
|
|
||
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
|
<div class="sidebar-scrollbox">
|
||
|
<ol class="chapter">
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="/">Home</a>
|
||
|
</li>
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="/news/">News</a>
|
||
|
</li>
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="/about/">About</a>
|
||
|
</li>
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="/pub/">Download</a>
|
||
|
</li>
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="https://git.hitchhiker-linux.org">Source</a>
|
||
|
</li>
|
||
|
<li class="spacer"></li>
|
||
|
<li class="chapter-item affix ">
|
||
|
<a href="/handbook/">Handbook</a>
|
||
|
</li>
|
||
|
</ol>
|
||
|
</div>
|
||
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||
|
</nav>
|
||
|
<div id="page-wrapper" class="page-wrapper">
|
||
|
<div class="page">
|
||
|
<div id="menu-bar-hover-placeholder"></div>
|
||
|
<div id="menu-bar" class="menu-bar sticky bordered">
|
||
|
<div class="left-buttons">
|
||
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
|
<i class="fa fa-bars"></i>
|
||
|
</button>
|
||
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
|
<i class="fa fa-paint-brush"></i>
|
||
|
</button>
|
||
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
|
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
<h1 class="menu-title">
|
||
|
Hitch Hiker Linux
|
||
|
</h1>
|
||
|
</div>
|
||
|
|
||
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
|
<script type="text/javascript">
|
||
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
|
});
|
||
|
</script>
|
||
|
<div id="content" class="content">
|
||
|
<main>
|
||
|
|
||
|
<h1><a class="header" href="#recent" id="recent">Experimental clang/llvm based build with nightly rust</a></h1>
|
||
|
<p class="subtitle"><strong>2020-11-24</strong></p>
|
||
|
<p>Ok, so this little side track has been on a slow burn for a while now, but I've currently got a rootfs that I can chroot into with the following features:</p>
|
||
|
<ul>
|
||
|
<li>Built almost entirely with llvm/clang (see caveats below)</li>
|
||
|
<li>Rust nightly compiler installed early in the build, accessible for all users</li>
|
||
|
</ul>
|
||
|
<span id="continue-reading"></span>
|
||
|
<ul>
|
||
|
<li>Directory hierarchy flattened, directories in /usr are symlinks to directories in /</li>
|
||
|
<li>libc++ standard C++ library from the llvm project instead of libstdc++ from gcc</li>
|
||
|
<li>Both GNU binutils and the lld linker installed (default is still binutils ld for now)</li>
|
||
|
<li>x86_64 only at this time, but should be portable to Arm
|
||
|
Some caveats:</li>
|
||
|
<li>llvm/clang wants to build against libstdc++, so not self hosting unless we go back to libstdc++</li>
|
||
|
<li>There were issues building the compiler-rt module, so llvm and clang link against libgcc</li>
|
||
|
<li>The GNU m4 package will not build with clang, so it had to be built with the gcc compiler from the temporary toolchain. I'm sure this is fixable, but I haven't researched it much yet.</li>
|
||
|
<li>The biggie: glibc refuses to try to build with any compiler except gcc. The. Sheer. Fucking. Hubris. ...again...
|
||
|
Nevertheless, this is all quite promising and brings up a number of possibilities going forward. As llvm by default supports multiple backends for code generation, a huge benefit is that HitchHiker would come out of the box with cross compilation ability. Also, including rust by default gives us the ability to use Rust code in the base system, with numerous potential benefits that I will explain below.</li>
|
||
|
</ul>
|
||
|
<p>The directory hierarchy is simple to understand, but is reversed in implementation from what the "big" distros have done. Basically most "modern" distros have ditched the /usr split by making /bin and /lib into symlinks to /usr/bin and /usr/lib. In this build we instead just give all programs a blank install prefix. Our root directory now takes not only all of our binaries and libraries but also has program data under /share, and we only have /usr because it is expected. everything in /usr is, in fact, just symlinks.</p>
|
||
|
<p>Rust is installed in a novel way using rustup. As root, we set the RUSTUP_HOME and CARGO_HOME environment variables to /rust, and make /rust/bin a symlink to /bin. That way, we can track a nightly toolchain system-wide and it will install binaries into /bin, for all users to access. We could, of course, build rustc from source, and I have in fact done so previously. However, apart from the ridiculous compilation time that it takes, this is not a great option until the language is truly stable, as a lot of the interesting bits if the Rust ecosystem need something newer than the stable branch. By using rustup and the binary toolchains, we always have access to the most up to date toolchain, and the ability to easily switch from one to another.</p>
|
||
|
<p>So what are the benefits of having rust available early on? For starters Rust can access C functions and export functions to C, making it relatively easy to replace parts of the software stack previously written in C with Rust code that enjoys the memory and concurrency safety checks which are not present in C. As an example, relibc is a complete C standard library written in Rust. This alternative C library is a potential future path of investigation. But on a smaller scale, there are a number of interesting cli utilities and programs written in Rust.</p>
|
||
|
<ul>
|
||
|
<li>sd is a stream editor similar to sed, but much faster and with a much easier syntax and reduced scope.</li>
|
||
|
<li>fd is a file finding utility which is orders of magnitude faster than find, and has interesting features like skipping .git folders by default.</li>
|
||
|
<li>exa is a file lister with some unique features over ls</li>
|
||
|
<li>The amp editor, while somewhat vi-like, has interesting extra features fuzzy file finder and a token based jump which make moving around even faster than vim.
|
||
|
I have also begun, partially as a learning exercise, writing my own Rust implementations of various small Unix utilities. In the future some may find their way into HitchHiker if we retain Rust in the base system.</li>
|
||
|
</ul>
|
||
|
<p>While this is still in an early evaluation phase, I think it likely that at the very least we will make the switch from gcc to clang/llvm at some future point, with the possibility of bringing some of the other features along as well. What may not make the cut is libstdc++, as replacing the C++ standard library is almost as problematic as replacing the C standard library, leading to the need to port a large amount of third party software in the future. However, I will likely be going further with Rust, and with the flattened filesystem, as I want HItchHiker to be a cutting edge distro while still adhering to traditional Unix practices. Basically, we're going to push the envelope when it makes sense to do so, but not follow fads and trends in the Linux community that might very well be dead ends (like I believe Systemd in particular to be).</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<p class="subtitle"><strong>Tags for this post:</strong></p>
|
||
|
|
||
|
<a class="tags" href="/tags/c-programming/">C Programming</a>
|
||
|
|
||
|
<a class="tags" href="/tags/rust/">Rust</a>
|
||
|
|
||
|
<a class="tags" href="/tags/llvm/">llvm</a>
|
||
|
|
||
|
<a class="tags" href="/tags/clang/">Clang</a>
|
||
|
|
||
|
<a class="tags" href="/tags/nongnu/">NonGNU</a>
|
||
|
|
||
|
<a class="tags" href="/tags/packages/">Packages</a>
|
||
|
|
||
|
|
||
|
|
||
|
</main>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<script>
|
||
|
(function themes() {
|
||
|
var html = document.querySelector('html');
|
||
|
var themeToggleButton = document.getElementById('theme-toggle');
|
||
|
var themePopup = document.getElementById('theme-list');
|
||
|
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||
|
var stylesheets = {
|
||
|
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||
|
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||
|
highlight: document.querySelector("[href$='highlight.css']"),
|
||
|
};
|
||
|
|
||
|
function showThemes() {
|
||
|
themePopup.style.display = 'block';
|
||
|
themeToggleButton.setAttribute('aria-expanded', true);
|
||
|
themePopup.querySelector("button#" + get_theme()).focus();
|
||
|
}
|
||
|
|
||
|
function hideThemes() {
|
||
|
themePopup.style.display = 'none';
|
||
|
themeToggleButton.setAttribute('aria-expanded', false);
|
||
|
themeToggleButton.focus();
|
||
|
}
|
||
|
|
||
|
function get_theme() {
|
||
|
var theme;
|
||
|
try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
|
||
|
if (theme === null || theme === undefined) {
|
||
|
return default_theme;
|
||
|
} else {
|
||
|
return theme;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function set_theme(theme, store = true) {
|
||
|
let ace_theme;
|
||
|
|
||
|
if (theme == 'coal' || theme == 'navy') {
|
||
|
stylesheets.ayuHighlight.disabled = true;
|
||
|
stylesheets.tomorrowNight.disabled = false;
|
||
|
stylesheets.highlight.disabled = true;
|
||
|
|
||
|
ace_theme = "ace/theme/tomorrow_night";
|
||
|
} else if (theme == 'ayu') {
|
||
|
stylesheets.ayuHighlight.disabled = false;
|
||
|
stylesheets.tomorrowNight.disabled = true;
|
||
|
stylesheets.highlight.disabled = true;
|
||
|
ace_theme = "ace/theme/tomorrow_night";
|
||
|
} else {
|
||
|
stylesheets.ayuHighlight.disabled = true;
|
||
|
stylesheets.tomorrowNight.disabled = true;
|
||
|
stylesheets.highlight.disabled = false;
|
||
|
ace_theme = "ace/theme/dawn";
|
||
|
}
|
||
|
|
||
|
setTimeout(function () {
|
||
|
themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
|
||
|
}, 1);
|
||
|
|
||
|
if (window.ace && window.editors) {
|
||
|
window.editors.forEach(function (editor) {
|
||
|
editor.setTheme(ace_theme);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var previousTheme = get_theme();
|
||
|
|
||
|
if (store) {
|
||
|
try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
|
||
|
}
|
||
|
|
||
|
html.classList.remove(previousTheme);
|
||
|
html.classList.add(theme);
|
||
|
}
|
||
|
|
||
|
// Set theme
|
||
|
var theme = get_theme();
|
||
|
|
||
|
set_theme(theme, false);
|
||
|
|
||
|
themeToggleButton.addEventListener('click', function () {
|
||
|
if (themePopup.style.display === 'block') {
|
||
|
hideThemes();
|
||
|
} else {
|
||
|
showThemes();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
themePopup.addEventListener('click', function (e) {
|
||
|
var theme = e.target.id || e.target.parentElement.id;
|
||
|
set_theme(theme);
|
||
|
});
|
||
|
|
||
|
themePopup.addEventListener('focusout', function(e) {
|
||
|
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||
|
if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
|
||
|
hideThemes();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
|
||
|
document.addEventListener('click', function(e) {
|
||
|
if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
|
||
|
hideThemes();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
document.addEventListener('keydown', function (e) {
|
||
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
|
||
|
if (!themePopup.contains(e.target)) { return; }
|
||
|
|
||
|
switch (e.key) {
|
||
|
case 'Escape':
|
||
|
e.preventDefault();
|
||
|
hideThemes();
|
||
|
break;
|
||
|
case 'ArrowUp':
|
||
|
e.preventDefault();
|
||
|
var li = document.activeElement.parentElement;
|
||
|
if (li && li.previousElementSibling) {
|
||
|
li.previousElementSibling.querySelector('button').focus();
|
||
|
}
|
||
|
break;
|
||
|
case 'ArrowDown':
|
||
|
e.preventDefault();
|
||
|
var li = document.activeElement.parentElement;
|
||
|
if (li && li.nextElementSibling) {
|
||
|
li.nextElementSibling.querySelector('button').focus();
|
||
|
}
|
||
|
break;
|
||
|
case 'Home':
|
||
|
e.preventDefault();
|
||
|
themePopup.querySelector('li:first-child button').focus();
|
||
|
break;
|
||
|
case 'End':
|
||
|
e.preventDefault();
|
||
|
themePopup.querySelector('li:last-child button').focus();
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
})();
|
||
|
|
||
|
(function sidebar() {
|
||
|
var html = document.querySelector("html");
|
||
|
var sidebar = document.getElementById("sidebar");
|
||
|
var sidebarLinks = document.querySelectorAll('#sidebar a');
|
||
|
var sidebarToggleButton = document.getElementById("sidebar-toggle");
|
||
|
var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
|
||
|
var firstContact = null;
|
||
|
|
||
|
function showSidebar() {
|
||
|
html.classList.remove('sidebar-hidden')
|
||
|
html.classList.add('sidebar-visible');
|
||
|
Array.from(sidebarLinks).forEach(function (link) {
|
||
|
link.setAttribute('tabIndex', 0);
|
||
|
});
|
||
|
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||
|
sidebar.setAttribute('aria-hidden', false);
|
||
|
try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
|
||
|
}
|
||
|
|
||
|
|
||
|
var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
|
||
|
|
||
|
function toggleSection(ev) {
|
||
|
ev.currentTarget.parentElement.classList.toggle('expanded');
|
||
|
}
|
||
|
|
||
|
Array.from(sidebarAnchorToggles).forEach(function (el) {
|
||
|
el.addEventListener('click', toggleSection);
|
||
|
});
|
||
|
|
||
|
function hideSidebar() {
|
||
|
html.classList.remove('sidebar-visible')
|
||
|
html.classList.add('sidebar-hidden');
|
||
|
Array.from(sidebarLinks).forEach(function (link) {
|
||
|
link.setAttribute('tabIndex', -1);
|
||
|
});
|
||
|
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||
|
sidebar.setAttribute('aria-hidden', true);
|
||
|
try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
|
||
|
}
|
||
|
|
||
|
// Toggle sidebar
|
||
|
sidebarToggleButton.addEventListener('click', function sidebarToggle() {
|
||
|
if (html.classList.contains("sidebar-hidden")) {
|
||
|
var current_width = parseInt(
|
||
|
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||
|
if (current_width < 150) {
|
||
|
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||
|
}
|
||
|
showSidebar();
|
||
|
} else if (html.classList.contains("sidebar-visible")) {
|
||
|
hideSidebar();
|
||
|
} else {
|
||
|
if (getComputedStyle(sidebar)['transform'] === 'none') {
|
||
|
hideSidebar();
|
||
|
} else {
|
||
|
showSidebar();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||
|
|
||
|
function initResize(e) {
|
||
|
window.addEventListener('mousemove', resize, false);
|
||
|
window.addEventListener('mouseup', stopResize, false);
|
||
|
html.classList.add('sidebar-resizing');
|
||
|
}
|
||
|
function resize(e) {
|
||
|
var pos = (e.clientX - sidebar.offsetLeft);
|
||
|
if (pos < 20) {
|
||
|
hideSidebar();
|
||
|
} else {
|
||
|
if (html.classList.contains("sidebar-hidden")) {
|
||
|
showSidebar();
|
||
|
}
|
||
|
pos = Math.min(pos, window.innerWidth - 100);
|
||
|
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
|
||
|
}
|
||
|
}
|
||
|
//on mouseup remove windows functions mousemove & mouseup
|
||
|
function stopResize(e) {
|
||
|
html.classList.remove('sidebar-resizing');
|
||
|
window.removeEventListener('mousemove', resize, false);
|
||
|
window.removeEventListener('mouseup', stopResize, false);
|
||
|
}
|
||
|
|
||
|
document.addEventListener('touchstart', function (e) {
|
||
|
firstContact = {
|
||
|
x: e.touches[0].clientX,
|
||
|
time: Date.now()
|
||
|
};
|
||
|
}, { passive: true });
|
||
|
|
||
|
document.addEventListener('touchmove', function (e) {
|
||
|
if (!firstContact)
|
||
|
return;
|
||
|
|
||
|
var curX = e.touches[0].clientX;
|
||
|
var xDiff = curX - firstContact.x,
|
||
|
tDiff = Date.now() - firstContact.time;
|
||
|
|
||
|
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||
|
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
|
||
|
showSidebar();
|
||
|
else if (xDiff < 0 && curX < 300)
|
||
|
hideSidebar();
|
||
|
|
||
|
firstContact = null;
|
||
|
}
|
||
|
}, { passive: true });
|
||
|
|
||
|
// Scroll sidebar to current active section
|
||
|
var activeSection = document.getElementById("sidebar").querySelector(".active");
|
||
|
if (activeSection) {
|
||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
|
||
|
activeSection.scrollIntoView({ block: 'center' });
|
||
|
}
|
||
|
})();
|
||
|
</script>
|
||
|
|
||
|
</body>
|
||
|
|
||
|
</html>
|