Skip to content

Building for iPhone (iOS) error: xpc/xpc.h not found in IOSurfaceAPI when including <Metal/Metal.h> in ggml-metal.m #3106

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

Closed
l3utterfly opened this issue Sep 10, 2023 · 8 comments · Fixed by #3116

Comments

@l3utterfly
Copy link
Contributor

Getting the error xpc/xpc.h not found when building targeting iOS.

I followed the fix in this stackoverflow answer: https://stackoverflow.com/questions/24013814/how-to-resolve-xpc-h-not-found-error

I downloaded the necessary headers from: https://github.com/realthunder/mac-headers, then copied the xpc directory in there into the root folder of llama.cpp.

After this fix, iOS builds work.

Is this something wrong with my setup in particular? Or is adding the xpc headers is necessary? If so, should I do a pull request adding the headers?

@jhen0409
Copy link
Collaborator

I've never encountered this before on iOS. What is your Xcode version? Or are you use some other build tool?

Also, the swift package provided some info you can refer to.

@l3utterfly
Copy link
Contributor Author

I'm using XCode 14.3.1 on Ventura 13.5

I'm building llama.cpp from source (not using the swift package). I created the xcodeproject by running CMake in the build folder, then linking the xcodeproj into my project

@jhen0409
Copy link
Collaborator

jhen0409 commented Sep 10, 2023

I took a quick look for IOSurfaceBase.h in the frameworks:

// ...
#if TARGET_OS_OSX
#include <xpc/xpc.h>
#endif

This means it doesn't work on iOS, but I don't think it should reference anything xpc on iOS, so I guess it has something wrong on the generated xcodeproj.

For iOS, I mainly build llama.cpp via CocoaPods, not familiar with CMake + Xcode, it would be great if you could provide a simple demo so I can help try it out.

@l3utterfly
Copy link
Contributor Author

My issue happens in IOSurfaceAPI.h

image

I'm not really familiar with the Apple environment to be honest. Could it be my frameworks are out of date or something?

Regarding the code, I can zip up the xcodeproj generated by cmake for you? I used the same code as in this repo, I didn't make any modifications.

@jhen0409
Copy link
Collaborator

I found the IOSurfaceAPI.h is only exists in the macOS framework and not in the iOS framework, so I guess you're not correctly target to iOS in the xcodeproj.

Path: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOSurface.framework/Headers

You can replace iPhoneOS with MacOSX to find IOSurfaceAPI.h.

Regarding the code, I can zip up the xcodeproj generated by cmake for you? I used the same code as in this repo, I didn't make any modifications.

I think the cmake command you used is better.

@l3utterfly
Copy link
Contributor Author

I used the CMake GUI. Pointed it at the llama.cpp folder, clicked "configure". Set "Xcode", "use default native compiler".

I looked through the CMake options, it seems at this stage all the variables such as "METALKIT_FRAMEWORK" are already set to point to the MacOS path.

@jhen0409
Copy link
Collaborator

jhen0409 commented Sep 10, 2023

Sorry I couldn't try the CMake GUI at this time, but I looking to the doc, it's simple on the command line:

We need to modify CMakeLists.txt to made it work:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e6242dc..17f18eb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -476,7 +476,7 @@ if (NOT MSVC)
     endif()
 endif()
 
-if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
+if ((${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm") OR (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64"))
     message(STATUS "ARM detected")
     if (MSVC)
         # TODO: arm msvc?
@@ -581,6 +581,9 @@ endif()
 if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
     add_compile_definitions(_DARWIN_C_SOURCE)
 endif()
+if (CMAKE_SYSTEM_NAME MATCHES "iOS")
+    add_compile_definitions(_DARWIN_C_SOURCE)
+endif()
 if (CMAKE_SYSTEM_NAME MATCHES "DragonFly")
     add_compile_definitions(_DARWIN_C_SOURCE)
 endif()

It's need to check CMAKE_SYSTEM_NAME is iOS to define _DARWIN_C_SOURCE. I don't why the previously MATCHES OR is broken to me.

mkdir build && cd build
cmake -G Xcode .. \
    -DLLAMA_BUILD_EXAMPLES=OFF \
    -DLLAMA_BUILD_TESTS=OFF \
    -DLLAMA_BUILD_SERVER=OFF \
    -DCMAKE_SYSTEM_NAME=iOS \
    -DCMAKE_OSX_DEPLOYMENT_TARGET=14.0
cmake --build . --config Release

This is works to me, we might be able to contribute a CI step to llama.cpp to ensure it continues to work.

@l3utterfly
Copy link
Contributor Author

l3utterfly commented Sep 11, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants