4

I have been wrestling with this for weeks now. Why does the following macOS setup give an Alamofire linker error ?

Steps to recreate linker error:

  • Create new macOS Command Line app
  • Run pod init from Terminal Update
  • Create the following podfile:

    platform :osx, ’10.10’ target 'testMacOS' do use_frameworks! pod 'Alamofire', '~> 4.0' end

Run pod install. Open and Build workspace

Error: dyld: Library not loaded: @rpath/Alamofire.framework/Versions/A/Alamofire Reason: image not found

AT THIS POINT, this error made sense. You needed to go to the Target's / General / Linked Frameworks and Libraries. Then add Alamofire. Now Alamofire was inside the workspace's Framework directory.

Build and run. Same error. Why?

3 Answers 3

12

You need to set @rpath manually, Pod install frameworks at "$(ProductDirectory)/$(FrameworkName)/$(FrameworkName).framework".

For example, your Alamofire framework is located at "$(ProductDirectory)/Alamofire/Alamofire.framework". Therefore, you need to add "@executable_path/Alamofire/" into your own target's Building Settings - Runpath Search Paths.

Furthermore, "Pods Project - Alamofire(Target)" also need to specify the swift runtime dynamic library position. In my environment, I need to add "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx" into "Building Settings - Runpath Search Paths".

But for convenient, you can have a look my pod post_install code.

post_install do |installer|
    files = Dir.glob("*.xcodeproj")
    proj_file = files[0]
    app_project = Xcodeproj::Project.open(proj_file)

    app_project.native_targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = '$(inherited) @executable_path/../Frameworks @loader_path/Frameworks'
            prefix = ' @executable_path/'

            # For each pod, add the framework path to LD_RUNPATH_SEARCH_PATHS
            installer.pods_project.targets.each do |pod_target|
                config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = config.build_settings['LD_RUNPATH_SEARCH_PATHS'] + prefix + pod_target.name + '/'

                pod_target.build_configurations.each do |pod_config|
#if you want embed swift stdlib into every framework, uncommend 1,2 and commend 3,4
#1
#pod_config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'YES'
#2
#pod_config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = '$(inherited) @executable_path/../Frameworks @loader_path/Frameworks'

#3
pod_config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'NO'
#4
pod_config.build_settings['LD_RUNPATH_SEARCH_PATHS'] = '$(inherited) /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/'
                end
            end
        end
    end

    app_project.save
end
Sign up to request clarification or add additional context in comments.

Comments

3

PROBLEM: with Xcode 8.1, I did not realize that macOS Command Line apps do not support Frameworks (dynamic libraries) in the same way as iOS or desktop macOS apps do with a bundle.

SOLUTION: I got around this by taking the source code off github and compiling it inside my workspace. That worked. Importing a static library also worked.

Comments

2

Commandline tools do indeed "support" Frameworks, but not in the way Application bundles do. You need to put the referenced frameworks in the @rpath which in practice is ~/Library/Frameworks/ or /Library/Frameworks/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.