= Migrating MacPorts after a major operating system upgrade or from one computer to another = A MacPorts installation is designed to work with a particular operating system and a particular hardware architecture. This migration procedure ensures a smooth transition after major system changes, such as: - major operating system upgrades (e.g., from macOS 10.15 Catalina to macOS 11 Big Sur). - architecture migrations (e.g., from Intel to Apple Silicon). - migrations from one computer to another If you don't want to migrate, you can always [https://guide.macports.org/chunked/installing.macports.uninstalling.html uninstall MacPorts] entirely before manually [https://www.macports.org/install.php reinstalling ports]. Note: If you move from one Mac to another Mac using [https://en.wikipedia.org/wiki/Migration_Assistant_(Apple) Migration Assistant], you have to do it first. == Migration procedure == 1. [=#xcode **Install the latest version of Xcode and the Xcode command-line tools**] [https://guide.macports.org/#installing.xcode Install the latest version of Xcode] that is compatible with your OS. Open the Xcode application once after installation and follow any prompts. Install the same version of the command line tools. (Run `xcode-select --install`). Recent versions of macOS have a bug that prevents them from automatically updating the command line tools, so if the preceding command says they're already installed, they may not be up to date and you may need to update manually by following the instructions in ProblemHotlist#reinstall-clt. 2. [=#base **Reinstall MacPorts base system**] To reinstall, simply [https://www.macports.org/install.php install the base MacPorts system] for your new platform. If there is no macOS Installer package available for your new OS version, you can install from source. 3. [=#config **Update your macports.conf (if not default)**] If your {{{macports.conf}}} (typically at {{{ /opt/local/etc/macports/macports.conf}}}) contains uncommented settings for {{{universal_archs}}} or {{{build_arch}}}, you will likely want to update them, since newer OS versions may support different CPU architectures. Default values are fine for most users, so unless you know you need something different, just comment out these two lines. Several other settings in {{{macports.conf}}} have changed their defaults over the years. Take a moment to compare each line of your {{{macports.conf}}} with the corresponding line in {{{macports.conf.default}}} in the same directory. Unless you know a reason why a line in your settings file should be different from the defaults, adopt the line from the defaults file. 3. [=#ports **Reinstall your ports**] a. Save the list of installed ports: {{{ port -qv installed > myports.txt }}} a. Save the list of requested ports: {{{ port echo requested | cut -d ' ' -f 1 | uniq > requested.txt }}} a. Uninstall all installed ports: {{{ sudo port -f uninstall installed }}} a. Run a regular clear out of your installation: {{{ sudo port reclaim }}} a. Download and execute the [https://raw.githubusercontent.com/macports/macports-contrib/master/restore_ports/restore_ports.tcl restore_ports script]. (If you installed MacPorts from source and used a custom prefix, then you'll need to use the -p option when you run restore_ports.tcl; see `./restore_ports.tcl -h`.) {{{ curl --location --remote-name https://github.com/macports/macports-contrib/raw/master/restore_ports/restore_ports.tcl chmod +x restore_ports.tcl xattr -d com.apple.quarantine restore_ports.tcl sudo ./restore_ports.tcl myports.txt }}} Note: ports that are not available on your new platform will be skipped, with only a warning message. \\ a. Restore requested status: If you saved the list of requested ports, you can now restore the requested flags for your newly installed ports to their former states. {{{ sudo port unsetrequested installed xargs sudo port setrequested < requested.txt }}} Warning: if a port in `requested.txt` was ''not'' installed in the previous step, the iterative `setrequested` will terminate, leaving some ports still marked as not-requested. Edit `requested.txt` to remove any ports that were not installed and repeat this step. Double-check your desired ports are set as requested with `port echo requested`. == Troubleshooting == Though it is now quite well-tested, the restore_ports script may fail in some cases. One known issue is that the script will fail if there are conflicting ports in the list. It's possible to have conflicting ports installed provided at most one of the conflicting set is active. If the script fails, for this reason, you can delete one of the conflicting ports from myports.txt and then simply run the script again. You may need to do this multiple times if there are multiple conflicting ports listed. In the worst case, you can reinstall your ports manually by browsing `myports.txt` and installing the ports one by one, remembering to specify the appropriate variants: {{{ sudo port install portname +variant1 +variant2 … }}} Note that if you have specified variants which are not the default, you may need to install ports in an order other than the alphabetical order recorded in `myports.txt`. You may skip explicitly installing ports that you did not request as long as they are not using non-default variants since they will be installed as dependencies of other ports. If you see an "infinite loop" error message, such as this: {{{ Error: we appear to be stuck, exiting... infinite loop while executing "sort_ports $portList" invoked from within "set operationList [sort_ports $portList]" (file "./restore_ports.tcl" line 285) }}} it indicates that the script has a list of ports to install, and it can't figure out which of the ports to install next. Each port has some obstacle that prevents it from being the next to install. One cause of this problem is a "dependency cycle": port A depends directly or indirectly on port B, while port B depends on port A. A workaround is to reduce your list of ports to install, until it no longer has a dependency cycle. If things go really wrong, don't forget that you can always [https://guide.macports.org/chunked/installing.macports.uninstalling.html uninstall MacPorts] entirely before manually reinstalling ports. Another potential problem is that the `restore_ports.tcl` command may fail with a `Too many open files` error message. Under macOS Sierra, the default shell has a default `ulimit` of 256 open files. The solution is to restore the ports with a slightly modified command: {{{ sudo bash -c "ulimit -n 4096; ./restore_ports.tcl myports.txt" }}} This will raise the file limit for the duration of the `restore_ports.tcl` command. Another potential problem comes from possible differences between ports that do compile on an older macOS, but no longer on the newer. For instance, you might have installed OpenBLAS on macOS Mojave. This was built with gcc10, the then preferred version of gcc. OpenBLAS sets a +gcc10 variant for this and it has remained like that as long as you were updating it. When upgrading to macOS Monterey according to the procedure above, MacPorts will try to exactly recreate what was on Mojave, hence OpenBLAS +gcc10. But gcc10 may not compile on macOS Monterey (it does not as I write this example). Hence, the migration of OpenBLAS and everything that depends on it fails. Another issue may come from incompatibility between some additional components, which may manifest itself with ports failing with a message like {{{ Failure Reason: The version of the CoreSimulator framework installed on this Mac is out-of-date and not supported by this version of Xcode. Recovery Suggestion: Please ensure that you have installed all available updates to your Mac's software, and that you are running the most recent version of Xcode supported by macOS. }}} In this case you may be able to solve it by running {{{ xcodebuild -runFirstLaunch }}}