Skip to content

Instantly share code, notes, and snippets.

@aghasemi
Last active October 26, 2016 08:45
Show Gist options
  • Save aghasemi/4540982c9ec71e09856c18cee7c38d96 to your computer and use it in GitHub Desktop.
Save aghasemi/4540982c9ec71e09856c18cee7c38d96 to your computer and use it in GitHub Desktop.
Brewstrap installer script for ChromiumOS devices
#Believe it or not, you _can_ install Homebrew/Linuxbrew on your shiny new Chromebook without [dual-booting](http://chromeos-cr48.blogspot.fr/) or [chrooting](https://github.com/dnschneid/crouton) another operating system like Ubuntu; nay, you can enjoy the goodness of CLI programs like `vim`, `zsh`, `ruby` , and all the other goodies Linuxbrew has to offer (not to mention anything you can compile from source) while still being able to flaunt your fancy Chrome OS GUI. So let's get started.
#**NOTE STILL IN PROGRESS EVERYTHING SHOULD WORK UNTIL GCC**
#> **Disclaimer**
#> This guide is still in progress and has only been tested on an Acer C720P, so results may vary with other Chromebooks, especially those with other architectures (sorry ARM).
#Prerequisites
#====================
#If you just opened up your factory-fresh Chromebook, the first thing you have to do is [enable developer mode](http://www.cnet.com/how-to/how-to-enable-developer-mode-on-a-chromebook/). If that guide doesn't help do a google search for device specific instructions; it shouldn't be too hard.
#Next, you're probably gonna want to install [Secure Shell](https://chrome.google.com/webstore/detail/secure-shell/pnhechapfaindjhompbnflcldabbghjo?hl=en-US&utm_source=chrome-ntp-launcher) so you can get at [Crosh Window](https://chrome.google.com/webstore/detail/crosh-window/nhbmpbdladcchdhkemlojfjdknjadhmh?hl=en-US&utm_source=chrome-ntp-launcher). This way you can have [multiple windows](https://github.com/adlr/croshwindow/issues/3).
#Now that we have a terminal we can really get crackin'.
#[Chromebrew](https://skycocker.github.io/chromebrew/)
#=============
#There are a couple of obstacles to installing Linuxbrew, or even anything at all, on a Chromebook. First of all, you have very limited permissions. Even with `sudo`, you only have write permissions in your home folder, `/home/chronos/user`, and `/usr/local`. To make matters worse, you can't execute anything in your home folder; it has to be in `/usr/local`. Not even with `chmod +x`, the problem is with the permissions it is mounted with by the Chrome OS system. One solution is to disable rootfs verification, but if we are clever, we don't have to be so heavy handed.
#The other main issue is that Chrome OS currently does not ship with a compiler, which makes building anything from source impossible. Luckily, the folks over at [Chromebrew](https://skycocker.github.io/chromebrew), which is a package manager exclusively for Chromebooks, cross-compiled the whole gcc toolchain, as well as some other stuff like `ruby` and `git`. We're going to use that to bootstrap our Linuxbrew installation, and then install new versions of everything using Linuxbrew so we can delete Chromebrew completely by the end.
#Enough talk, let's do. Install Chromebrew with
read -p "Press Enter to continue"
wget -q -O - https://raw.github.com/skycocker/chromebrew/master/install.sh | bash
sudo chown -R chronos:chronos /usr/local
#```
#This may take a while depending on your internet speed.
#When it's done, restart your Chromebook (it only takes 10 seconds!). I'm not sure why this is necessary, but whenever there's a weird problem it's usually because I forgot to restart after I installed Chromebrew.
#Linuxbrew Setup
#================
#You're back? Let's get Linuxbrew going right away.
read -p "Press Enter to continue"
export prefix=/usr/local/linuxbrew
git clone https://github.com/Homebrew/linuxbrew.git $prefix
#```
#We need to symlink our Chromebrew `gcc` so Linuxbrew can use it.
read -p "Press Enter to continue"
mkdir $prefix/lib
ln -s $(which gcc) $prefix/bin/gcc-$(gcc -dumpversion | cut -d. -f1,2)
ln -s $(which g++) $prefix/bin/g++-$(g++ -dumpversion | cut -d. -f1,2)
#```
#Now we need to create a temporary directory for Linuxbrew special because the default location is `/tmp`, and we don't have write permissions there.
read -p "Press Enter to continue"
mkdir $prefix/tmp
export HOMEBREW_TEMP=$prefix/tmp
#```
#Now we need to modify our environment a bit to make Linuxbrew happy. I repeated some commands because they need to be run for every new terminal session, so either copy-paste each time or edit your `.bash_profile`.
read -p "Press Enter to continue"
export prefix=/usr/local/linuxbrew # wherever you want linuxbrew, but it better be somewhere in /usr/local
PATH="$prefix/bin:$prefix/sbin:$PATH"
export HOMEBREW_TEMP=$prefix/tmp
unset LD_LIBRARY_PATH
#```
#Let's see if everything is working. For now to make `gcc` work right we need to temporarily set `LD_LIBRARY_PATH`.
read -p "Press Enter to continue"
export LD_LIBRARY_PATH=/usr/local/lib
brew install hello && brew test hello && brew remove hello
unset LD_LIBRARY_PATH
#```
#If everything is working that should produce something along the lines of
#=> Downloading http://ftpmirror.gnu.org/hello/hello-2.10.tar.gz
#Already downloaded: /home/chronos/user/.cache/Homebrew/hello-2.10.tar.gz
#==> ./configure --disable-silent-rules --prefix=/usr/local/linuxbrew/Cellar/hello/2.10
#==> make install
#/usr/local/linuxbrew/Cellar/hello/2.10: 52 files, 692K, built in 18 seconds
#Testing hello
#==> /usr/local/linuxbrew/Cellar/hello/2.10/bin/hello --next-generation --greeting=brew
#Uninstalling /usr/local/linuxbrew/Cellar/hello/2.10...
#Now we need to modify some of the more vital programs we just installed so they always know where to look for libraries. They usually taking cues from the environment variable `LD_LIBRARY_PATH`, but Linuxbrew doesn't work well if `LD_LIBRARY_PATH` is set. Instead, we'll tell them where to find libraries by setting the rpath using `patchelf`, but first we have to install it.
read -p "Press Enter to continue"
export LD_LIBRARY_PATH=/usr/local/lib
brew install patchelf
unset LD_LIBRARY_PATH
#```
#You should now have the `patchelf` command. Now use it to set the rpath of `gcc` and `ruby`, which are vital to Linuxbrew and Chromebrew.
read -p "Press Enter to continue"
patchelf --set-rpath /usr/local/lib /usr/local/bin/gcc
patchelf --set-rpath /usr/local/lib /usr/local/bin/g++
patchelf --set-rpath /usr/local/lib /usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.8.1/cc1
patchelf --set-rpath /usr/local/lib /usr/local/libexec/gcc/x86_64-unknown-linux-gnu/4.8.1/cc1plus
patchelf --set-rpath /usr/local/lib /usr/local/bin/ruby
patchelf --set-rpath /usr/local/lib /usr/local/lib/ruby/2.0.0/x86_64-linux/digest/sha1.so
patchelf --set-rpath /usr/local/lib /usr/local/lib/ruby/2.0.0/x86_64-linux/digest/sha2.so
#```
#Now everything should be working without pesky `LD_LIBRARY_PATH`
read -p "Press Enter to continue"
brew install hello && brew test hello && brew remove hello
#```
#Our Very Own Toolchain
=======================
#We're doing alright, but to be honest, Linuxbrew and Chromebrew's toolchain aren't crazy about each other. Let's install a new one with Linuxbrew now that we have it functioning. The lines are separated based into programs and their dependencies, but as long as you preserve the order, you can combine all those `brew install yadayadas` if you feel like it.
read -p "Press Enter to continue"
brew tap homebrew/dupes
brew install diffutils binutils # SEE NOTES ON BOTTOM
brew install m4 gmp
brew install gpatch flex bison libmpc
brew install mpfr
brew install gawk glibc
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 brew postinstall glibc
brew unlink glibc
ln -s /lib64/libz.so.1 /usr/local/linuxbrew/lib/
brew install zlib
rm /usr/local/linuxbrew/lib/libz.so.1
brew link zlib
#```
#Now we have all the prerequisites for `gcc`, but first we need to reinstall _everything_ so that it will link with the `glibc` we just installed.
read -p "Press Enter to continue"
brew list | grep -v "glibc\|zlib" | xargs brew reinstall # takes a long time to reinstall everything
brew link glibc
#```
#Now we're ready to install `gcc`.
read -p "Press Enter to continue"
ln -s /usr/local/lib64/libstdc++.so.6 /usr/local/linuxbrew/lib/
brew install gcc --with-glibc -v
rm /usr/local/linuxbrew/lib/libstdc++.so.6
brew link gcc
export HOMEBREW_CC=gcc-4.9
brew install hello && brew test hello && brew remove hello
#```
#Now we're almost done. We just need a few more things that Chromebrew provides, like `perl`, `ruby`, and `git` that are vital to Linuxbrew.
read -p "Press Enter to continue"
brew install perl
brew install tcl-tk --without-tk
brew install curl expat git
brew install bzip2 coreutils findutils gawk gnu-sed gnu-which grep libpng libxml2 libxslt make ncurses readline texinfo --default-names --with-default-names
ln -s ncursesw/curses.h ncursesw/ncurses.h ncursesw/term.h ncursesw/termcap.h $prefix/include/
brew install ruby
brew install python
#```
#Now we can remove the old Chromebrew stuff.
read -p "Press Enter to continue"
cd /usr/local/
ls | grep -v "linuxbrew" | xargs rm -rf
brew install hello && brew test hello && brew remove hello
#```
#If you want you can symlink everything into `/usr/local`, because if you actually move it all the `rpath`s are wrong.
read -p "Press Enter to continue"
ln -s linuxbrew/* /usr/local
#```
### Notes
#- `binutils` and `gcc` need a [pull request](https://github.com/Homebrew/linuxbrew/pull/200)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment