Repository navigation
Build macOS with the Command Line Tools instead of full Xcode #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| diff --git a/src/recompilation.cpp b/src/recompilation.cpp | ||
| index c228433..afdfe63 100644 | ||
| --- a/src/recompilation.cpp | ||
| +++ b/src/recompilation.cpp | ||
| @@ -128,7 +128,10 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | ||
|
|
||
| auto hook_find = func.function_hooks.find(instr_index); | ||
| if (hook_find != func.function_hooks.end()) { | ||
| - fmt::print(output_file, " {}\n", hook_find->second); | ||
| + // The leading null statement lets a hook that declares something follow a | ||
| + // branch label under C17 (Clang before 18 rejects it). It is not braced: | ||
| + // hooks declare locals that later hooks in the function read. | ||
| + fmt::print(output_file, " ; {}\n", hook_find->second); | ||
| if (indent) { | ||
| print_indent(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| diff --git a/plume_metal.cpp b/plume_metal.cpp | ||
| index b670ed3..f0ca614 100644 | ||
| --- a/plume_metal.cpp | ||
| +++ b/plume_metal.cpp | ||
| @@ -1342,8 +1342,16 @@ namespace plume { | ||
| functionName->retain(); | ||
|
|
||
| NS::Error *error = nullptr; | ||
| - const dispatch_data_t dispatchData = dispatch_data_create(data, size, dispatch_get_main_queue(), ^{}); | ||
| - library = device->mtl->newLibrary(dispatchData, &error); | ||
| + // Precompiled libraries start with the "MTLB" magic. Anything else is MSL source, | ||
| + // compiled by the OS so macOS builds don't need Xcode's offline Metal compiler. | ||
| + if ((size >= 4) && (memcmp(data, "MTLB", 4) == 0)) { | ||
| + const dispatch_data_t dispatchData = dispatch_data_create(data, size, dispatch_get_main_queue(), ^{}); | ||
| + library = device->mtl->newLibrary(dispatchData, &error); | ||
| + } | ||
| + else { | ||
| + const std::string source(static_cast<const char *>(data), size); | ||
| + library = device->mtl->newLibrary(NS::String::string(source.c_str(), NS::UTF8StringEncoding), nullptr, &error); | ||
| + } | ||
|
|
||
| if (error != nullptr) { | ||
| fprintf(stderr, "MTLDevice newLibraryWithSource: failed with error %s.\n", error->localizedDescription()->utf8String()); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| diff --git a/CMakeLists.txt b/CMakeLists.txt | ||
| index 17563c1..d86dfec 100644 | ||
| --- a/CMakeLists.txt | ||
| +++ b/CMakeLists.txt | ||
| @@ -163,17 +163,15 @@ function(build_shader_msl_impl TARGETOBJ FILENAME TARGET_NAME OUTNAME) | ||
| add_custom_command(OUTPUT ${OUTNAME}.metallib | ||
| COMMAND xcrun -sdk ${_dkr_ios_metal_sdk} metallib ${OUTNAME}.ir -o ${OUTNAME}.metallib | ||
| DEPENDS ${OUTNAME}.ir) | ||
| + set(_dkr_msl_blob ${OUTNAME}.metallib) | ||
| else() | ||
| - add_custom_command(OUTPUT ${OUTNAME}.ir | ||
| - COMMAND xcrun -sdk macosx metal -o ${OUTNAME}.ir -c ${OUTNAME}.metal $<$<CONFIG:Debug>:-frecord-sources> | ||
| - DEPENDS ${OUTNAME}.metal) | ||
| - add_custom_command(OUTPUT ${OUTNAME}.metallib | ||
| - COMMAND xcrun -sdk macosx metallib ${OUTNAME}.ir -o ${OUTNAME}.metallib | ||
| - DEPENDS ${OUTNAME}.ir) | ||
| + # macOS embeds the MSL source; plume compiles it at runtime, so the | ||
| + # build needs no Xcode Metal toolchain. | ||
| + set(_dkr_msl_blob ${OUTNAME}.metal) | ||
| endif() | ||
| add_custom_command(OUTPUT ${OUTNAME}.metal.c | ||
| - COMMAND file_to_c ${OUTNAME}.metallib ${TARGET_NAME}BlobMSL ${OUTNAME}.metal.c ${OUTNAME}.metal.h | ||
| - DEPENDS ${OUTNAME}.metallib file_to_c | ||
| + COMMAND file_to_c ${_dkr_msl_blob} ${TARGET_NAME}BlobMSL ${OUTNAME}.metal.c ${OUTNAME}.metal.h | ||
| + DEPENDS ${_dkr_msl_blob} file_to_c | ||
| BYPRODUCTS ${OUTNAME}.metal.h) | ||
| target_sources(${TARGETOBJ} PRIVATE ${OUTNAME}.metal.c) | ||
| endfunction() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,13 +4,27 @@ source "${BASH_SOURCE[0]%/*}/lib/apple-build.sh" | |
| dkr_macos_host_tools() { | ||
| local skip_deps="$1" make_version probe | ||
| dkr_require_macos || return 1 | ||
| dkr_require_xcode || return 1 | ||
| # Command Line Tools are enough: RT64's Metal shaders compile at runtime. | ||
| xcrun --sdk macosx --show-sdk-path >/dev/null 2>&1 || { | ||
| echo 'Install the Command Line Tools: xcode-select --install' >&2 | ||
| return 1 | ||
| } | ||
| if [[ "$skip_deps" -eq 0 ]]; then | ||
| command -v brew >/dev/null || { | ||
| echo 'Install Homebrew: https://brew.sh/' >&2 | ||
| return 1 | ||
| } | ||
| HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_UPGRADE=1 brew install --quiet cmake ninja make pcre2 python sdl2 coreutils || return 1 | ||
| # Install only what is missing: on macOS releases Homebrew no longer | ||
| # bottles, reinstalling a present tool (python) means a failing source build. | ||
|
Comment on lines
+17
to
+18
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| local pair missing=() | ||
| for pair in cmake:cmake ninja:ninja make:gmake pcre2:pcre2-config sdl2:sdl2-config coreutils:sha1sum; do | ||
| command -v "${pair#*:}" >/dev/null || missing+=("${pair%%:*}") | ||
| done | ||
| # tomllib needs 3.11; the Command Line Tools ship 3.9. | ||
| python3 -c 'import sys; sys.exit(sys.version_info < (3, 11))' 2>/dev/null || missing+=(python) | ||
| if [[ "${#missing[@]}" -gt 0 ]]; then | ||
| HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_UPGRADE=1 brew install --quiet "${missing[@]}" || return 1 | ||
| fi | ||
| fi | ||
| dkr_require_tools git python3 cmake ninja c++ shasum sha1sum pcre2-config sdl2-config || { | ||
| echo 'Run ./Setup-macOS.sh (sha1sum is supplied by brew install coreutils).' >&2 | ||
|
|
@@ -39,11 +53,4 @@ dkr_macos_host_tools() { | |
| return 1 | ||
| fi | ||
| rm -rf -- "$probe" | ||
| if ! xcrun metal -v >/dev/null 2>&1; then | ||
| if [[ "$skip_deps" -eq 1 ]]; then | ||
| echo 'Install Metal: xcodebuild -downloadComponent MetalToolchain' >&2 | ||
| return 1 | ||
| fi | ||
| xcodebuild -downloadComponent MetalToolchain || return 1 | ||
| fi | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RasterShadercallscreateShaderwith these blobs for every new combiner/other-mode combo (src/render/rt64_raster_shader.cpp:166-167), so I think every specialized raster shader now recompiles the whole ubershader MSL, not just once at setup. The 2.66 s number only covers setup. We should watch for pop-in during gameplay on a cold cache.Maybe keep the metallib when
xcrun -sdk macosx -f metalresolves at configure time and only embed source when it doesn't? The plume patch already handles both, and CI/release builds keep the old load path and build-time shader errors.