Search code examples
macosapple-siliconlipo

"command not found" running universal console app on macOS with Apple Silicon chip


I have the issue on my library – DllNotFoundException on Apple Silicon chips. It's fixed now but we observed strange behavior trying to run simple console application on macOS with Apple Silicon chip:

sudo ./LoopbackDevice "MIDI A" "MIDI B" "MIDI C"  
Password:
sudo: ./LoopbackDevice: command not found

LoopbackDevice is definitely in the current directory (checked via ls). The one moment here: LoopbackDevice is built on Intel-based machine but using lipo to merge x86_64 and arm64 architectures so it should run fine on both Intel- and Apple Silicon-based machines:

clang -undefined dynamic_lookup -o LoopbackDevice_arm64 LoopbackDevice.c -framework CoreServices -framework CoreFoundation -framework CoreMIDI -arch arm64
clang -undefined dynamic_lookup -o LoopbackDevice_x86_64 LoopbackDevice.c -framework CoreServices -framework CoreFoundation -framework CoreMIDI -arch x86_64
lipo LoopbackDevice_x86_64 LoopbackDevice_arm64 -output LoopbackDevice -create

Here the archive with the app you can try to run on your machine: LoopbackDevice.zip. (If you're interested, here the source code: LoopbackDevice.c)

But if to build LoopbackDevice from source code within Xcode on target Apple Silicon machine and run it with the command above, then it works fine:

Creating client...
Creating port 'MIDI A'...
    creating source...
    creating destination...
OK
Creating port 'MIDI B'...
    creating source...
    creating destination...
OK
Creating port 'MIDI C'...
    creating source...
    creating destination...
OK
Waiting for data...

So what am I doing wrong building universal app?

I also need to note that building universal dylibs on Intel-based machines is OK, such dylibs works fine on Apple Silicon chips. So maybe I need to use different steps for apps (not dylibs).


Solution

  • sudo ./LoopbackDevice "MIDI A" "MIDI B" "MIDI C" Password: sudo: ./LoopbackDevice: command not found

    You appear to have something changing your directory when sudo completes. I tested your code and it appeared to work on Apple Silicon. Try supply an absolute path?

    % sudo ./LoopbackDevice "MIDI A" "MIDI B" "MIDI C"
    Creating client...
    Creating port 'MIDI A'...
        creating source...
        creating destination...
    OK
    Creating port 'MIDI B'...
        creating source...
        creating destination...
    OK
    Creating port 'MIDI C'...
        creating source...
        creating destination...
    OK
    Waiting for data...
    

    So what am I doing wrong building universal app?

    It's simpler to just compile in one step:

    clang -arch arm64 -arch x86_64 -undefined dynamic_lookup -o LoopbackDevice LoopbackDevice.c -framework CoreServices -framework CoreFoundation -framework CoreMIDI