not a mach-o file error in Python - mismatching architecture

For a Python project, I'm reading a .so file with the ctypes.CDLL and ctypes.cdll.LoadLibrary(...), this is done in a vscode devcontainer. The docker image is based off the following:

FROM --platform=linux/amd64 mcr.microsoft.com/vscode/devcontainers/python:3.10

Notice the linux/amd64 platform. When checking system information with uname, it shows the x86_64 architecture:

Linux ceb596f614b7 5.10.124-linuxkit #1 SMP PREEMPT Thu Jun 30 08:18:26 UTC 2022 x86_64 GNU/Linux. 

This runs fine, and loads the library without any errors.

However, I have a M1 MacBook Pro (the 14" model), where I'm using Rosetta and installed Python on that environment. (https://stackoverflow.com/a/71873666/2989034). When I check the system information then, I get the following, also a x86_64 architecture.

Darwin MacBook-van-Bas.local 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000 x86_64

When I load the file in this terminal, I get the following error:

OSError: dlopen(/Users/bas/lib.so, 0x0006): tried: '/Users/bas/lib.so' (not a mach-o file)

How is this even possible? It's the same x86_64 architecture. Is my only option working in a devcontainer?

Accepted Reply

Oh, one more thing. You wrote:

It's the same x86_64 architecture.

Apple platforms draw an important distinction between architecture and platform. Just because something is the right architecture doesn’t necessarily mean it’ll work on the target platform. In this case there’s an obvious difference, ELF versus Mach-O, but within Mach-O there are subtle differences. I explain this in more detail in my An Apple Library Primer post.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Replies

What does this report?

% file /Users/bas/lib.so

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • ./lib.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=***, not stripped

  • lib.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=***, not stripped

Add a Comment
lib.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=***, not stripped

macOS use Mach-O for its binaries. It’s not able to load ELF binaries.

Reading through your original email it’s not clear to me how you actually built lib.so. Regardless, you’ll need to rework those steps so that that they build a Mach-O file rather than an ELF file.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Hi Quinn, thanks for the reply. Is it possible for tools such as gobjcopy to convert from ELF to Mach-o?

Add a Comment

Oh, one more thing. You wrote:

It's the same x86_64 architecture.

Apple platforms draw an important distinction between architecture and platform. Just because something is the right architecture doesn’t necessarily mean it’ll work on the target platform. In this case there’s an obvious difference, ELF versus Mach-O, but within Mach-O there are subtle differences. I explain this in more detail in my An Apple Library Primer post.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"