Closed jvkolyadich closed 2 years ago
My most recent setup for static libraries in iOS/MacOS is:
s.pod_target_xcconfig = {
--
| 'DEFINES_MODULE' => 'YES',
| 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386',
| "OTHER_LDFLAGS[sdk=iphoneos*]" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/ios-arm64_armv7/libmylib_staticlib.a",
| "OTHER_LDFLAGS[sdk=iphonesimulator*]" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a",
| }
| s.vendored_frameworks = 'Frameworks/mylib_staticlib.xcframework'
The framework is created by running the following steps from a C source and CMake build.
/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=armv7 -DCODE_SIGN_IDENTITY=<...>
/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=arm64 -DCODE_SIGN_IDENTITY=<...>
/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=arm64
/Applications/CMake.app/Contents/bin/cmake -S /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/src/mylib_staticlib -B /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/ -GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_DEPLOYMENT_TARGET=10.0 -DCMAKE_INSTALL_PREFIX=`pwd`/_install -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_IOS_INSTALL_COMBINED=YES -DCMAKE_OSX_ARCHITECTURES=x86_64
/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/ --target mylib_staticlib -- -sdk iphonesimulator
/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/ --target mylib_staticlib -- -sdk iphoneos
/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/ --target mylib_staticlib -- -sdk iphoneos
/Applications/CMake.app/Contents/bin/cmake --build /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/ --target mylib_staticlib -- -sdk iphonesimulator
lipo -create /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm/Debug-iphoneos/libmylib_staticlib.a /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/ios_arm64/Debug-iphoneos/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphoneos/libmylib_staticlib.a
lipo -create /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_arm64/Debug-iphonesimulator/libmylib_staticlib.a /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iossimulator_x64/Debug-iphonesimulator/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphonesimulator/libmylib_staticlib.a
xcodebuild -create-xcframework -library /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphoneos/libmylib_staticlib.a -library /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/out/iosiphonesimulator/libmylib_staticlib.a -output /Users/dacoharkes/ffi-samples/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.11" CACHE STRING "Minimum OS X deployment version")
project(mylib_staticlib_library VERSION 0.0.1 LANGUAGES C)
add_library(mylib_staticlib STATIC mylib_staticlib.c)
set_target_properties(mylib_staticlib PROPERTIES
PUBLIC_HEADER mylib_staticlib.h
OUTPUT_NAME "mylib_staticlib"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${CODE_SIGN_IDENTITY}"
)
As far as I know, using a framework is the only way to support both the arm64 device and arm64 simulator for iOS. You can also make this to work without a framework:
s.vendored_libraries = 'Frameworks/libmylib_staticlib.a'
s.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/macos-arm64_x86_64/libmylib_staticlib.a" }
Set Strip Style to "Non-Global Symbols"
I believe this is not required.
I created a minimal project that can be used to reproduce the error here: https://github.com/jvkolyadich/libndi_bindings
By downloading the .a
in binary, it is harder to troubleshoot what is going on.
Try using the file
command to see what architectures are in there:
$ file /Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a
/Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a: Mach-O universal binary with 2 architectures: [x86_64:current ar archive random librarycurrent ar archive random library] [arm64:current ar archive random librarycurrent ar archive random library]
/Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a (for architecture x86_64): current ar archive random library
/Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a (for architecture arm64): current ar archive random library
And nm -fC <file>
to see what symbols are in there
$ nm -gC /Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a
/Users/dacoharkes/src/dacoharkes/native_lib_distribution/mylib_staticlib/ios/Frameworks/mylib_staticlib.xcframework/ios-arm64_x86_64-simulator/libmylib_staticlib.a(mylib_staticlib.o):
0000000000000000 T _sum_staticlib
The library I'm using is closed-source, only the header files and the fat static library are provided.
As far as I know, using a framework is the only way to support both the arm64 device and arm64 simulator for iOS. You can also make this to work without a framework:
s.vendored_libraries = 'Frameworks/libmylib_staticlib.a' s.pod_target_xcconfig = { "OTHER_LDFLAGS" => "-force_load $(PODS_TARGET_SRCROOT)/Frameworks/mylib_staticlib.xcframework/macos-arm64_x86_64/libmylib_staticlib.a" }
This is the way I have the project set up, but I'm still getting the Failed to lookup symbol
error.
Running the file
command shows that the library has all the needed architectures for ios (armv7, i386, x86_64, arm64
)
nm -gC
shows that the library contains all the needed symbols, including the one shown in the error message (NDIlib_version
)
arm64
It will only contain either the one for arm64 iosdevice or arm64 iossimulator. Are you running on the iPad Air from your device list?
The next step would be to see if a self-built static library with just a single symbol works, to see if the issue is with how the static library is bundled with your FFI plugin or if the issue is with the closed source static library.
It will only contain either the one for arm64 iosdevice or arm64 iossimulator. Are you running on the iPad Air from your device list?
I've tried it on an iPad Air and on a simulator, but I ended up with the same error on both.
The static library might actually contain the arm64 archive for both devices and simulators.
Earlier, I ran into an issue that said it was built for iOS + iOS Simulator. This should not be done according to Apple, but there is a workaround that allows it to be used anyway.
I don't think that this is the cause of the symbol not found
issue because it wasn't solved by using a self-built static library.
The next step would be to see if a self-built static library with just a single symbol works...
I built a test library with only the NDIlib_version
symbol using the steps from your first comment and used it instead of the closed-source library, but still ended up with the same issue.
I made a new minimal project to test this apart from the specific library I'm trying to use. I started from a new dart_ffi plugin and tried to keep the changes to a minimum. Again, I ran into the same problem.
I was able to get the self-built static library to work by adding its headers to Runner-Bridging-Header.h
and using one of the functions from the library inside of AppDelegate.swift
. However, doing the same for the closed-source library didn't work.
I'm closing this issue since this is likely a problem with the closed-source library.
I'm getting the error message
which is the same one as in issue dart-lang/native#897, but I decided to open a new issue because
Here's what I've done so far:
https://github.com/dart-lang/native/issues/897
I created a minimal project that can be used to reproduce the error here: https://github.com/jvkolyadich/libndi_bindings
flutter doctor -v output: