Home > Net >  Swift Static Library based on C sources: linker command failed error: ld: symbol(s) not found for
Swift Static Library based on C sources: linker command failed error: ld: symbol(s) not found for

Time:01-09

I've C based swift static library called: FooCppBasedSwiftLibrary

  • It's a Swift Static Library which uses some C sources mixed with Objective C using .mm files (Objective C )
  • ObjectiveC classes are exposed to Swift(within the same library) using module.private.modulemap file
  • Library on its own builds successfully and generated libFooCppBasedSwiftLibrary.a binary and FooCppBasedSwiftLibrary.swiftmodule file BUILT FOR SIMULATOR
  • Then in client app project I added and linked .a file
  • Also in client app project I added .swiftmodule file and given it's parent folder path in SWIFT_INCLUDE_PATHS in app's build settings
  • Now I build client app on same SIMULATOR with same iOS version as in Static Library, But got number of errors like:
// ...100-500 lines error log above...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

enter image description here

CodePudding user response:

TLDR: Use linker flag: -lc   or -lstdc  
// You can skip to the "The Endgame" section below

Initial Workaround

Background

While going through lot of forums for solution I came across someone's thoughts:

NOTE: This text is quoted from a thread of similar question (as mine), but the difference being: Importing Swift Static Library in ObjC Project

This is because the main target (app) is trying to build solely against Objective-C and isn't told by the static library that it needs to include Swift libraries. This was because there weren't any Swift files in the Compile Sources section of our Build Phases for the app target.

So basically all you have to do is add at least one .swift file to that compile list and it will include the Swift libraries for you. It doesn't even need to have any code or values in it, it can be an empty file.

The workaround:

So considering same logic, I thought, my client App Project, which Swift based:

How will it know that static library libFooCppBasedSwiftLibrary.a has used or needs (not sure what's correct word here) standard C libraries, like for eg: std::

So what is did to solve this is:

  • In my client app project clicked on root/any folder "New File..." -> Select "C File" -> Set any file name -> Check "Also create a header file" -> Next -> Create -> You will get Prompt saying "Would you like to configure an Objective-C bridging header?", click on "Create Bridging Header" button

And you are DONE, now build you app it should be working fine!

This is a workaround at best, but not sure if there is any Build Setting that enforces this rahter than adding empty C file.

The Endgame:

After some more digging I found perfect solution to this

Firstly, ignore/undo that inital workaround, we don't need it any more

Go to to client app project's build settings (For app target) and in Other linker flags add -lc or -lstdc and build the app, done!

What to chooese -lc or -lstdc ?

Check "C standard library"/ CLANG_CXX_LIBRARY setting in build settings

if its libc then use: lc in Other linker flags

else if its libstdc then use: lstdc in Other linker flags

I'm assuming this is explicitly telling linker to properly link .a binary of static library with given Standard C library

  •  Tags:  
  • Related