hhl/public/news/reconfiguring-the-build-process/index.html

454 lines
19 KiB
HTML
Raw Normal View History

2021-02-19 22:43:36 -05:00
<!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="&#x2F;favicon.svg">
<link rel="shortcut icon" href="&#x2F;favicon.png">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;css&#x2F;variables.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;css&#x2F;general.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;css&#x2F;chrome.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;css&#x2F;print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="&#x2F;handbook&#x2F;FontAwesome&#x2F;css&#x2F;font-awesome.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;fonts&#x2F;fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="&#x2F;handbook&#x2F;highlight.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;tomorrow-night.css">
<link rel="stylesheet" href="&#x2F;handbook&#x2F;ayu-highlight.css">
<!-- Custom Stylesheets -->
<link rel="stylesheet" href="&#x2F;hhl.css">
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "&#x2F;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">Reconfiguring the build process</a></h1>
<p class="subtitle"><strong>2021-02-01</strong></p>
<p>Up until now HitchHiker has used a build process that closely followed that used
by the Linux From Scratch book. There was a temporary toolchain, hacked to use a
different library directory and prefix</p>
<span id="continue-reading"></span>
<p>so as not to conflict with the host system or with the libraries and tools being installed as the finished system. This temporary toolchain was in itself a complete development environment that included everything required to bootstrap a full system. To build to final system, is was necessary to chroot into a new directory containing the temporary tools and root filesystem.</p>
<p>This method had some advantages, but also involved compiling most packages at least twice. It also required quite a lot of extra work to do any kind of cross compiling. In fact, I had set up an RPI4 specifically as a compilation machine for Armv7l, as it was basically impractical to use my x86_64 laptop to develop for Arm.</p>
<p>In an effort to increase the flexibility of the HitchHiker build tree, support more architectures, and to streamline the build I am experimenting with using a sysroot compiler for the majority of the build. In testing, with minimal effort I was able to set up cross toolchains for armv7l, aarch64, riscv64, and i486 as well as a native x86_64 toolchain using the same build tree and only adjusting the ${arch} variable in config.mk. In testing I was able to compile almost the complete userland for x86_64, aarch64 and riscv64 without resorting to a chroot, and all on my main machine. My current plan is to compile most of the base system using a sysroot toolchain, either native or cross, including the build of the native toolchain, and then to chroot into the near complete root filesystem to finish up any packages that cannot be easily cross compiled. At this juncture I believe the only package in the base system that will be truly problematic for cross-compilation is Perl, which uses an ill conceived homegrown configure script instead of autotools. However this is not quite verified for all packages just yet.</p>
<p>In the case of a package refusing to cross-compile, I can then use the method outlined in the previous post and compile with the native toolchain using qemu user-mode emulation.</p>
<p>In addition to the vast reduction of packages being compiled twice or more, this also has the advantage of running on a fast machine. Additionally, with most of the work not requiring the chroot trick, there is no emulation layer to slow the process down. A future goal will be to fix the issues with Perl and push patches upstream if possible, as Perl is a hard build dependency of the kernel and therefore must be considered an essential part of the base system.</p>
<p>To give some idea of the resource savings this brings about, here's a quick table outlining the number of passes required for certain packages under the old layout vs the new. Note that it is still necessary to make multiple passes at Binutils and Gcc, as we have to build our sysroot/cross toolchain, but there is a rather significant reduction in the amount of other software being built twice.</p>
<table><thead><tr><th>Package</th><th>Passes (old)</th><th>Passes (new)</th></tr></thead><tbody>
<tr><td>Binutils</td><td>3</td><td>2</td></tr>
<tr><td>Gcc</td><td>3 + separate libstdc++ pass</td><td>3</td></tr>
<tr><td>Linux Headers</td><td>2</td><td>1</td></tr>
<tr><td>Glibc</td><td>2</td><td>1</td></tr>
<tr><td>M4</td><td>2</td><td>1</td></tr>
<tr><td>Ncurses</td><td>2</td><td>1</td></tr>
<tr><td>Bison</td><td>2</td><td>1</td></tr>
<tr><td>Diffutils</td><td>2</td><td>1</td></tr>
<tr><td>Gettext</td><td>2</td><td>1</td></tr>
<tr><td>Make</td><td>2</td><td>1</td></tr>
<tr><td>Perl</td><td>2</td><td>1</td></tr>
<tr><td>Python</td><td>2</td><td>1</td></tr>
<tr><td>Texinfo</td><td>2</td><td>1</td></tr>
<tr><td>Patch</td><td>2</td><td>1</td></tr>
<tr><td>Busybox</td><td>1</td><td>Not Built</td></tr>
</tbody></table>
<hr>
<p class="subtitle"><strong>Tags for this post:</strong></p>
<a class="tags" href="&#x2F;tags&#x2F;cross-compile&#x2F;">cross-compile</a>
<a class="tags" href="&#x2F;tags&#x2F;sysroot&#x2F;">sysroot</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>