Metal with C library

Hi Caroline :slight_smile: Thank you for the elegant example of how to use Metal. I have a question that is somewhat off-topic to the game challenge, but it doesn’t really fit anywhere in the tutorial, which is excellent and has helped me understand Metal so much better.

I am trying to include a c library in the project you’ve built. The library compiles without errors, but as soon as I add it’s header to common.h, when I build, xcode tries to find c headers in the iPhone SDK, which of course breaks. If I try to include the library the same way in a new xCode 11 swift project without metal, it compiles without problems.

Can you point me in the right general direction? Why might Metal (which is written in c) have a conflict finding system c headers when another c lib is included?

I have more details here:

I am thoroughly at a loss for a resolution, any thoughts would be a great help :slight_smile: Thanks!!

@lewis-h thank you for the code fragment, but I’m not sure how it applies. Could you say more about why this is a solution to the problem? Thanks!

@agiglbox Do you still have issues with this?

Thank You for asking ShogunKaramazov, I have resolved the issue. For the sake of anyone who finds themselves with a similar error, here are the details of problem.

Task: I was integrating a third party library written in C into the metal example project provided in a tutorial on this site. I had compiled the library into an archive, and had the appropriate headers, but there are two aspects which affect how the library has to be handled, which were complicating the root cause of the error.

First, I need to process strings with the library, and those have to be sent to C functions as pointer parameters. I had written a C wrapper for the library functionality and imported the wrapper’s function declaration in a bridging header - a conventional way to import C functions in a Swift project. However, in this Metal project the bridging header is imported via a Metal shader because it defines structs for a bunch of code that runs on the GPU. Code that runs on the GPU has to designate itself correctly within the address spaces allowed on the GPU. Since the C function wrapper had pointers as parameters (string processing), the compiler was requiring an address space to be specified for the pointers, and there is no construct for doing that with C.

There is only one bridging header allowed per target in an xCode project. But there is another way to reference library header files, you can write a module map, and import it in the build settings. So I wrote a module map for the C library, and that resolved the problem of making the library code available for functionality running on the CPU - which I fine, I didn’t want to use the library in anything running on the GPU.

A second issue with this library is that while it has only one public header file, it also uses macros to expose functionality, and they aren’t simple variable definitions, they are complex macros. Swift doesn’t process complex C macros. It took some digging for me to understand this :). So instead of referencing the headers directly in a Swift file, I wrote a C wrapper for the C library functionality which referenced the macros, and Swift is just fine with importing the C wrapper functions instead of dealing with the macros directly.

In the process of resolving all of these issues, thinking I had left the extremely confounding error detailed in the stackoverflow description behind, I was somewhat more than mildly horrified to find a similar error with new code I had written in C. I really need to know more about how all of this is wired together to articulate this issue, and the mistake is clearly a silly error but it looks like xCode does not like to find things like stdio.h both in a C header file, and again in the C source file. When the compiler tries to resolve the second reference to the same header, it generates the same error messages I was seeing with my library integration error. So - I think - the root cause of the really messy error message was that I was integrating the library in such a way that xCode tried to import it twice, the second time it tried to actually re-compile the library archive.

I beg your pardon for the long explanation, and if you have more to add which corrects any thing I may have mis-represented, I will be grateful for your insight :). Also, I realize the Metal is not written in C, but is written in Obj-C.

This topic was automatically closed after 166 days. New replies are no longer allowed.