0

In migrating custom Core Image filter kernels to Metal Shading Language, I encountered an error with building the default Metal library (default.metallib):

metallib: error: exactly one input file required

I was under the impression these could be in separate .metal files. Attempting to merge them into one file leads to this error:

Metal library creation failed: Error Domain=MTLLibraryErrorDomain Code=3 "Filters module must contain no vertex/fragment/kernel functions but contains 1 kernel function"

Namespacing to metal and to coreimage prevent the compute kernel from showing up as an available function in the default library.

Found this SO answer, which recommends building separate libraries:

Metal: vertexFunction defined in .metal file becomes nil once setting Compiler and Linker Options for MSL cikernel

narnar
  • 23
  • 4

2 Answers2

1

You may create multiple Foo.metal and Bar.metal files. Just don't add them as linker targets.

Instead #include "Foo.metal" and #include "Bar.metal" in a Main.metal file. And only add the Main.metal file as linker target.

That way there is only one .metal file, which includes all the other .metal files. Simple.


Therefore the content of the Main.metal file may very simply look like:

#include "Foo.metal"
#include "Bar.metal"
SirEnder
  • 564
  • 4
  • 14
0

You can’t use the default Metal build pipeline for compiling multiple .metal files containing Core Image kernels into one library right now. The linker doesn’t allow merging multiple .air files into one .metallib when setting the -cikernel flag.

You either have to put all your kernels into one .metal file or use the solution I posted in the answer you linked to above.

Frank Rupprecht
  • 9,191
  • 31
  • 56
  • Thank you for your reply! What's the correct way to merge the files? I tried keeping the compute function the same (top-level scope), and adding the CIKernel functions using the `extern "C" { namespace coreimage { // implementation } }` namespacing, but encountered the error "Filters module must contain no vertex/fragment/kernel functions but contains 1 kernel function". Couldn't find any documentation on how to namespace the compute function. – narnar Nov 07 '19 at 16:25
  • Oh, I guess you can’t mix “regular” Metal shaders with Core Image kernels because CI kernels require special treatment. You’d have to compile them into different libs, I guess… – Frank Rupprecht Nov 07 '19 at 18:36