Skip to content

Instantly share code, notes, and snippets.

@onehundredfeet
Last active January 30, 2023 05:37
Show Gist options
  • Save onehundredfeet/92e48e437b0ecc22935f49da3d966c38 to your computer and use it in GitHub Desktop.
Save onehundredfeet/92e48e437b0ecc22935f49da3d966c38 to your computer and use it in GitHub Desktop.
Developing for Haxe / Hashlink on an M1

Challenge

Getting Haxe, and especially Hashlink, up and running on an Apple M1 is not easy. We'll try to put our heads together and come up with any recipes for success that people have found.

Intel vs Arm with Hashlink

The first thing to note, is that the Hashlink JIT does not work with the M1 (arm) instruction set. To develop with the Hashlink, we end up using a combination of arm64 compiled tools and x86/64 tools libraries.

The M1 Mac's can run x64 (Intel) applications using a technology called 'Rosetta' that translates the x86 code into arm64 code at runtime. We can use this to run Hashlink, with the JIT, effectively. At the moment, there is no known way to run the Hashlink debugger on an M1 Mac.

Using the Command Line

Developing on the M1 will require understanding what architecture your current terminal is set up for.

Recomendation - Make two terminals, one for Intel and one for Arm

You can duplicate the Terminal program (or use a different one) in the Applications / Utilities folder. Rename the duplicate to Terminal Intel. Right click on it, select 'Get Info', find the 'Open with Rosetta' checkbox and enable it.

This will give you a terminal that thinks it's native environment is Intel under some circumstances.

Switching Architectures

You will often need to switch architectures to compile different programs. Given that the above has already been set up, it will just involve switching applications.

To find out what architecture you're currently set to compile as you can type 'arch' into the prompt. The Intel one should show the below.

> arch
i386

While the regular terminal should show the below.

> arch
arm64

You can switch architectures using the arch command as well. You can also use the arch command to run an application within one or the other architectures. A hidden challenge, is that which libraries are used by the program may not always be obvious.

Recommendation - Using two different homebrews

Instead of switching back and forth, it's easy to create two different homebrew aliases.

mbrew - M1 homebrew (rooted in /opt/homebrew) ibrew - Intel homebrew (rooted in /usr/local)

For those using zsh, you can add this to your ~/.zprofile file.

alias ibrew='arch -x86_64 /usr/local/bin/brew'
alias mbrew='arch -arm64e /opt/homebrew/bin/brew'

Then typing ibrew or mbrew in any terminal will direct it to the homebrew you intend. It is recommended to avoid having both in the path.

Further, to set up the development environment you can add the following to your .zprofile

i_brew_env () { eval "$(/usr/local/bin/brew shellenv)" }
m_brew_env () { eval "$(/opt/homebrew/bin/brew shellenv)" }

While will allow you to set that shell to implicitely assume a shell environment of one or the other.

My recomendation is to stay aligned within your two terminal applications. Keep the use of the Intel to the Intel Terminal and the Arm to the Arm Terminal.

@afaur
Copy link

afaur commented Jan 30, 2023

Notes

  • x86_64
    • Run session in x86_64 mode
      • arch -x86_64 $SHELL
    • Set brew commands to operate on x86_64 brew install
      • Add to your ~/.bashrc / ~/.zshrc / ~/.fishrc
        • x86_brew_env () { eval "$(/usr/local/bin/brew shellenv)" }
      • Then you can call it during a session
        • x86_brew_env
  • arm64
    • Run session in arm64 mode
      • arch -arm64 $SHELL
    • Set brew commands to operate on arm64 brew install
      • Add to your ~/.bashrc / ~/.zshrc / ~/.fishrc
        • arm_brew_env () { eval "$(/opt/homebrew/bin/brew shellenv)" }
      • Then you can call it during a session
        • arm_brew_env

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment