Install x86_64 libraries on macs with Apple Silicon

Lumibit
Lumibit
Published in
4 min readMar 2, 2023

What’s the difference?

Mac’s with Apple Silicon instead of Intel chips are developed with an arm64 architecture. Some libraries need the x86_64 architecture cause they don’t support arm64 architecture yet, like connecting to Oracle databases with cx_Oracle in python.

Terminal architecture

The default Terminal on MacOS with Apple Silicon runs on arm64 architecture, you can get this info with the “arch” command:

$ arch
arm64

With the “arch” command you can also run a Terminal command with other architectures for e.g. installing Homebrew:

$ arch -x86_64 /bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Sometimes you need more than one command in a different architecture for e.g. installing python with pyenv. You can also run pyenv with arch command, but build and installation process is done with arm64. So it’s better to create a seperate Terminal environment for x86_64 architecture.

Rosetta 2

With Rosetta 2 you can use apps designed for a Mac with an Intel processor on a Mac with an Apple Silicon processor.

Running application is quite easy, cause a popup gives you all the information you need and you can install Rosetta with one click:

A manual installation can be done with softwareupdate in your Terminal:

$ /usr/sbin/softwareupdate --install-rosetta --agree-to-license

Rosetta Terminal

After Rosetta has been installed duplicate your Terminal app located at

/System/Applications/Utilities/Terminal.app

and rename it to for e.g. “Terminal Rosetta.app”

Right-click on your new Terminal, select “Get Info” and check “Open using Rosetta” box.

In your new Rosetta Terminal you can check the architecture again:

$ arch
i386

“i386” refers to Intel architecture in your Rosetta Terminal, you can check this with the uname command, which gives you system information form the machine:

$ uname -m
x86_64

Installation of x86_64 libraries in Rosetta Terminal

In our use case we run into a problem with Oracle connections in python on Apple Silicon Mac’s:

DPI-1047: Cannot locate a 64-bit Oracle Client library: “dlopen(libclntsh.dylib, 0x0001): tried: ‘libclntsh.dylib’ (no such file), ‘/usr/local/lib/libclntsh.dylib’ (mach-o file, but is an incompatible architecture (have ‘x86_64’, need ‘arm64e’)), ‘/usr/lib/libclntsh.dylib’ (no such file)”. See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help

So we had to install our python version with cx_Oracle library in our newly created x86_64 environment with pyenv.

I had Homebrew and Pyenv already installed on my default Terminal. If it’s missing on your machine install it in your default Terminal with:

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install pyenv

Pyenv version 2.3.0 is recommended cause of bugs with arm64 machines in some older python versions, see related GitHub issue. We don’t need to install Pyenv our newly created Rosetta Terminal again because it supports arch commands like arch -x86_64 pyenv versions. Running commands in Rosetta Terminal is similar to run commands with arch -x86_64 in your default Terminal.

Cause x86_64 Homebrew installation $PATH is different to arm64 $PATH we have to install it twice.

From now on we’re using our Rosetta Terminal:

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

If you get a permission error to /usr/local/* you can grant those with:

$ sudo chown -R ${USER}:admin /usr/local/*

Now you can check, that Homebrew has been installed at the “Intel” location at:

$ which brew
/usr/local/Homebrew/bin/

Best practice of Homebrew $PATH configuration in your ~/.zprofile:

if [ $(arch) = "i386" ]; then
export PATH=/usr/local/Homebrew/bin:/opt/homebrew/Cellar/pyenv/2.3.0/libexec:$PATH
else
export PATH=/opt/homebrew/bin:$PATH
fi

With this setting you have set $PATH to your respective Homebrew installation. Cause Pyenv is installed once in arm64 Homebrew you’ve to add pyenv executables manually to your x86_64 environment (check your pyenv version).

Now we can install python build dependencies with Homebrew and also Xcode Command Line tools, if it is not already installed on your mac:

$ brew install openssl@1.1 readline sqlite3 xz zlib tcl-tk
$ xcode-select --install

Out of the box, pyenv does not allow you to install multiple copies of the same python version. So we recommend installing pyenv-alias plugin, which allows you to specify a ‘version name alias’ when installing python:

$ git clone https://github.com/s1341/pyenv-alias.git $(pyenv root)/plugins/pyenv-alias

Install python with optional alias or without:

$ VERSION_ALIAS="3.9.10_x86" pyenv install 3.9.10
$ pyenv install 3.9.10

Since I installed Python on both architectures with the pyenv-alias plugin, I have a nice overview:

$ pyenv versions
system
3.9.10_arm64
* 3.9.10_x86 (set by /Users/${USER}/.pyenv/version)

For further libraries installations we set our global python to our x86_64 version (you can also do this locally in your repo)

$ pyenv global 3.9.10_x86

Now you can install x86_64 libraries on your Apple Silicon Mac. We’ve installed cx_Oracle and can now create Oracle connections.

Conclusion

There are a few articles on the subject, but in each one a small ingredient was missing to make it understood throughout. This article is intended to improve the overall understanding of all those who faced the same problem. Besides the above solution, there are other ways to install x86_64 libraries, but this one was the most practical for us.

--

--

Lumibit
Lumibit
Editor for

Willkommen bei Lumibit. We light you up!