Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS SDK 5.1 linker error for non_lazy_ptr in Xcode 4.4.1

(I posted this question to the VideoLAN forum, but have had no takers yet. I know the SO community won't let me down.)

I am trying to build the MobileVLC project for iOS. I have gone through the command line process to build the project, and after a couple of tweaks as described in http://forum.videolan.org/viewtopic.php?f=12&t=103331 and http://forum.videolan.org/viewtopic.php?f=12&t=103271, the build script runs almost to completion. It errors out when it tries to get Xcode to build the final project. So I load it into Xcode and try to build, and I can see the error, here is what I get when I use the -v linker flag:

Ld /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos/VLC.app/VLC normal armv7
    cd /Users/bp/Desktop/vlc/MobileVLC
    setenv IPHONEOS_DEPLOYMENT_TARGET 5.1
    setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk -L/Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos -L/Users/bp/Desktop/vlc/MobileVLC/External/MobileVLCKit -L/Users/bp/Desktop/vlc/MobileVLC/External/MediaLibraryKit -F/Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos -filelist /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Intermediates/MobileVLC.build/Debug-iphoneos/MobileVLC.build/Objects-normal/armv7/VLC.LinkFileList -dead_strip -Wl,-no_pie,-v -fobjc-link-runtime -miphoneos-version-min=5.1 -framework Foundation -framework UIKit -framework CoreGraphics -framework OpenGLES -framework AudioToolbox -framework QuartzCore -liconv -lz /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos/libMobileMediaLibraryKit.a -lsqlite3 -lstdc++.6 -lbz2 -lxml2 -framework CoreData -framework CoreText -framework MediaPlayer /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos/libMobileVLCKit.a -o /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos/VLC.app/VLC

@(#)PROGRAM:ld  PROJECT:ld64-133.3
configured to support archs: armv6 armv7 i386 x86_64
Library search paths:
   /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos
   /Users/bp/Desktop/vlc/MobileVLC/External/MobileVLCKit
   /Users/bp/Desktop/vlc/MobileVLC/External/MediaLibraryKit
   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib
Framework search paths:
   /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos
   /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/System/Library/Frameworks/
LLVM version 3.1svn, from Apple Clang 4.0 (build 421.0.60)
ld: 'non_lazy_ptr' in /Users/bp/Library/Developer/Xcode/DerivedData/MobileVLC-ctcjnpeqzuhulxcmjlhrjnyzpzil/Build/Products/Debug-iphoneos/libMobileVLCKit.a(libdeinterlace_plugin_la-deinterlace.o) contains undefined reference for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

As far as I can tell, the libMobileVLCKit.a file is linked into the MobileVLC project, so I am unsure what to look for next, as I cannot find any references to non_lazy_ptr anywhere in any code, and the framework references all look good. Even if you do not know the solution, any ideas as to where to look for the problem would be appreciated. Thanks.

EDIT: Here is a screen capture showing everything in the Build Phases tab of the MobileVLC project.

MobileVLC Build Phases

EDIT 2: My posting on the VideoLAN forums has gotten some "me too" replies, along with an error that is very similar looking to my error from another user. Here is the final line with the error message:

ld: '_AmplifyFloat' in /Users/**/MobileVLC/ImportedSources/VLCKit/build/Release-iphoneos/libMobileVLCKit.a(libvolume_neon_plugin_la-volume.o) contains undefined reference for architecture armv7

Here is the posting on the VideoLAN forum: http://forum.videolan.org/viewtopic.php?f=12&t=103433

EDIT 3: I grabbed a fresh copy of the source from VideoLAN's git repository and went through the answer provided below by user1071136, and ended up with the same exact error that they got as well.

I found a similar looking error on Stack Overflow that indicated the solution was to check to make sure that the Generate Position-Dependent Code option in the Apple LLVC compiler 4.0 - Code Generation build setting was set to No. But as usual in trying to get VLC running on iOS, that was a dead end also as the build setting is already set to No for that.

Here is a link to that question and answer: (null): In section __TEXT,__text reloc 3: section For Address(0x7C6C) address not in any section for architecture armv7

like image 505
BP. Avatar asked Aug 18 '12 02:08

BP.


1 Answers

I haven't been able to successfully build it, but I've overcome some hurdles which might be useful.

Hurdle 1: ARM Thumb2

Summary: Even though advertised as fully supporting thumb, it appears Apple's provided clang, as well as LLVM 3.2's one fail to translate some valid thumb instructions which appear in libav's ARM-assembler code.

Details: libav (a fork of ffmpeg) has some functionality implemented in assembler. When building for iOS, files from MobileVLC/ImportedSources/vlc/contrib/iPhoneOS/ffmpeg/libavcodec/arm are used. The first compile error one will probably encounter is something similar to

libavcodec/arm/aacpsdsp_neon.S:132:21: error: invalid operand for instruction
        add r4, r0, #38*64*4

According to ARM Thumb2's reference, the above instruction is a valid ADD{S} Rd, Rn, <Operand2> instruction, where <Operand2> in thumb mode is "a 32-bit constant, formed by left-shifting an 8-bit value by any number of bits". Since #38*64*4 equals 38 left-shifted 8 times, clang should accept it. It seems that clang won't recognize it's possible, therefore attempting to interpret the instruction as a ADD Rd, Rn, #<imm12> one, for which the immediate argument must be smaller than 4096.

If somebody with more confidence on the subject can relate - is it a bug in clang?

Workaround: As noted in http://forum.videolan.org/viewtopic.php?f=12&t=103271, thumb should be disabled when configuring ffmpeg (which is in fact libav).

Hurdle 2: libtool cannot infer tag

Summary: MobileVLC's libtool is configured to infer C++ compilations, which expects an invokation of clang++. When the build system calls gas-preprocessor.pl xcrun clang instead, libtool throws an error.

Details: MobileVLC configures a copy of libtool (which is just a bash script) at MobileVLC/ImportedSources/vlc/build-ios-OS. On line 1681, the function func_infer_tag is responsible for, well, inferring the tag. For each tag that appears in the variable $available_tags defined on line 38, libtool itself is searched for a tag configuration section. For example, the CXX (=C++) tag configuartion begins on line 9258. As can be seen on line 9271, the compiler command which is expected of a C++ compilation is xcrun clang++.

The build system calls something like libtool --mode=compile gas-preprocessor.pl xcrun clang …, and since xcrun clang++ does not prefix the command, the C++ mode cannot be inferred. (gas-preprocessor.pl translates GNU Assembler into something Apple's assembler can work with)

Workaround: As noted in http://forum.videolan.org/viewtopic.php?f=12&t=103331, MobileVLC/ImportedSources/vlc/modules/video_filter/Modules.am can be modified to force libtool to infer a C compilation. If it doesn't work for you, like it didn't for me, you can call libtool yourself.

cd into MobileVLC/ImportedSources/vlc/build-ios-OS/modules/video_filter; typing make should cause the error to appear. Typing make V=1 will also show the command being executed. It will start with source='deinterlace/merge_arm.S' o…. You can now copy it and call it manually, adding --tag=CC after ../../libtool.

Hurdle 3: CopyStringsFile

Summary: Building MobileVLC fails with the error,

The following build commands failed:
    CopyStringsFile build/Release-iphoneos/VLC.app/pl.lproj/Localizable.strings Resources/pl.lproj/Localizable.strings

Details: The offending file, MobileVLC/Resources/pl.lproj/Localizable.strings is a UTF-16-LE file missing a byte-order-mark (BOM), which confuses Xcode for some reason.

Workaround: cd into MobileVLC/Resources/pl.lproj/ and execute

mv -n Localizable.strings Localizable.strings.backup && python -c "import sys; sys.stdout.write(chr(0xFF)+chr(0xFE))" > Localizable.strings && cat Localizable.strings.backup >> Localizable.strings

This will add the BOM to the beginning of the file.

Hurdle 4: non_lazy_ptr + AmplifyFloat

Summary: This error should read: "An internal data structure of the linker ld has a non-lazy pointer which contains the address of a symbol ld cannot find". The missing symbols cannot be found because they are not prefixed with an underscore.

Details: It is obviously a shame that ld won't indulge us with the knowledge of what exactly it can't find, but we're not here to rant.

Consider the following simple bla.c file,

int bla();
int foo() { return bla(); }

Compiling this file (clang -c bla.c) and then listing its symbols (nm bla.o) reveals that the linker expects some other compilation unit to provide the symbol _bla (note the underscore). The underscore is presumably added to signify bla should be called in the C calling convention. The problem arises when bla is defined in an assembler file; the assembler does not add an underscore, resulting in a bla symbol, leading to linking failure.

An interesting detail is that this behaviour is different to Linux, where an underscore is not added to symbol names, which probably helped the problem escape the attention of VLC's devs. Still, the underscoring behavior appears in MinGW as far as I know, so the solution could be similar.

Workaround: The simplest solution, even if ad-hoc, is to use a symbol alias list. Create a file symbol-alias.txt with the following contents,

merge16_arm_neon _merge16_arm_neon
merge8_arm_neon _merge8_arm_neon
amplify_float_arm_neon _amplify_float_arm_neon

This file is enough depending on flags and configurations; it was enough for me, though. Type open MobileVLC.xcodeproj when in the MobileVLC/ directory. This should laungh Xcode. In project settings, choose the MobileVLC target, and then Build Settings. In Other Linker Flags, add

-Wl,-alias_list
-Wl,<absoluate-path-to-symbol_aliases.txt>

Save and build. Congratulations. You now have reached the Hurdle I don't know how to overcome :)

Hurdle 5: Address not in any section

Summary: The linker fails with the cryptic error

ld: in section __TEXT,__text reloc 13: sectionForAddress(0xE142) address not in any section for architecture armv7

I'm not sufficiently familiar with linking to figure out what's wrong, but I guess it all boils down to code written in assembler.

like image 58
user1071136 Avatar answered Sep 28 '22 00:09

user1071136