0

Full disclosure: total iOS development amateur here. My background is embedded firmware development.

TLDR: I'm trying to include a shared library, written in C, into a swift project, but getting "undefined symbols" errors

For a project, I'm trying to include a shared library written in C, that I manually cross compiled for ios-arm64 architecture (using xcrun -sdk iphoneos clang -arch arm64 on a macbook ), and I'm trying to include this into a swift based iOS application: as the most simple example let's take the default swift application you get when starting a new iOS application in xcode.

If I understand correctly, the way I should approach this, is adding a target framework to the project (Editor > Add Target > Framework ) and then dragging my shared library (let's name it libcustom.dylib) and my header (custom.h) into the target framework. And then adding this custom header into the framework header file. I also set the framework settings to embed & sign the shared library.

Next, I try to call a function in this shared library in the ViewController.swift file. So what I do is import the framework header and then call the function, let's call it perform_custom_action() (xcode editor also autocompletes it), but when trying to build I get the following error:

Undefined symbol: _perform_custom_action

So there is a linking issue, probably it's not linking the library, but I dont know how I can link it in this xcode environment. I see in the compile output that it includes the framework, but I dont know if this framework is correctly including the library...

Does anyone know how I can fix this?

PS: some sanity checks:

libcustom.dylib is cross-compiled for arm64, output of file libcustom.dylib is:

libcustom.dylib: Mach-O 64-bit dynamically linked shared library arm64

_perform_custom_action is part of the symbols inside libcustom.dylib, when executing nm libcustom.dylib I get

...
00000000005a544 T _perform_custom_action
...

EDIT: extra info:

  • When creating the target framework, a bridging header is automatically created, after adding my own header to it, it looks like this:
//
//  custom_framework.h
//  custom_framework
//
//  Created by <user> on 13.01.22.
//

#import <Foundation/Foundation.h>

//! Project version number for custom_framework.
FOUNDATION_EXPORT double custom_frameworkVersionNumber;

//! Project version string for custom_framework.
FOUNDATION_EXPORT const unsigned char custom_frameworkVersionString[];

// In this header, you should import all the public headers of your framework using statements like #import <custom_framework/PublicHeader.h>

#import "custom_framework/custom.h"

EDIT2: when manually setting linker flags, namely:

  • Library Search Paths : set to $(PROJECT_DIR)/custom_framework
  • Other Linker Flags : set to -lcustom

Then it builds succesfully, so to me it looks like something is wrong in the framework

wilson1994
  • 93
  • 1
  • 7
  • Try `nm -D libcustom.dylib | grep "_perform_custom_action"` and check if you get the same output. – kiner_shah Jan 17 '22 at 11:00
  • Did you create the bridging header ? See https://stackoverflow.com/questions/24004732/how-to-call-c-from-swift – Jean-Baptiste Yunès Jan 17 '22 at 11:09
  • @kiner_shah do you mean `nm -gU libcustom.dylib | grep "_perform_custom_action` as osx has other flags than linux? That does return the expected output – wilson1994 Jan 17 '22 at 12:08
  • @Jean-BaptisteYunès I updated my question with the content of the bridging header, that was auto-generated when creating the framework – wilson1994 Jan 17 '22 at 12:16

0 Answers0