iOS SDK 5.1 linker error for non_lazy_ptr in Xcode 4.4.1

ios, linker, vlc, xcode

Solution

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.

Problem

(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. 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

Original source

Related problems