{"id":29001651,"url":"https://github.com/juniperphoton/cimetalcompilerplugin","last_synced_at":"2025-06-25T09:11:08.676Z","repository":{"id":295497341,"uuid":"990264250","full_name":"JuniperPhoton/CIMetalCompilerPlugin","owner":"JuniperPhoton","description":"Swift Package plugin to compile and link Core Image Metal Shaders to a single Metal Library that can be use in code.","archived":false,"fork":false,"pushed_at":"2025-06-12T03:14:04.000Z","size":42,"stargazers_count":20,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-12T04:27:29.631Z","etag":null,"topics":["core-image","metal","swift-package-manager"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuniperPhoton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-25T20:36:13.000Z","updated_at":"2025-06-12T03:14:07.000Z","dependencies_parsed_at":"2025-05-25T22:19:48.503Z","dependency_job_id":"6934e54d-5982-4585-aa48-436fd270ddae","html_url":"https://github.com/JuniperPhoton/CIMetalCompilerPlugin","commit_stats":null,"previous_names":["juniperphoton/cimetalcompilerplugin"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/JuniperPhoton/CIMetalCompilerPlugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuniperPhoton%2FCIMetalCompilerPlugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuniperPhoton%2FCIMetalCompilerPlugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuniperPhoton%2FCIMetalCompilerPlugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuniperPhoton%2FCIMetalCompilerPlugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuniperPhoton","download_url":"https://codeload.github.com/JuniperPhoton/CIMetalCompilerPlugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuniperPhoton%2FCIMetalCompilerPlugin/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261841937,"owners_count":23217918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["core-image","metal","swift-package-manager"],"created_at":"2025-06-25T09:11:07.431Z","updated_at":"2025-06-25T09:11:08.655Z","avatar_url":"https://github.com/JuniperPhoton.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CIMetalCompilerPlugin\n\nA Swift Package plugin to compile and link Core Image Metal Shaders to a single Metal Library that can be use in code. \n\nThis repo significantly changed some implementations of this [original repo](https://github.com/schwa/MetalCompilerPlugin).\n\nMore details and insights about creating a Swift Package plugin can be [read here](https://juniperphoton.substack.com/p/creating-core-image-metal-shader).\n\n\u003e Note: For Xcode 26 Beta, there will be some compiling issues when using Swift Package Plugin. More investigations are to come.\n\n# Background\n\nWhy do you need this Swift Package Plugin?\n\n1. Compiling and linking Core Image Metal Shaders (not pure Metal Shaders) requires specifying certain flags (`-fcikernel` and `-cikernel`) in the Xcode Build Settings.\n2. Swift Package Manager doesn't support setting user-defined flags for compiling and linking Metal Shaders.\n3. Therefore, you have to put your Core Image Metal Shaders inside a Framework to prebuild, or inside a target to build.\n4. If you have Swift code that resides in a Swift Package and reads the Metal library, the code and the shader code can't be in the same package.\n5. Putting shader code inside targets to build increases the app bundle size, as the built artifacts will exist in every target that uses the shader code.\n\n\u003e Note: Swift Package can build pure Metal Shader out of the box. Separating your Core Image Metal Shader and pure Metal Shader should be a good start.\n\n# Usage \n\nAdd this package as a dependency to your Swift Package:\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/JuniperPhoton/CIMetalCompilerPlugin\", from: \"0.11.0\")\n]\n```\n\nSpecify the plugin to use for your target.\n\n```swift\ntargets: [\n    .target(\n        name: \"MyPackage\",\n        exclude: [\n            \"Shaders/\"\n        ],\n        plugins: [\n            .plugin(name: \"CIMetalCompilerPlugin\", package: \"CIMetalCompilerPlugin\")\n        ]\n    )\n]\n```\n\nNote:\n\n1. You should put all your Core Image Metal Shaders in a folder like `Shaders`, as shown above, including any C headers that are included in the shaders.\n2. You also need to explicitly exclude the entire `Shaders` folder, as the Swift Package build system will still try to build the shaders and will fail.\n\nAfter the Swift Packgage being built, the `default.metallib` will reside in the Package's Bundle. Get this file using `Bundle.module` in your Swift Package's code:\n\n```swift\nlet url = Bundle.module.url(forResource: \"default\", withExtension: \"metallib\")\n```\n\n# How does it work under the hood\n\nIt internally iterates over the directory to find all files that end with \"metal\".\n\nThen it uses the equivalent command to create the intermediate files:\n\n```shell\nxcrun metal -c -fcikernel MyKernel.metal -o MyKernel.air \"-fmodules=none\" \n```\n\n\u003e Clang enables Modules for Metal by default. Enabling Modules will cause the build to fail when running on Xcode Cloud, as it may not have permissions to write the files to the system default cache dir. Thus, disabling Modules by specifying `-fmodules=none` or specifying the dir in the plugin sandbox dir `-fmodules-cache-path=xxxx` will do the trick.\n\nFor each intermediate file:\n\n```shell\nxcrun metallib --cikernel MyKernel.air -o MyKernel.metallib\n```\n\nThose `metallib` can be already used directly in code:\n\n```swift\nlet resource = \"your_metallib_name\"\n\nguard let url = Bundle.module.url(forResource: resource, withExtension: \"metallib\") else {\n    return nil\n}\n\nguard let data = try? Data(contentsOf: url) else {\n    return nil\n}\n\nlet kernel = try? CIKernel(functionName: functionName, fromMetalLibraryData: data)\n```\n\nThey can be then merged into one `default.metallib`:\n\n```shell\nxcrun metal -fcikernel -o default.metallib MyKernel1.metallib MyKernel2.metallib ...\n```\n\n# Useful Links\n\nThe original repo: \n\nhttps://github.com/schwa/MetalCompilerPlugin\n\nBuilding a Shader Library by Precompiling Source Files:\n\nhttps://developer.apple.com/documentation/metal/building-a-shader-library-by-precompiling-source-files\n\nXcrun:\n\nhttps://keith.github.io/xcode-man-pages/xcrun.1.html\n\nClang Modules:\n\nhttps://clang.llvm.org/docs/Modules.html#problems-with-the-current-model\n\n# License\n\nBSD 3-clause. See [LICENSE.md](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuniperphoton%2Fcimetalcompilerplugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuniperphoton%2Fcimetalcompilerplugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuniperphoton%2Fcimetalcompilerplugin/lists"}