October 14, 2021
I recently ran into a situation where I needed macOS for React Native app deployment. The issue is, my current machine is a ThinkPad X13 that runs Windows 10. After searching around for a way to get a macOS virtual machine set up, I found macos-virtualbox.
macos-virtualbox is a shell script that provisions a macOS virtual machine for you in VirtualBox. In most cases, all you'll need to do is press enter a few times when the script is running. In this post, I'll share how to use the script and how the process went for me.
You'll need to install VirtualBox (optionally with the extension pack) and Cygwin (with the packages bash, coreutils, gzip, unzip, wget, and xxd) (you may be able to use WSL instead, but I used Cygwin). Installation was straightforward except for me not understanding how to select packages during Cygwin installation (just filter for the package and make sure a version is selected for the package). Also download the script.
Now you'll need to open Cygwin, navigate to where the script is located (e.g., cd /cygdrive/c/Users/.../Downloads) and start the script (./macos-guest-virtualbox.sh). Continue following the script's prompts and press enter when requested.
Documentation can be viewed with this command: ./macos-guest-virtualbox.sh documentation
During installation, I ran into issues related to CPU profiles and CPUID settings (in fact, the script referred me to this section of the documentation "CPU profiles and CPUID settings"). I followed the mitigations suggested in this section and the issue was resolved. I was able to use the "Intel Xeon X5482 3.20GHz" CPU profile to fix booting.
If you run into any issues and you need to abort the script, you can resume the script with this command: ./macos-guest-virtualbox.sh <section> and_all_subsequent_stages
After installation finished and you log in, you can power down the virtual machine and run this command to clean up temporary files: ./macos-guest-virtualbox.sh prompt_delete_temporary_files
If you need to change the location of the VDI file, you can use this command (PowerShell): .\VBoxManage.exe modifymedium "<medium-id>" --setlocation "C:\Users\...\macOS.vdi"
After installation finished and you log in, you can upgrade to the latest macOS release.
If you want to share files between Windows and your virtual machine, you can turn on SSH and use rsync. I had the best luck setting up SSH and rsync in WSL (I ran into an issue where Cygwin was trying to use Windows' SSH with rsync instead of Cygwin's).
This Super User answer explains a command you need to run to get access to Windows' ports from within WSL.
Since the command does not persist across restarts, you can use this command to remove any firewall rule named WSL, then recreate it (preventing duplication): Remove-NetFirewallRule -DisplayName "WSL"; New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow
You'll also need to port forward port 22 in your virtual machine's network settings (I port forwarded Windows port 3022 to the virtual machine's port 22).
Finally, you need to use a specific IP address within WSL that is essentially an alias to Windows' localhost. Go to "View network connections" in the Start menu and go to the properties of "vEthernet (WSL)". Press details and note down the IPv4 Address. You can use this address in WSL to reference Windows' localhost.
So now you can use a command like this to SSH from WSL into your virtual machine: ssh -p 3022 username@<ipv4-address>
And you can use an rsync command like this: rsync -rvz -e 'ssh -p 3022' --progress ./directory username@<ipv4-address>:/path