“dyld: Library not loaded” error

2019-01-28 02:12发布

问题:

i have successfully compiled static library and added it to the XCode project just like it's written in documentation:

  1. libclang.a file is in project directory (added file copy and group)
  2. libclang.a is listed in "Frameworks"
  3. i've added '-Objc' linker flag to 'Other linker flags'.
  4. libclang.a is listed in "Copy bundle resources"

libclang.a is compiled for ios simulator:

MBA-Anton:llvm_34_build_i386 asmirnov$ lipo -info ../llvm_34_ios_i386_installed/lib/libclang.a
input file ../llvm_34_ios_i386_installed/lib/libclang.a is not a fat file
Non-fat file: ../llvm_34_ios_i386_installed/lib/libclang.a is architecture: i386

I'm able to build the project but i'm getting error while ios simulator starts the app:

dyld: Library not loaded: @rpath/libclang.dylib
  Referenced from: /Users/asmirnov/Library/Application Support/iPhone Simulator/7.1/Applications/D87A3FA9-7207-40B4-9EA0-5F06CEF6EF7B/StaticLibraryUsage.app/StaticLibraryUsage
  Reason: image not found

I have found similar questions but it seems i did everything what was recommended. Any thoughts?

PS. I have libclang.dylib file but i'm not sure it's really needed since i have added libclang.a file in the project.

PPS. I have compiled armv7 version of libclang.a and created fat library with both i386 and armv7 using lipo. After removing i386 version of libclang.a and adding fat version of libclang.a i have multiple unresolved references for i386 arch build errors.

PPPS. I have resolved "unresolved references" errors by adding all libLLVM*.a files in the project. but now i'm having original "dyld: Library not loaded".

PPPPS: .m compile command-line:

CompileC /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/ASAppDelegate.o StaticLibraryUsage2/ASAppDelegate.m normal i386 objective-c com.apple.compilers.llvm.clang.1_0.compiler
    cd /Users/asmirnov/Documents/dev/src/iOS_Projects/StaticLibraryUsage2
    export LANG=en_US.US-ASCII
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.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 -x objective-c -arch i386 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu99 -fobjc-arc -fmodules -fmodules-cache-path=/Users/asmirnov/Library/Developer/Xcode/DerivedData/ModuleCache -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Werror=return-type -Wno-implicit-atomic-properties -Werror=deprecated-objc-isa-usage -Werror=objc-root-class -Wno-receiver-is-weak -Wno-arc-repeated-use-of-weak -Wduplicate-method-match -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wconditional-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wshorten-64-to-32 -Wpointer-sign -Wno-newline-eof -Wno-selector -Wno-strict-selector-match -Wundeclared-selector -Wno-deprecated-implementations -DDEBUG=1 -DDEBUG=1 -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk -fexceptions -fasm-blocks -fstrict-aliasing -Wprotocol -Wdeprecated-declarations -g -Wno-sign-conversion -fobjc-abi-version=2 -fobjc-legacy-dispatch -mios-simulator-version-min=7.1 -iquote /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/StaticLibraryUsage2-generated-files.hmap -I/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/StaticLibraryUsage2-own-target-headers.hmap -I/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/StaticLibraryUsage2-all-target-headers.hmap -iquote /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/StaticLibraryUsage2-project-headers.hmap -I/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator/include -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -I/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/DerivedSources/i386 -I/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/DerivedSources -F/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator -include /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/PrecompiledHeaders/StaticLibraryUsage2-Prefix-baynabgphydhcmapwpcclpqhagrv/StaticLibraryUsage2-Prefix.pch -MMD -MT dependencies -MF /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/ASAppDelegate.d --serialize-diagnostics /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/ASAppDelegate.dia -c /Users/asmirnov/Documents/dev/src/iOS_Projects/StaticLibraryUsage2/StaticLibraryUsage2/ASAppDelegate.m -o /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/ASAppDelegate.o

link command-line:

Ld /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator/StaticLibraryUsage2.app/StaticLibraryUsage2 normal i386
    cd /Users/asmirnov/Documents/dev/src/iOS_Projects/StaticLibraryUsage2
    export IPHONEOS_DEPLOYMENT_TARGET=7.1
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.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 i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk -L/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator -L/Users/asmirnov/Documents/dev/src/llvm_34_ios_fat_installed -L/Users/asmirnov/Documents/dev/src/iOS_Projects/StaticLibraryUsage2/StaticLibraryUsage2 -L/Users/asmirnov/Documents/dev/src/llvm_34_ios_i386_installed_2/lib -F/Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator -filelist /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/StaticLibraryUsage2.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -ObjC -lstdc++ -fobjc-arc -fobjc-link-runtime -Xlinker -no_implicit_dylibs -mios-simulator-version-min=7.1 -lLLVMRuntimeDyld -lLLVMSystemZAsmParser -lLLVMAArch64CodeGen -lLLVMTarget -lLLVMMCJIT -lLLVMX86Disassembler -lLLVMExecutionEngine -lLLVMPowerPCInfo -lLLVMHexagonAsmPrinter -lLLVMX86Utils -lLLVMPowerPCAsmParser -lclangDriver -lLLVMARMInfo -lLLVMAArch64AsmParser -lLLVMHexagonDesc -lLLVMipa -lclangARCMigrate -lLLVMMipsDesc -lLLVMNVPTXCodeGen -lLLVMBitWriter -lLLVMXCoreDisassembler -lLLVMNVPTXDesc -lLLVMX86CodeGen -lLLVMHexagonInfo -lLLVMSystemZAsmPrinter -lLLVMTableGen -lLLVMSystemZCodeGen -lLLVMInstrumentation -lLLVMAArch64Disassembler -lLLVMX86AsmPrinter -lLLVMCppBackendInfo -lclangBasic -lLLVMCodeGen -lLLVMDebugInfo -lLLVMAArch64Utils -lLLVMNVPTXAsmPrinter -framework CoreGraphics -lLLVMAsmParser -lLLVMSparcCodeGen -lclangFormat -lLLVMXCoreDesc -lLLVMipo -lLLVMObject -lclang -lLLVMX86Desc -lLLVMPowerPCDesc -lLLVMXCoreCodeGen -lLLVMVectorize -lclangAST -lclangSema -lclangTooling -lLLVMIRReader -lLLVMMipsCodeGen -lclangRewriteCore -lLLVMXCoreAsmPrinter -lLLVMMSP430Desc -lLLVMInstCombine -lLLVMAArch64AsmPrinter -lLLVMMCParser -lLLVMR600Info -lLLVMMipsAsmPrinter -lLLVMMipsAsmParser -lLLVMMCDisassembler -lLLVMBitReader -lclangAnalysis -lclangStaticAnalyzerCore -lLLVMMipsDisassembler -lLLVMR600AsmPrinter -lLLVMR600CodeGen -lLLVMAArch64Info -lclangDynamicASTMatchers -lLLVMARMAsmPrinter -lLLVMXCoreInfo -lclangStaticAnalyzerFrontend -lLLVMMipsInfo -lLLVMSelectionDAG -lLLVMTransformUtils -lLLVMSparcInfo -lLLVMR600Desc -lLLVMOption -lLLVMAArch64Desc -lLLVMObjCARCOpts -lLLVMJIT -lclangEdit -lLLVMSystemZDesc -lLLVMARMDesc -lLLVMSparcDesc -lLLVMMC -lLLVMMSP430CodeGen -lLTO -lLLVMHexagonCodeGen -lLLVMMSP430AsmPrinter -framework UIKit -lLLVMAnalysis -lLLVMMSP430Info -lLLVMARMCodeGen -lLLVMARMAsmParser -lclangCodeGen -lLLVMLinker -lLLVMPowerPCCodeGen -lLLVMAsmPrinter -lLLVMX86AsmParser -lLLVMSystemZInfo -framework Foundation -lclangASTMatchers -lLLVMScalarOpts -lLLVMPowerPCAsmPrinter -lLLVMARMDisassembler -lLLVMNVPTXInfo -lclangParse -lclangIndex -lclangStaticAnalyzerCheckers -lclangRewriteFrontend -lLLVMInterpreter -lclangLex -lLLVMCppBackendCodeGen -lLLVMX86Info -lLLVMCore -lLLVMLTO -lclangFrontend -lclangFrontendTool -lLLVMSupport -lLLVMSystemZDisassembler -lclangSerialization -Xlinker -dependency_info -Xlinker /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Intermediates/StaticLibraryUsage2.build/Debug-iphonesimulator/StaticLibraryUsage2.build/Objects-normal/i386/StaticLibraryUsage2_dependency_info.dat -o /Users/asmirnov/Library/Developer/Xcode/DerivedData/TestProject-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator/StaticLibraryUsage2.app/StaticLibraryUsage2

libclang.a adding to executable command-line:

CpResource /Users/asmirnov/Documents/dev/src/llvm_34_ios_i386_installed_2/lib/libclang.a /Users/asmirnov/Library/Developer/Xcode/DerivedData/PocketIDE-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator/StaticLibraryUsage2.app/libclang.a
    cd /Users/asmirnov/Documents/dev/src/iOS_Projects/StaticLibraryUsage2
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -resolve-src-symlinks /Users/asmirnov/Documents/dev/src/llvm_34_ios_i386_installed_2/lib/libclang.a /Users/asmirnov/Library/Developer/Xcode/DerivedData/PocketIDE-axtxqjlvmrcxqsfnvgobybceosvb/Build/Products/Debug-iphonesimulator/StaticLibraryUsage2.app

controller code to test libclang:

#import "Index.h"

// ...

// show diagnostics
void showHighlight(CXTranslationUnit TU, const char *src_filename, unsigned filesize)
{
    if (TU)
        NSLog(@"Translation unit valid: %s\n", src_filename);

    CXFile file = clang_getFile(TU, src_filename);

    if (file)
        NSLog(@"file is valid, size = %i\n", filesize);

    unsigned int line, column, offset;

    CXToken *tokens;
    unsigned numTokens;

    // range = all the file
    CXSourceLocation beginning = clang_getLocationForOffset(TU, file, 0);
    CXSourceLocation end = clang_getLocationForOffset(TU, file, filesize);
    CXSourceRange range = clang_getRange(beginning, end);

    clang_tokenize(TU, range, &tokens, &numTokens);

    NSLog(@"%i tokens:\n", numTokens);

    for (int i=0; i<numTokens; i++) {
        CXToken token = tokens[i];

        CXTokenKind kind = clang_getTokenKind(token);
        CXSourceLocation location = clang_getTokenLocation(TU, token);
        clang_getSpellingLocation(location, &file, &line, &column, &offset);
        CXString filename = clang_getFileName(file);
        CXString spelling = clang_getTokenSpelling(TU, token);

        NSLog(@"kind=[%s], [%s %i:%i offset=%i] [%s]\n",
                kinds[kind], clang_getCString(filename), line, column, offset, clang_getCString(spelling));

        clang_disposeString(filename);
        clang_disposeString(spelling);
    }

    clang_disposeTokens(TU, tokens, numTokens);
}

unsigned getfilesize(const char* filename)
{
    FILE *fp = fopen(filename, "r");
    fseek(fp, 0L, SEEK_END);
    unsigned sz = ftell(fp);
    fclose(fp);
    return sz;
}
- (void)testClang
{
    NSLog(@"started");

    // get file from bundle
    NSString *ns_filename = [[NSBundle mainBundle] pathForResource:@"test_hl" ofType:@"cpp"];
    BOOL fileExists = [[NSFileManager defaultManager]fileExistsAtPath:ns_filename];
    NSLog(@"file %@ exists: %d", ns_filename, fileExists);

    CXIndex index = clang_createIndex(false, false);

    // command-line tu
    const char *filename = [ns_filename UTF8String];
    const char *argv = { filename };
    int argc = 1;
    CXTranslationUnit commandLineTu = clang_parseTranslationUnit(index, 0, &argv, argc, 0, 0, CXTranslationUnit_None);

    unsigned filesize = getfilesize(filename);
    showHighlight(commandLineTu, filename, filesize);

    clang_disposeTranslationUnit(commandLineTu);
    clang_disposeIndex(index);

    NSLog(@"finished");
}

- (void)viewWillAppear:(BOOL)animated
{
    [self testClang];
}

回答1:

What this error is sadly trying to tell you is that lib clang thinks its @rpath is at the root of your app bundle, but it's not.

I figured this out the hard way just the other day. It's hard. You have to do some crazy stuff with libclang.a using Build Phase settings. In your target's Build Phases, you will need to add a few Run Script Phases.

One will be this:

echo "warning: OTOOL BEGIN1";
pwd;
otool -L ${SRCROOT}/Clangwrap/ClangAndLLVM/lib/libclang.dylib;
echo "Warning: OTOOL END1";

This just does a few things. First it nicely sandwiches things with a log to see what happened. The second is it really is just confirming the path to your lib once it's copied. (and yes, you should be copying it into your project to keep things sane.) otool does this. SRCROOT is the root of your project, then anything after that is your relative path within you project's folder in Finder to the lib you are going to use.

Again, this just confirms it is where you think it is.

Ok, next step. This is the real doozy.

echo "BEGIN install_name_tool";
install_name_tool -id @executable_path/../Frameworks/libclang.dylib ${SRCROOT}/Clangwrap/ClangAndLLVM/lib/libclang.dylib;
echo "END install_name_tool";

This runs the obscure command line tool install_name_tool and that is used to set the path where the lib thinks it is located within your app's bundle. Without doing this, the lib will think it is in some other path. You will be setting this path to what you intend it to be. In a Mac app, I used the Frameworks folder inside the bundle so I set it as such. The first argument to install_name_tool is the relative path in your app bundle where the lib is going to be. The second argument is where the lib is currently in your project so that install_name_tool can set its executable path. This literally modifies a bit of the lib so it is loadable. libs must know their own load path.

Note the first step is only optional for your own sanity. The second step is required, and both should occur before the Compile Sources Build Phase. Click and drag to move them up.

Now the final step. Add a new Copy Files Phase and this will remain last in your build phases. Set the destination to the same as the first arg of install_name_tool so you know your relative path is set and that's where you're going to put the lib. I used Frameworks. Now add the files to this Build Phase, for iPhone, add libclang.a (I don't think you can use libclang.dylib on iOS)

Note, you saw me use libclang.dylib and that's because I did this on a Mac app project. It should be the same process for just about anything.

this is not an easy or discoverable process, I pieced it together from several blogs and docs.