433 lines
19 KiB
HTML
433 lines
19 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">Continued porting of BSD userland against remaining self-hosting</a></h1>
|
||
|
<p class="subtitle"><strong>2020-09-03</strong></p>
|
||
|
<p>At this juncture we're well over the halfway point in regards to providing a predominately BSD userland in HitchHiker, with over 90 console utilities ported against a total of 59 remaining programs brought in from GNU coreutils. That total includes<span id="continue-reading"></span>, of course, some programs that are not included in GNU coreutils. Some of the utilities replace standalone GNU packages, such as grep and diff, while some are utilities that may not be present on most Linux distributions, such as pax or leave. In general, the BSD utilities have compatible functionality, as both GNU and BSD have mostly embraced the POSIX standard, but with a few caveats where there are extensions made to the standard. The biggest differences reflect a difference in philosophy, as the BSD utils are quite small and include only what they must, while the GNU versions are all (yes all) larger and accept more options. GNU particularly accept long options and in general have better internationalization. The GNU utilities also accept the --help option, giving a brief summary of their function. BSD utilities specifically omit this functionality, as each command comes with a man page, which would duplicate functionality.</p>
|
||
|
<p>One of the dangers in just blindly replacing the usual GNU userland on Linux is that when the accepted options differ slightly, some scripts may not run as expected. This also can affect building packages from source if care is not taken to stick with only POSIX specified options when writing Makefiles. To some extent I have been working to minimize the effects here by taking the time to verify each utility works as expected and in some cases implementing options that most users expect, such as the -v switch (verbose) for the ln and rmdir utilities. In other cases, such as the much abused -a or --preserve-attributes options of GNU cp, implementing equivalent functionality in the BSD port is definitely non-trivial, and many people are just trying to copy directories recursively while preserving symlinks when they use 'cp -a', and not actually wanting to preserve ownership or modification times. Those cases can be served by using BSD cp as 'cp -R'. If preserving attributes is the desired behavior, then this is one of the tradeoffs being made and extra steps will have to be taken with chown and touch.</p>
|
||
|
<p>In order to ensure that HitchHiker always remains self-hosting I have been running bootstrapping the system from itself multiple times during the porting effort. A few issues have been found and fixed along the way, but it has been an overall smooth transition. In one case, I had actually misused 'cp -a' myself in the busybox build (busybox is only built as part of the temporary toolchain).</p>
|
||
|
<p>One particularly special case is glibc, which has a hard dependency on GNU awk during build time. As I have a preference for the historical (yet still maintained) Nawk, this requires building a statically compiled Gawk early in the bootstrap process as part of the temporary tools in /toolchain, which is discarded along with the rest of the temporary tools after the bootstrap phase and does not become part of the base system. Another example of the "Sheer F%$king Hubris" of much GNU software, which often will only build with other GNU tools, even though other tools exist with equivalent (and sometimes superior) functionality.</p>
|
||
|
|
||
|
|
||
|
<hr>
|
||
|
<p class="subtitle"><strong>Tags for this post:</strong></p>
|
||
|
|
||
|
<a class="tags" href="/tags/porting/">Porting</a>
|
||
|
|
||
|
<a class="tags" href="/tags/roadmap/">Roadmap</a>
|
||
|
|
||
|
<a class="tags" href="/tags/nongnu/">NonGNU</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>
|