I have a C file containing a function my_library_function()
that I have compiled into a static library using gcc
and packaged into an xcframework called mylib.xcframework
using xcodebuild -create-framework
. I have added this framework to an Xcode project for a Mac App. However within my Mac App I am unable to call this function, and am generally unsure about how to do so. I have tried import mylib
from within Swift files and tried to directly call the function my_library_function()
but in both cases have gotten compiler errors No such module mylib
and Use of unresolved identifier 'my_library_function'
. The only workaround I have found is to create a bridging header and #include
the header file from its path within the xcframework. However, since eventually I would like to work with a more complex library and cross compile and have the xcframework include static libraries for multiple targets this seems like a hacky workaround. Is there some way I can do this without the bridging headers, am I missing something in this process?
Below are exact instructions of exactly what I did. First I compiled the C code into a static library. The source code for the library contains a single function:
#include <stdio.h>
void my_library_function(void) {
printf("called from a static library");
}
mylib.c
I also have a header for the above:
void my_library_function(void);
mylib.h
The tree for the source code is as follows:
.
├── include
│ └── mylib.h
└── mylib.c
Project source tree
I then compiled the C code into a static library using:
> gcc -c mylib.c -o mylib.o
> ar rcs mylib.a mylib.o
Then I created an xcframework with:
xcodebuild -create-xcframework -library mylib.a -headers include -output mylib.xcframework
This resulted in an xcframework as so:
.
├── Info.plist
└── macos-x86_64
├── Headers
│ └── mylib.h
└── mylib.a
mylib.xcframework source tree
I then created a new Xcode project using Xcode 11.
At the root of the project I created a new group and called it Frameworks. I then dragged and dropped the xcframework into XCode frameworks group and checked the copy items if needed checkbox and the create groups radio button.
In the Xcode projects general tab, under Frameworks, Libraries and Embedded Content I set the framework to Embed & Sign.
Under the Build Settings tab, under Signing, I set Other Code Signing Flags to --deep
to prevent a codesign error. In the same Build Settings tab, under Linking, the Runpath Search Paths is set to @executable_path/../Frameworks/
. Additionally in the Build Settings tab under Search Paths, I have tried to set the Framework Search Paths, Library Search Paths and Header Search Paths to this same value @executable_path/../Frameworks/
and I have also tried with these paths as empty.
Unfortunately I am not able to use the my_library_function()
from anywhere in the application, nor am I able to import mylib
from Swift.
The only workaround I have found is to create an objective C bridging header and make a #include
explicitly point within the framework folder into the Headers/mylib.h
to be able to call my function. This seems like a hacky solution though as eventually I would like to cross compile my code and will have separate header files for each separate library for different architectures and it might get quite complex to do it this way. Is there something I am missing as to how to include my function from within an XCFramework with a MacOS Swift project?
Below are some images of my Xcode configuration:
I built with clang instead of gcc and included a clang modulemap file alongside the header. It now builds and even offers Xcode autocompletion.