Undefined symbols for architecture armv7 when using ZXing library in Xcode 4.5

Krishnabhadra picture Krishnabhadra · Oct 19, 2012 · Viewed 28.1k times · Source

What I am trying to do

Integrate Zxing, QR code reader framework, in my iPhone project. I checked out ZXing sdk from here. I ran the sample project coming with ZXing, named ScanTest, without any issues. But when I try to integrate the library with my project I am getting the error mentioned.

Project specification

  • Target OS : iOS 6.0
  • Deployment target : iOS 5.0 or above.
  • Tested on : iPhone 4 and iPhone 3GS.
  • Xcode : Xcode 4.5.1
  • ZXing version : 2.0

Problem

When I build, after doing every integration step in ZXing readme file, I am getting build errors like

Undefined symbols for architecture armv7:
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<<<std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      zxing::qrcode::Detector::computeDimension(zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, zxing::Ref<zxing::ResultPoint>, float) in libZXingWidget.a(Detector-B8B28E953F840D47.o)

Undefined symbols for architecture armv7:
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)", referenced from:
      zxing::Exception::Exception(char const*) in libZXingWidget.a(Exception.o)
      zxing::common::StringUtils::guessEncoding(unsigned char*, int, std::map<unsigned int, std::string, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, std::string> > >

There are 27 errors like that.. I only copied the first two.

What did I found out

Well, I went through this, this ,this ,this, this, this,this threads in stackoverflow, all with the same error message. None of the solutions worked for me.

Then I found this closed thread in ZXing forums discussing the same issue. From that discussion, some possible solutions are (worked for some)

The first error is (probably) because you haven't renamed main.m to main.mm. The second error is (probably) because you're not linking against the widget library

I also renamed my main.m, cross checked whether I have added the library only to find I surely had. So this is not the case.

After I changed the Architectures of the library to "Standard (armv7, armv7s)" to match my main project I was able to successfully compile the app.

My project, target, library project (for debug, distribution, release) architecture is given as Standard (armv7, armv7s). So no luck there either.

Then they closed the issue saying this,

The zxing projects have been updated to add the armv7s arch and remove the armv6 arch. These changes are required (1) to build for the iPhone 5 which is armv7s and (2) to build at all since Xcode 4.5 does not include support for armv6. If you have your own project files, you'll need to make these changes yourself. These are general changes not specific to zxing so if you have trouble, you make get more/quicker help in a general forum like StackOverflow.

So here I am, in StackOverflow.

One more point

In ZXing integration README file , the first step in integration is,

1) Locate the "ZXingWidget.xcodeproj" file under "zxing/iphone/ZXingWidget/". Drag ZXingWidget.xcodeproj and drop it onto the root of your Xcode project's "Groups and Files" sidebar. A dialog will appear -- make sure "Copy items" is unchecked and "Reference Type" is "Relative to Project" before clicking "Add". Alternatively you can right-click on you project navigator and select 'Add files to "MyProject"'.

When I dragged the ZXingWidget.xcodeproj file to my project, there was no dialog. The project directly added to the project and I could not set, "copy items" and "Reference Type" properties. I don't know if it is a new feature of Xcode 4.5 or a bug. That is the only step I couldn't correctly follow as per the README file.

Well, you have all the information that I have with me. I have been trying to fix this for 6 hours. Any idea?

Answer

Krishnabhadra picture Krishnabhadra · Oct 19, 2012

Well, at last I got it working.. For anyone who encounters this in the future..

  1. Rename the main.m file to main.mm.

    ZXing's README states why we need this

    It can happen that when trying to build your own project with ZXingWidgetController you get linker errors like "undefined reference to". If this error looks like a c++ undefined reference, then renaming main.m into main.mm (Objective-C++ source suffix) may fix the problem

  2. Rename the file (ViewController/View) which uses ZXing libray functions so that it also has .mm extension.

  3. Check architecture settings across project. Give architecture and valid architecture as armv7 armv7s in your project settings, target settings, and ZXing project (which you added to your main project) and target settings.

  4. In main project -> Build Settings scroll and find out the options, C++ Language Dialect and C++ Standard Library. Select options "Compiler Default" for both of them. (This is the step I missed, It is needed because newest XCode template has compiler default settings different to what they were in older versions).

  5. You also might have to set ZXingWidget's "Build Valid Architecture Only" flag set as NO. In my case, this field was already NO

These fixed the issue for me..

Update

On December 2013, Google has retired ZXing iOS/Objective C port. So Zxing project for iOS is no longer maintained and updated for new iOS versions. Also Zxing doesn't have support for Arm64 architecture which is one of the standard architecture as per new XCode versions.

So developers are encouraged to move over to the native Apple framework to read barcode which is available from iOS7 onwards. See this for a step by step tutorial.