The story of "duplicate symbol" after putting Swifty Tesseract and OpenCV

As the title says. The duplicate symbol came out and I was taken aback, so I will leave the solution as a memorandum.

Environmental information

name version
Xcode 12.3 (12C33)
Swift 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
SwiftyTesseract 4.0.0
CMake 3.19.3
Python 2.7.16
xcode-select 2384
OpenCV 4.5.1

Use Swifty Tesseract and OpenCV in the same project

Here are the steps to use the two in the same project.

Add Swifty Tesseract to your project

As of January 19, 2021, Swifty Tesseract can only be added from Swift Package Manager, so add it from Swift Package Manager.

Select "File> Swift Packages> Add Package Dependency ..." on Xcode and select1.png Enter the following GitHub URL in the input field.

https://github.com/SwiftyTesseract/SwiftyTesseract

2.png

Add OpenCV to your project

Build for iOS

Get OpenCV from GitHub and build for iOS with the following command in platform/ios /.

$ ./platform/ios/build_framework.py <output_dir>

Add the built framework file to your project

Select the project file and select the app from "TARGETS" in the left pane. Then select "Build Phases> Link Binary With Libraries (n items)" and add the "opencv2.framework" output by the build by dragging and dropping. 3.png

Add -all_load to Other Linker Flags

Select the project file and select the app from "PROJECT" in the left pane. Select Build Settings and add -all_load to Linking> Other Linker Flags. 6.png

Add libc ++. Tbd to your project

Similarly, select the application from "TARGETS" in the project file. Then select "General> Frameworks, Libraries, and Embedded Content" and press the "+" button at the bottom left. 4.png If you enter "libc ++" in the search window, "libc ++. Tbd" will appear, so add it. 5.png

I'll try to build it ...

Even if I try to build it, it doesn't work at this point. If you look at the error, you can see that there is a tremendous number of conflicts such as "509 duplicate symbols for architecture x86_64 (x86_64 for the simulator, arm64 for the actual machine)". 7.png The solution is to remove the conflicting file from __opencv2.framework __.

Collect files (.o files) that are in conflict

Collect files that are in conflict, relying on errors. In the author's environment, there was a conflict in the following files.

jutils.o pngrio.o pngwio.o jdcoefct.o jaricom.o jdmainct.o jdcolor.o pngerror.o jfdctint.o pngget.o pngrutil.o jmemmgr.o jccoefct.o jcmaster.o jidctflt.o pngpread.o jcprepct.o jerror.o pngset.o jctrans.o jcparam.o jdinput.o pngwtran.o jdarith.o jdsample.o jcomapi.o png.o pngrtran.o jchuff.o jddctmgr.o jidctfst.o jfdctfst.o pngwrite.o jfdctflt.o jdatasrc.o jdapistd.o pngmem.o jdapimin.o pngwutil.o jcdctmgr.o jdtrans.o jdhuff.o jdmaster.o jcapistd.o jdatadst.o jquant2.o jdmerge.o jmemnobs.o jccolor.o jdmarker.o jdpostct.o jcmarker.o jidctred.o jcarith.o jcmainct.o pngtrans.o jcinit.o jcsample.o jquant1.o pngread.o jidctint.o jcapimin.o

Write the above list in a text file etc. so that it will be easy to use when you feed the command as an argument later.

$ echo "jutils.o pngrio.o ..." > duplicate_lib_list

Decompose OpenCV by architecture

Use the lipo command to decompose opencv2 in the framework folder by architecture.

First, check what is included with the following command,

$ cd opencv2.framework
$ lipo -info opencv2
Architectures in the fat file: opencv2 are: armv7 armv7s i386 x86_64 arm64

Use the following command to separate them.

$ lipo -thin armv7 opencv2 -output opencv2_armv7
$ lipo -thin armv7s opencv2 -output opencv2_armv7s
$ lipo -thin i386 opencv2 -output opencv2_i386
$ lipo -thin x86_64 opencv2 -output opencv2_x86_64
$ lipo -thin arm64 opencv2 -output opencv2_arm64

Delete conflicting files

Execute the following command for the separated files to delete the conflicting files from each.

$ cat duplicate_lib_list | xargs ar -dv opencv2_armv7
$ cat duplicate_lib_list | xargs ar -dv opencv2_armv7s
$ cat duplicate_lib_list | xargs ar -dv opencv2_i386
$ cat duplicate_lib_list | xargs ar -dv opencv2_x86_64
$ cat duplicate_lib_list | xargs ar -dv opencv2_arm64

Regenerate from separated files

Execute the following command to regenerate opencv2.

$ lipo -create opencv2_arm64 opencv2_armv7 opencv2_armv7s opencv2_i386 opencv2_x86_64 -output opencv2

After that, delete unnecessary files such as text files created on the way and rebuild. The conflict should be resolved and you should be able to build!

Reference article

  1. OpenCV is now available in Objective-C / Swift & tried using it --Qiita
  2. Avoid "duplicate symbols" error when building with Xcode

Recommended Posts

The story of "duplicate symbol" after putting Swifty Tesseract and OpenCV
Story of putting ubuntu in HDD from complete ignorance and yolov3
This and that of the JDK
The story of @ViewScoped consuming memory
The story of forgetting to close a file in Java and failing
The story of installing raspi-config on ubuntu 18.04 and changing the initial settings of GPIO