Swift link and build with C/C++ library

2019-08-20 11:51发布

问题:

I don't have any prior experience with swift.

I have a static library libseriallib.a which was written in C++ but has a C wrapper interface by using extern C.

I want to link this library into a swift iOS application. I am creating this application from scratch.

There are three libraries that libseriallib.a depends on. These are: libz.a, 'libcrypto.a,libssh.a`.

I followed the second method mentioned here (Using module) and tried to build the project. However, I am confused how to link the three dependencies and get it building successfully. Right now I only added libseriallib.a to XCode Build Phases->Link Binary With Libraries section.

The errors I have right now look like this:

Apple Mach-O Linker Warning Group
ld: warning: URGENT: building for iOS simulator, but linking in object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(seriallib.cpp.o)) built for OSX. Note: This will be an error in the future.

ld: warning: object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(seriallib.cpp.o)) was built for newer OSX version (10.11) than being linked (10.0)

ld: warning: URGENT: building for iOS simulator, but linking in object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(mem_buffer.cpp.o)) built for OSX. Note: This will be an error in the future.

ld: warning: object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(mem_buffer.cpp.o)) was built for newer OSX version (10.11) than being linked (10.0)

ld: warning: URGENT: building for iOS simulator, but linking in object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(buffers.cpp.o)) built for OSX. Note: This will be an error in the future.

ld: warning: object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(buffers.cpp.o)) was built for newer OSX version (10.11) than being linked (10.0)

ld: warning: URGENT: building for iOS simulator, but linking in object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(packet_reader2.cpp.o)) built for OSX. Note: This will be an error in the future.

ld: warning: object file (/Users/duminda/dev/swiftlibtest/libseriallib.a(packet_reader2.cpp.o)) was built for newer OSX version (10.11) than being linked (10.0)

Apple Mach-O Linker Error Group
  "std::runtime_error::what() const", referenced from:

  "std::__1::__basic_string_common<true>::__throw_length_error() const", referenced from:

  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:

  "std::__1::ios_base::getloc() const", referenced from:

  "std::runtime_error::runtime_error(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:

Now, it looks like I have to link libstd++ also.

Is there any comprehensive resource to how to link a C/C++ library with a swift iOS app?

Any help would be much appreciated.

回答1:

Take a look into Build settings -> Other linker flags

You have to list there all the libs you have to link, like seriallib, crypto, z, ssh.

Also you need to set the path where those libs can be found via Build settings -> Library search paths

Make sure that you have those libraries available and all of them compiled for actual SDK versions and configurations you are using (this is what linker tells you - OS X vs iOS).



回答2:

You don't have to use module maps in this case. You can add all 4 static libraries in the Build Phases->Link Binary With Libraries section or in the Build Settings -> Other Linker Flags, in which case you need to specify them as -lseriallib -lcrypto -lz -lssh. In either case you also need to add their paths in Build Settings -> Library Search Path, as suggested by ikliashchou.

As for the errors about C++ symbols, those can be resolved by adding -lc++ to Other Linker Flags. That's if the wrapper is a separate library; you should not be getting those errors if the wrapper code is part of the project.

The warnings about architectures won't prevent the app from running in the simulator (for now). However, as soon as you try running it on a device, it won't build because the static libs are not built for an iOS device's architecture.

Building the code in those static libs for a device is a topic in its own right and may be tricky. A few things to consider:

  • Create an Xcode static library project from the library source. This would need to be done for each library.
  • Include all the library sources into your application project (in this case this approach would probably be too messy).
  • The libraries may have yet other dependencies that are not readily available for iOS devices.
  • The library code may have already been ported to iOS, so Google for it.

Here are some links that might be helpful: - How do I compile a library in Xcode using a makefile? - Can I build a static library for iOS without using the Xcode IDE? - Compiling external C++ library for use with iOS project