Skip to content

Tools, things, stuff, miscellaneous, etc., for Chrome OS / Chromium OS

Notifications You must be signed in to change notification settings

ryanwoodsmall/crosware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

crosware

Tools, things, stuff, miscellaneous, detritus, junk, etc., primarily for Chrome OS / Chromium OS. This is a development-ish environment for Chrome OS on both ARM and x86 (32-bit and 64-bit for both). It should work on "normal" Linux too (Armbian, CentOS, Debian, Raspbian, Ubuntu, etc.).

bootstrap

If running on a Chromebook/Chromebox/ChromeOS/Flex machine, developer mode is necessary. crosware temporarily requires root access to set ownership and permission in /usr/local.

To bootstrap, using /usr/local/crosware with initial downloads in /usr/local/tmp...

⚠️ On ChromeOS sudo must be run via a virtual terminal ⚠️

Google, in their infinite wisdom, has disabled sudo on ChromeOS. Or, rather, disabled gaining extra privileges in the current process (PR_SET_NO_NEW_PRIVS/minijail/???). This effectively stops root user access via the ChromeOS GUI.

This means the sudo commands below must be run via a VT.

  • To access a VT, press one of the following key sequences:
    • Ctrl-Alt-right arrow (F2)
    • Ctrl-Alt-refresh (F3)
    • Ctrl-Alt-full screen (F4)
  • Login as chronos either with no password, or with a dev password (if you set one)
  • Run the sudo ... commands below
  • Return to the ChromeOS GUI with Ctrl-Alt-back arrow (F1)

If you want to start a locally-accessible SSH daemon, see: scripts/start-root-sshd.

# check you're the chronos user on a chromebook/not root in a container
whoami

# allow your regular user to write to /usr/local
sudo chgrp ${GROUPS} /usr/local
sudo chmod 2775 /usr/local

The sudo commands above only need to be run once; it should be safe to run them again. If you choose to use the scripts/start-root-sshd script, it must be run after every reboot.

The following can now be run as the standard ChromeOS user chronos from a GUI/crosh shell terminal.

# run the bootstrap
# use curl to download the primary shell script
# this in turn downloads a jdk, jgit and a toolchain
bash <(curl -kLs https://raw.githubusercontent.com/ryanwoodsmall/crosware/master/bin/crosware) bootstrap

# source the environment
source /usr/local/crosware/etc/profile
which crosware

install some packages

# install some stuff
crosware install busybox toybox

# update environment
source /usr/local/crosware/etc/profile

# see what we just installed
which -a make busybox toybox \
| xargs realpath \
| xargs toybox file

# automatically update the environment after an install
`${cwtop}/scripts/tcrs jo`
which -a jo

update

To get new recipes:

crosware update

And to re-bootstrap (for any updated zulu, jgitsh, statictoolchain installs):

crosware bootstrap

further usage

Run crosware without any arguments to see usage; i.e, a (possibly outdated) example:

usage: crosware [command]

commands:
  bootstrap : bootstrap crosware
  check-installed : given a package name, check if it's installed
  env : dump source-/eval-able crosware etc/profile
  help : show help
  install : attempt to build/install a package from a known recipe
  list-available : list available recipes which are not installed
  list-funcs : list crosware shell functions
  list-installed : list installed recipes
  list-installed-reqs : list installed recipes with their requirements
  list-recipe-deps : list recipes with their declared dependencies
  list-recipe-files : list recipes with their source file
  list-recipe-reqs : list recipes with their requirements
  list-recipe-reqs-expanded : list recipes with their expanded requirements
  list-recipes : list build recipes
  list-recipe-transitive-reqs : list recipes with only transitive requirements
  list-recipe-versions : list recipes with version number
  list-upgradable : list installed packages with available upgrades
  profile : show .profile addition
  reinstall : uninstall then install given packages without chasing upgrades
  run-func : run crosware shell function
  set : run 'set' to show full crosware environment
  show-arch : show kernel and userspace architecture
  show-env : run 'env' to show crosware environment
  show-func : show the given function name
  show-karch : show kernel architecture
  show-uarch : show userspace architecture
  uninstall : uninstall some packages
  update : attempt to update existing install of crosware
  update-list-upgradable : update crosware and list upgradable recipes
  update-upgrade-all : update crosware and upgrade out-of-date recipes
  upgrade : uninstall then install a recipe
  upgrade-all : upgrade all packages with different recipe versions
  upgrade-all-with-deps : upgrade all out-of-date packages and installed dependents
  upgrade-deps : upgrade any installed deps of a package
  upgrade-with-deps : upgrade a package and installed depdendents

a few more examples

See the scripts/ directory for a hodge-podge of stuff.

# works anywhere - for use system-wide on a normal non-chromeos linux distro (non-root users only)
sudo ln -sf /usr/local/crosware/scripts/etc-profile-dot-d_crosware.sh /etc/profile.d/zz-crosware.sh

# works anywhere - remove dev bits ({C,LD,...}FLAGS, etc.) from the environment
# also move crosware paths to the end of ${PATH}
# facilitates "i just want the command" installs
. /usr/local/crosware/etc/profile
. ${cwtop}/scripts/non-interactive.sh

# chromeos only - when using the scripts/start-root-sshd script
# for sudossh (non-interactive) and sudossht (terminal) command wrappers
sudo ln -sf /usr/local/crosware/scripts/usr-local-bin-sudossh /usr/local/bin/sudossh
sudo ln -sf /usr/local/crosware/scripts/usr-local-bin-sudossht /usr/local/bin/sudossht

# chromeos only? - obsolete on chromeos but good to note anyway
# wrap sudo to be passwordless with a trust-on-first-use approach
# this is (well, was) useful for dev-mode chromebooks with a chronos user password set
. /usr/local/crosware/scripts/passwordless-sudo.sh

use external or disable java and jgit

A few user environment variables are available to control how crosware checks itself out and updates recipes.

var default purpose
CW_GIT_CMD jgitsh which "git" command to use for checkout/update
CW_USE_JAVA true use java for bootstrap, jgit
CW_EXT_JAVA false use system java instead of zulu recipe
CW_USE_JGIT true use jgit.sh for checkout/update
CW_EXT_JGIT false use system jgit.sh instead of jgitsh recipe
CW_UPDATE_USE_GIT true use a git client to update
CW_UPDATE_USE_ZIP true use update-crosware-from-zip.sh to update
CW_IGNORE_MISSING false set to "true" ot ignore any missing prereqs

alpine

Alpine (https://alpinelinux.org/) uses musl libc (http://musl-libc.org) and as such cannot use the Zulu JDK as distributed. To bootstrap using the system-supplied OpenJDK from Alpine repos:

# as above, make sure /usr/local is writable by the primary user/group you'll be using...
# this assumes you're using the default busybox ash shell, and running apk as root...
export CW_EXT_JAVA=true
apk update
apk upgrade
apk add bash curl openjdk11
cd /tmp
curl -kLO https://raw.githubusercontent.com/ryanwoodsmall/crosware/master/bin/crosware
bash crosware bootstrap
# or, using bash process substitution...
#   bash -c 'export CW_EXT_JAVA=true ; bash <(curl -kLs https://raw.githubusercontent.com/ryanwoodsmall/crosware/master/bin/crosware) bootstrap'

Make sure the environment variable CW_EXT_JAVA is set to true (or just something other than false) to use system Java. Please note that /usr/local/crosware/etc/profile contains bashisms, and does not work on BusyBox ash, so set your SHELL accordingly.

If Zulu is installed on a non-glibc distro, run crosware uninstall zulu and make sure CW_EXT_JAVA and JAVA_HOME environment variables are configured.

To manually remove the Zulu install directory, environment script and installation flag, remove these paths:

  • /usr/local/crosware/etc/profile.d/zulu.sh
  • /usr/local/crosware/var/inst/zulu
  • /usr/local/crosware/software/zulu/

container

A container suitable for bootstrapping is available:

Run with:

docker run -it ryanwoodsmall/crosware

An interactive bash shell session will start, and any crosware C/C++ packages should build and run out of the box.

Build with something like:

docker build --tag crosware https://raw.githubusercontent.com/ryanwoodsmall/dockerfiles/master/crosware/Dockerfile
docker run -it crosware

Inside the container, install git to enable updates and list any upgradable packages:

# note: this installs git and its prereqs from source, it might take awhile
crosware install git
. /usr/local/crosware/etc/profile
crosware update
crosware list-upgradable

notes

This is a mostly self-hosting virtual Linux distribution of sorts, targeting all variations of 32-/64-bit x86 and ARM on Chrome OS, installable on other Linux distributions independently - with riscv64 support as well. The primary aim of crosware is to be a small - for some definition of small - and "as statically-linked as possible" development environment aimed at containers and ChromeOS, but also piggybacking on virtually any distribution that has a persistent /usr/local with write permissions.

A static-only GCC compiler using musl libc (with musl-cross-make ) is installed as part of the bootstrap; this sort of precludes things like emacs, but doesn't stop anyone from using the static musl toolchain to build a shared toolchain and libraries, bootstrap another compiler, leverage Alpine packages, etc.. Despite having "static" in the name, a libc.so (and ld.so, normally a symlink to musl's libc) is available and leveraged for a number packages, primarily to support other programming languages' linking modes and plugin/shared object strategies.

The initial bootstrap looks something like:

  • scripted, i.e., crosware bootstrap:
    • get a JDK (Azul Zulu OpenJDK for glibc)
    • get jgit.sh (standalone)
    • get static bootstrapped compiler
    • checkout rest of project
  • manually install some packages, i.e, crosware install vim git ...:
    • build GNU make
    • build native busybox, toolbox, sed, etc.
    • build a few libs / support (ncurses, openssl, slang, zlib, bzip2, lzma, libevent, pkg-config)
    • build a few packages (curl, vim w/syntax hightlighting, screen, tmux, links, lynx - mostly because I use them)

Some scripts that might be use for bootstrapping on a non-glibc distro:

environment

Environment stuff to figure out how to handle:

  • PATH (working)
  • PKG_CONFIG_LIBDIR/PKG_CONFIG_PATH (working)
  • CC (working)
  • CFLAGS (working)
  • CPP (working)
  • CPPFLAGS (working)
  • CXX (working)
  • INFOPATH
  • LDFLAGS (working)
  • MANPAGER (working)
  • MANPATH
  • ACLOCAL_PATH
  • EDITOR (vim?)
  • PAGER (working, set to less (gnu or busybox))

stuff to figure out

See the to-do list (TODO.md)

See the maybe file (MAYBE.md) for recipes to consider, notes, etc.

links

Chromebrew looks nice and exists now: https://github.com/skycocker/chromebrew

Alpine and Sabotage are good sources of inspiration and patches:

The Alpine folks distribute a chroot installer:

And I wrote a little quick/dirty Alpine chroot creator that works on Chrome/Chromium OS; no Docker or other software necessary.

The musl wiki has some pointers on patches and compatibility, and a list of useful alternative implementations of common programs/libraries/utilities/etc.; many are in use in crosware:

bootstrapping ex nihilo

Mes (and m2) might be useful at some point.

other sites/utilities/etc.

Suckless has a list of good stuff:

Mark Williams Company open sourced Coherent; might be a good source for SUSv3/SUSv4/POSIX stuff:

9p implementations:

Eltanin tools may be useful:

Busybox tiny utility notes:

C/C++ compiler

Static musl GCC compiler(s) are done, and should work to compile (static-only, some shared lib support) binaries on Chrome OS:

Based on Rich Felker's musl-cross-make:

recipes

bootstrap recipes

These recipes are included in the main bin/crosware script, as they're the foundation of the tool and are distributed as binaries. There are a handful of other binary recipes that are not necessary for bootstrapping. The statictoolchain recipe could theoretically be pulled into a normal standalone recipe, but is bedrock enough that it fits in the main script. A smaller, more supportable, preferably single-binary static Git client would/will hopefully also find its way to the main script for bootstrap purposes.

working recipes

deprecated/broken/disabled recipes