Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[submodule "lib/APCpp"]
path = lib/APCpp
url = https://github.com/RecompRando/APCpp.git
branch = main
# TEMPORARY: the macOS build needs the size_t->Json::Value fix that is
# still pending upstream (see PR referenced in the commit/PR description).
# Pointing at the fork so CI can build; revert to RecompRando/APCpp once
# the fix is merged.
url = https://github.com/MarcDufresne/APCpp.git
branch = macos-arm64-fix
[submodule "Archipelago-MM"]
path = archipelago
url = https://github.com/RecompRando/Archipelago-MM
17 changes: 16 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH "$\{ORIGIN\}")
if(APPLE)
# macOS dyld uses @loader_path (dir of the loading binary), not $ORIGIN.
set(CMAKE_INSTALL_RPATH "@loader_path")
else()
set(CMAKE_INSTALL_RPATH "$\{ORIGIN\}")
endif()

# Include the script to download and set up the Python binary
if(WIN32)
Expand All @@ -29,6 +34,8 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
else()
message(FATAL_ERROR "Unknown pointer size.")
endif()
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
include(${CMAKE_SOURCE_DIR}/PythonStandalone_macOS_arm64.cmake)
endif()

add_library(APCpp-Glue SHARED
Expand All @@ -41,6 +48,14 @@ add_library(APCpp-Glue SHARED

target_include_directories(APCpp-Glue PRIVATE lib/APCpp)

# The recomp engine resolves the native_libraries manifest entry by bare name
# ("APCpp-Glue") + platform extension, matching the Windows APCpp-Glue.dll and
# Linux APCpp-Glue.so in the release. macOS would otherwise get CMake's default
# "lib" prefix (libAPCpp-Glue.dylib) and fail to resolve, so drop the prefix.
if(APPLE)
set_target_properties(APCpp-Glue PROPERTIES PREFIX "")
endif()

if (WIN32)
target_link_libraries(APCpp-Glue PRIVATE ws2_32)
else()
Expand Down
52 changes: 52 additions & 0 deletions PythonStandalone_macOS_arm64.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.20)
project(UsePythonStandalone)

include(FetchContent)

set(PYTHON_URL "https://github.com/astral-sh/python-build-standalone/releases/download/20250409/cpython-3.11.12+20250409-aarch64-apple-darwin-install_only_stripped.tar.gz")
set(PYTHON_ARCHIVE "${CMAKE_BINARY_DIR}/cpython.tar.gz")
set(PYTHON_EXTRACT_DIR "${CMAKE_BINARY_DIR}/python-standalone")

if(NOT EXISTS "${PYTHON_ARCHIVE}")
message(STATUS "Downloading Python artifact...")
file(DOWNLOAD "${PYTHON_URL}" "${PYTHON_ARCHIVE}" SHOW_PROGRESS)
endif()

if(NOT EXISTS "${PYTHON_EXTRACT_DIR}")
message(STATUS "Extracting Python artifact...")
file(MAKE_DIRECTORY "${PYTHON_EXTRACT_DIR}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xzf "${PYTHON_ARCHIVE}"
WORKING_DIRECTORY "${PYTHON_EXTRACT_DIR}"
)
endif()

file(GLOB EXTRACTED_DIRS LIST_DIRECTORIES true "${PYTHON_EXTRACT_DIR}/*")
list(GET EXTRACTED_DIRS 0 PYTHON_ROOT)

add_library(python_standalone INTERFACE)
target_include_directories(python_standalone INTERFACE "${PYTHON_ROOT}/include/python3.11")
target_link_directories(python_standalone INTERFACE "${PYTHON_ROOT}/lib")
target_link_libraries(python_standalone INTERFACE "${PYTHON_ROOT}/lib/libpython3.11.dylib")

function(link_python_standalone TARGET_NAME)
target_link_libraries(${TARGET_NAME} PRIVATE python_standalone)
# Copy the interpreter next to the target so it ships with the mod.
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PYTHON_ROOT}/lib/libpython3.11.dylib"
"$<TARGET_FILE_DIR:${TARGET_NAME}>/libpython3.11.dylib"
)
# The python-build-standalone dylib has install_name /install/lib/libpython3.11.dylib,
# which gets baked into the target as an absolute dependency that won't exist on the
# user's machine. Rewrite it to @loader_path so dyld finds the copy placed alongside.
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
COMMAND install_name_tool -change
"/install/lib/libpython3.11.dylib"
"@loader_path/libpython3.11.dylib"
"$<TARGET_FILE:${TARGET_NAME}>"
)
endfunction()

set(PYTHON_EXE "${PYTHON_ROOT}/bin/python3.11" CACHE PATH "Python executable")
set(PYTHON_STANDALONE_ROOT "${PYTHON_ROOT}" CACHE PATH "Root of extracted Python standalone distribution")
2 changes: 1 addition & 1 deletion lib/APCpp
Submodule APCpp updated 2 files
+74 −1 Archipelago.cpp
+12 −0 Archipelago.h