I have been using Apple computers close to full time since mid-90's. Originally because I used Photoshop extensively for processing confocal microscope images and Macs were the standard platform for that. It helped that they were also relatively safe from viruses and generally stable. I switched to more computational work in the early 2000's, and Apple was right there with Mac OS X, which still is a great interface to a Unix-like system. I have owned an Apple laptop continuously since around 2000.
For me, the extra I had to pay for these laptops has been a good value for money. For one, the Apple premium was not that high given the specs. In addition, the quality of build, reliability, and excellent customer service were worth paying extra for. I also like the Apple design approach. My job involves writing open-source software for scientific applications. It has to be easily transferable to servers that usually run some version of Linux. Most of my colleagues, who are the target audience for my development, use Macs or Linux. The Unix flavor provided by Mac OS allows me write my code for any flavor of Unix, but there have always been pain points. For example, Apple moved to LLVM as the C/C++ compiler (I am a C++ developer), but the version they include is pretty old. It is possible to install GCC and most other things via third-party package managers (like Homebrew), but things do break every once in a while. Apple has always aimed for a tight integration of software and hardware, which is great for its users but not for portability. In short, while it is quite possible to use Macs for open-source development, this is not what Macs are designed for.
I put up with the (relatively minor) annoyances I was experiencing with Mac OS as a developer platform for two reasons: (1) I really liked the hardware and (2) I had software needs that were not directly related to development work but were required for other aspects of my job. On the hardware side, the Apple Retina displays changed my life. I have to stare at text on the screen most of the day, and the sharpness delivered by Retina very noticeably reduced eye fatigue for me. The other specs I care about (processor speed and RAM) have been good enough, and I do not use many external devices so was never upset about Apple's port shenanigans. On the software side, my colleagues (and, now that I am out on my own, my clients) use Microsoft products extensively. I have to be able to look at and edit these files. I occasionally need to make vector-graphic illustrations. I used to use the Illustrator from Adobe, but switched to Graphic, which is a lot cheaper and does everything I need (I am not really a power user). I use desktop replacement laptops because I work from different locations. I can do 95% of my computational work on a high-end laptop, and off-load to a server or AWS if a need for some really serious data processing arises.
Switching to System76
Over the past few years, many other manufacturers have started to catch up to Apple laptops in design and specs. Apple, on the other hand, seems focused on thinness and lightness. For my use case this is close to irrelevant. The price I have to pay now for a high-end MBP is becoming hard to justify. I am also thinking of adding GPU computation to some of the code I write. Apple's GPU offerings are really not up to scratch for these purposes. The software that was holding me back from switching to Linux is available on the iPad. I have the 11" iPad Pro, a great device for editing Word documents, PDFs, or making illustrations. I also use it for most of my e-mail and reading. Although I been using BBEdit for years as the scripting editor, I have switched to Vim a couple of years ago. Vim blows BBEdit out of the water for my needs. So when it came time to upgrade my 2015 15" MBP (still one of the best machines ever made), I decided to try out the System76 Oryx Pro. Some of my colleagues tried other System76 laptops and seemed generally happy with them. I ordered the 15" version with the HiDPI display, 32G of RAM and 250G NVME drive. I added my own 1TB SSD to the extra slot. I did not need to get an extra cable, everything was ready to just plug the drive in and it worked.
Overall, having used this laptop full time since the end of November, I am very happy with it. There are small manufacturing glitches here and there, something I notice because I am spoiled by Apple's obsessive perfectionism in industrial design, but no deal-breakers. The keyboard is amazing, and has fun back-light options. The only minus is that there is no indicator light on the caps lock. It feels very good to type on, better than any laptop keyboard I have personally tried (even the excellent ThinkPad keyboard). The trackpad is OK, Apple is way ahead of everyone on that, but I use a trackball most of the time. I note that the Oryx Pro line-up recently changed and they no longer have a HiDPI screen offering. That is too bad, the display is excellent. Although I am not a big user of various ports, it is nice to have the wide range of them available (even an ethernet port!). Battery life is not great, especially when using the GPU, but that is not a concern for me. It is enough to last through a meeting with a client, otherwise I have it plugged in.
System76 laptops come with a choice of Ubuntu or their own Ubuntu front-end they call Pop! OS. Pop! OS is well-designed, but after distro-hopping for a while I decided to go with Arch. My main reason was to educate myself about how Linux works. Since I have been on Mac OS X since its beginning, I feel fairly confident about fixing anything that goes wrong. I only needed to contact Apple support over a system software issue once. I noticed that most of my queries about Linux ended up at the Arch wiki, so I figured I should just install the thing rather than try and figure out how the answers there apply to Ubuntu. Below is the short version of the instructions to install Arch on the Oryx Pro. The full instructions are here, including details on how to compile R with Intel's MKL library for fast linear algebra. I like open source software, and release source code of everything I write, but I am not super ideological about it. I am happy to use free offerings from Intel and NVIDIA.
I want to have full-disk encryption, with the exception of the boot partition and I am installing with WiFi. There is a discrete NVIDIA graphics card. I would like to use it for OpenCL/CUDA and for an external monitor.
I used the
archlinux-2019.01.01-x86_64.iso, put it on a USB flash drive using
dd (standard procedure).
Inserted the USB drive, booted while pressing
F7 on boot to enter the boot disk picker. Once there, press
e to enter kernel command line options. Add
video=1920x1080 to enlarge the console fonts (I have the 4K screen version of the Oryx Pro and the default resolution makes the letters tiny) and
module_blacklist=nouveau to switch off the NVIDIA GPU for now. The commands should be separated by space and entered at the end of the line. Switching off the
nouveau driver is necessary, otherwise any hardware listing (such as
lspci) will hang with fans blazing. The WiFi card has functional firmware, checked by running
lspci -k dmseg | grep iwlwifi
List WiFi networks, pick the relevant and follow prompts to connect:
Set up time and date.
timedatectl set-ntp true timedatectl set-timezone America/New_York
I want to use LVM on LUKS to get full-disk encryption, including the SWAP.
/boot will be unencrypted.
Partition the target disk (here, it is
To list partitions:
System76 requires the EFI partition to be in
/boot so that it can do firmware updates. I leave the secondary disk alone. It is already formatted and has data on it. I use
gdisk to set up GPT.
p to list current partitions
o to delete them all and create an empty GPT partition table
n to create new
- first (for EFI, code EF00): default start, end at +500M, otherwise defaults, erase ext4 signature if asked
- second (LVM, code 8E00): the rest of the disk
p to check if everything looks sane
w to write (THE DISK WILL BE ERASED AT THIS POINT)
Format the EFI boot partition (left unencrypted):
mkfs.fat -F32 /dev/nvme0n1p1
Create the non-boot file systems. The following will require coming up with a passphrase. I followed the instructions in Encrypting an entire system.
Encrypt the future LVM container:
cryptsetup luksFormat —-type luks1 /dev/nvme0n1p2 cryptsetup open /dev/nvme0n1p2 cryptlvm
I have to use
luks1 because GRUB does not support
luks2 as of this writing. That is not an issue in the ThinkPad set-up, as far as I can tell because I am booting from BIOS there rather than EFI. Prepare the logical volumes:
pvcreate /dev/mapper/cryptlvm vgcreate MainVolGroup /dev/mapper/cryptlvm lvcreate -L 16G MainVolGroup -n swap lvcreate -l 100%FREE MainVolGroup -n root mkfs.ext4 /dev/MainVolGroup/root mkswap /dev/MainVolGroup/swap mount /dev/MainVolGroup/root /mnt swapon /dev/MainVolGroup/swap
Mount the EFI boot partition:
mkdir /mnt/boot mkdir /mnt/boot/efi mount /dev/nvme0n1p1 /mnt/boot/efi
pacstrap /mnt base base-devel python gvim git grub dhclient networkmanager gnome-keyring efibootmgr
genfstab -U /mnt >> /mnt/etc/fstab
/mnt/etc/crypttab to add a line
cryptlvm UUID=_/dev/nvme0n1p2 UUID_ none luks,discard,timeout=5
discard option enables TRIM support. There are security implications, but not serious enough for my use case. Read the linked documentation to decide for yourself. An easy way to transfer the UUID without typing it is to do
blkid -pi /dev/nvme0n1p2 | cut -d' ' -f3 >> /mnt/etc/crypttab
and edit the
crypttab file to make it correct, or use
:read in vim.
There is an issue with GRUB and LVM which causes grub-mkconfig to hang and grub-install to keep probing LVM devices. For the workaround, prepare the following:
mkdir /mnt/hostlvm mount --bind /run/lvm /mnt/hostlvm
Move into the fresh Arch installation on the main disk. Note that the paths will no longer require
/mnt in front.
To deal with the GRUB/LVM problem, run
ln -s /hostlvm /run/lvm
/etc/mkinitcpio.conf (this is now on the target drive):
HOOKS=(base udev autodetect **keyboard** **keymap** modconf block **encrypt** **lvm2** **resume** filesystems fsck) # resume is included for suspend to disk support mkinitcpio -p linux
blkid to list UUIDs of devices. Edit
/etc/default/grub to modify variables. Append "lvm" to
GRUB_PRELOAD_MODULES. Uncomment the
GRUB_ENABLE_CRYOTDISK=y line. Append
cryptdevice=UUID=UUID-of-/dev/nvme0n1p2:cryptlvm root=/dev/MainVolGroup/root resume=/dev/MainVolGroup/swap ec_sys.write_support=1 video=1920x1080 module_blacklist=nouveau to
resume=... part is for suspend to disk support. Install GRUB on EFI:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ArchLinuxGRUB
Make the GRUB config:
grub-mkconfig -o /boot/grub/grub.cfg
systemctl enable NetworkManager
Time zone and locale specification (I am in New York, yours may be different).
ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime hwclock --systohc
en_US entries in
LANG=en_US.UTF-8 in newly created
/etc/hostname and write nerv there (that is the name I gave the laptop; substitute what you like). Edit
/etc/hosts to add
127.0.0.1 localhost ::1 localhost 127.0.0.1 nerv.localdomain nerv
unmount -R /mnt, and shut down the computer. Remove the USB drive and start the laptop again.
Start by connecting to WiFi
nmcli device wifi list nmcli device wifi connect *SSID* --ask
and enter the WiFi password (if any) at the prompt.
Start by installing the NVIDIA drivers:
pacman -S nvidia nvidia-utils nvidia-settings
The System76 drivers are available from AUR. Cannot install these using root, so I generate my root password and add a regular user first.
passwd useradd -m -g wheel *username* passwd tonyg
sudo for the user, uncomment the
%wheel ALL=(ALL) ALL line in
/etc/sudoers. I like to reboot etc without entering a password, so I also add
%wheel ALL=(ALL) NOPASSWD: REBOOT. I add
/sbin/shutdown to the
REBOOT alias. Reboot the laptop. Login as the regular user and proceed with driver installation. First install kernel headers:
pacman -S linux-headers
Now install the kernel modules (mostly following the instructions here):
git clone https://aur.archlinux.org/system76-dkms.git cd system76-dkms makepkg -sci modprobe system76 cd rm -rvf system76-dkms git clone https://aur.archlinux.org/system76-firmware-daemon.git cd system76-firmware-daemon makepkg -sci systemctl enable --now system76-firmware-daemon.service cd rm -rvf system76-firmware-service git clone https://aur.archlinux.org/system76-io-dkms.git cd system76-io-dkms makepkg -sci modprobe system76-io cd rm -rvf system76-io-dkms git clone https://aur.archlinux.org/system76-driver.git cd system76-driver makepkg -sci cd rm -rvf system76-driver git clone https://aur.archlinux.org/system76-power.git cd system76-power makepkg -sci systemctl enable --now system76-power.service cd rm -rvf system76-power
I mostly follow the instructions here. I activate the NVIDIA card
sudo system76-power graphics nvidia
I add the file
/usr/share/X11/xorg.conf.d. This file contains
Section "OutputClass" Identifier "intel" MatchDriver "i915" Driver "modesetting" EndSection Section "OutputClass" Identifier "nvidia" MatchDriver "nvidia-drm" Driver "nvidia" Option "AllowEmptyInitialConfiguration" Option "PrimaryGPU" "yes" ModulePath "/usr/lib/nvidia/xorg" ModulePath "/usr/lib/xorg/modules" EndSection
I also put the following script in
/etc/lightdm to check if the NVIDIA card is on at startup, and add an external monitor if it is connected.
#!/bin/sh if system76-power graphics | grep -q 'nvidia'; then xrandr --setprovideroutputsource modesetting NVIDIA-0 xrandr --output eDP-1-1 --auto --primary --dpi 144 if [ $( xrandr | grep HDMI | cut -d ' ' -f2 ) == "connected" ]; then output=$( xrandr | grep HDMI | cut -d ' ' -f1 ) xrandr --output $output --auto --left-of eDP-1-1 fi fi
I keep the screens (I have a 4K external monitor, and the HiDPI screen on the laptop) at the full resolution, but enlarge fonts and follow some suggestions on the Arch HiDPI wiki page. I am really happy with the text rendering with this set-up. Running the screens at 1080p made everything larger, but noticeably fuzzier.
- External monitor
- Keyboard back-light
- Laptop screen back-light adjustment (via light)
- Trackpad and external mouse (via USB)
Things I have not tested:
- Ethernet cable
I heavily use Vim, with YouCompleteMe for C++ and some of my own keybindings for Sweave code in R and for LaTeX. For the latter two, I like to have a PDF window (using zathura) side-by-side with the code. The zathura PDF viewer auto-updates when the file on disk changes, so I can see the type-set document essentially in real-time. The tiling window manager makes it easy to arrange the windows and the HiDPI screen ensures that all the text readable and crisp.
To cap everything off, here is the obligatory screen shot: