Metal-cpp link errors

Not quite understanding these. As far as I can tell the Foundation, QuartzCore and Metal frameworks are included in the link line:

-framework Metal -framework QuartzCore -framework Foundation

Technically they are in there a few times. Not familiar enough with our project to know why.

Getting a ton of undefined symbols. Metal-cpp is a header only library and so doesn't have any additional libraries of it's own right?

Undefined symbols for architecture arm64:
"MTL::Private::Selector::s_knewTextureViewWithPixelFormat_textureType_levels_slices_swizzle_", referenced from:
"MTL::Private::Selector::s_knewTextureWithDescriptor_", referenced from:
"NS::Private::Selector::s_kinit", referenced from:
"NS::Private::Selector::s_kautorelease", referenced from:

This is while compiling for iOS (thus the arm64).

  • Was thinking of this more and realizing it probably has something to do with the private implementation, but I do have a .cpp file that defines and includes it:

    `#define NS_PRIVATE_IMPLEMENTATION #define CA_PRIVATE_IMPLEMENTATION #define MTL_PRIVATE_IMPLEMENTATION

    #include <Foundation/Foundation.hpp> #include <Metal/Metal.hpp> #include <QuartzCore/QuartzCore.hpp>`

    That .cpp is located in a library, whereas the framework is on the final link (but that's kind of what I'd expect).

Add a Comment

Replies

Hi scarrow,

As you pointed out, you need to define the NS_PRIVATE_IMPLEMENTATION, MTL_PRIVATE_IMPLEMENTATION, and CA_PRIVATE_IMPLEMENTATION macros before including the .hpp files in exactly one cpp file. This makes metal-cpp generate the symbols that are listed as missing in your linker message.

As you go through this process, make sure that you have not already included the headers prior to the macro definitions. This can happen for example if you include metal-cpp from a custom header file, and that header is then included into your .cpp before the macros are defined.

For example, this would prevent symbol generation:

in A.h:

#include <Metal/Metal.hpp>

in A.cpp:

#include "A.h" // A.h already included Metal.hpp, preventing the macros from taking effect.
#define NS_PRIVATE_IMPLEMENTATION
#define MTL_PRIVATE_IMPLEMENTATION
#define CA_PRIVATE_IMPLEMENTATION
#include <Metal/Metal.hpp>

To solve this problem, you should move the line #include "A.h" to a place after you have included Metal.hpp, or just reposition the macro definitions with the inclusion of the metal-cpp headers to the top of your cpp file.

Please let us know if this helps you address the issue.

  • Ah, that is probably what is happening. I think some of the Apple includes were causing some issues for our earlier includes and so they are a bit further down in the file. It might make sense that they then hit something else that included Metal earlier. Thanks!

Add a Comment

I had this same problem and it was resolved by changing the Xcode option of "compile sources as: c/objc" to "according to filetype" or just c++.