iainctduncan/scheme-for-max

Compiling for Apple Silicon

Closed this issue · 4 comments

r-gr commented

Hey @iainctduncan,

I noticed that you mentioned not being able to compile s4m for Apple Silicon. I've just compiled a universal (Intel + Apple Silicon) binary for s4m in Xcode now using the Max 8.2 SDK. I'll outline the process below. It's possible that this won't work with older versions of the SDK or that the compiled external is incompatible with earlier versions of Max, I'm not sure.

I ran into one issue -- I needed to comment out a function in s4m/s4m.c which was causing a build error. I haven't read the source code at all so I have no idea if the function is safe to comment out, but commenting it out does allow the external to compile:

On line 3360 of s4m/s4m.c, the build fails with the error "Implicit declaration of function 's7_dict_put_lookup' is invalid in C99". This error does seem to make sense because I can't find a definition of that function anywhere in the project's source code. I commented out the whole s7_dict_put function (L3319 to 3366) because it doesn't appear to be used anywhere else in the code.

Compiling a universal .mxo with Xcode 13 (Xcode 12 might work too) and the Max 8.2 SDK

1. Download/clone the Max SDK as described in the Max 8.2 SDK Update Overview video on the Cycling '74 YouTube channel (linked in the README.md of https://github.com/Cycling74/max-sdk).

git clone https://github.com/Cycling74/max-sdk.git
cd max-sdk && git submodule update --init --recursive

2. Place this repo within the Max SDK source. (I don't like this step -- it feels wrong to put the external's source code inside the Max SDK when the Max SDK should instead be a dependency of the external. There's a way around this by creating new CMake project and changing the hierarchy but I won't complicate this explanation with that.)

cd source
mkdir scheme-for-max  # it doesn't matter what this folder is called, but it is needed.
cd scheme-for-max
git clone https://github.com/iainctduncan/scheme-for-max.git s4m

3. Create a CMakeLists.txt in the root of the scheme-for-max repo (i.e. at max-sdk/source/scheme-for-max/s4m/CMakeLists.txt) with the following contents:

include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-pretarget.cmake)

#############################################################
# MAX EXTERNAL
#############################################################

include_directories( 
	"${MAX_SDK_INCLUDES}"
	"${MAX_SDK_MSP_INCLUDES}"
	"${MAX_SDK_JIT_INCLUDES}"
)

file(GLOB PROJECT_SRC
	"s4m/s4m.c"
	"s4m/s7.h"
	"s4m/s7.c"
)
add_library( 
	${PROJECT_NAME} 
	MODULE
	${PROJECT_SRC}
)

include(${CMAKE_CURRENT_SOURCE_DIR}/../../max-sdk-base/script/max-posttarget.cmake)

4. Comment out the s7_dict_put function on lines 3319 to 3366 in s4m/s4m.c to prevent a build error.

5. Create the build directory and use CMake to generate the Xcode projects as described here: https://github.com/Cycling74/max-sdk/blob/main/README-8.2-update.md.

cd /path/to/max-sdk  # go to the root of the Max SDK
mkdir build
cd build
cmake .. -G Xcode

The directory tree now looks like this:

max-sdk/
├── CMakeLists.txt
├── LICENSE.md
├── MaxAPI.html
├── MaxAPI.pdf
├── README-8.2-update.md
├── README.md
├── build/
├── doxygen/
├── externals/
├── help/
├── html/
├── icon.png
├── init/
├── media/
├── package-info.json
└── source/
    ├── ...
    └── scheme-for-max/
        └── s4m/
            ├── CMakeLists.txt   # new
            ├── License.md
            ├── README.md
            ├── RELEASES.md
            ├── Scheme-For-Max/
            ├── assets/
            ├── cm/
            ├── docs/
            ├── make-release.py
            ├── notes/
            ├── s4m/
            │   ├── ...
            │   └── s4m.c        # edited
            ├── test-code/
            └── uninstall.py

6. Open the s4m.xcodeproj generated in the build directory (build/source/scheme-for-max/s4m/s4m.xcodeproj).

Screenshot 2022-02-06 at 16 08 01

7. Set the compilation target/scheme to Any Mac (Intel, Apple Silicon) and run the build.

Screenshot 2022-02-06 at 16 28 38

This should create the s4m.mxo in the max-sdk/externals directory, which appears to work correctly on my Apple Silicon Mac:

Screenshot 2022-02-06 at 16 35 37

Ah fantastic! And your timing is perfect, I just got an M1 mini two days ago and was going to get on this this week. I will try following your instructions, but if I get stuck, I will let you know.

Thanks so much for posting this! Once we are built for M1, I can get s4m in the package manager. :-)

r-gr commented

You're welcome, thank you for creating this. I haven't used s4m much yet, needed to compile it for Apple Silicon first, but it seems great so far!

If the method above works for you, I have a CMake setup I've been using for my externals where the Max SDK is included as a git submodule in my repo and I can build the externals without going through the whole process of putting my code inside the max-sdk. I don't know to what extent that process bothers you, but feel free to give me a shout if you'd like an explanation of the setup.

Btw, rather than opening up the .xcodeproj manually for steps 6 and 7, I think you can just run cmake --build . --target s4m and it should build a universal binary by default if your version of Xcode is >= 12.

Hi, I was able to get compiles going with your instructions, so should have a binary up in the next few days. Thanks so much for the details, it was very helpful!

btw I would like to be able to thank your for the help, but I don't know anything beyond r-gr. ha! feel free to email me.