skip to Main Content

I’m trying to achieve weak linking with static libraries. I’ve read those two articles, "Static Library on iOS" and "How Jesse Pinkman cracked Dynamic Library on iOS", which are really helpful.

However, I’m in a situation that I cannot achieve what I want. I’ve developed two frameworks, let’s call them Main and Feature, they can be installed both as pods and swift packages.

Main doesn’t have a dependency on Feature, nor Feature on Main, but if both Main and Feature are present on the podfile of the developer, then Main can use Feature’s functionality. This is achieved by adding the Framework’s path on the Main’s framework search paths in its podspec.

Main.podspec

# This works when use_frameworks! is added in the podfile.
s.pod_target_xcconfig = {
    "FRAMEWORK_SEARCH_PATHS" => [
      "$(inherited)",
      "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
}

This way, Main can use Feature’s functionality the following way

#if canImport(Feature)
print("SUCCESS!!!")
let feat = Feature()
feat.test()
#else
print(“Failed to import Feature“)
#endif

The problem starts when the integrating developer doesn’t include use_frameworks! In his podfile (e.g. React Native). Main and Feature are then built as static libraries, it compiles but it never gets inside the SUCCESS block.

After reading the above articles, I believe that the correct approach would be something like the following

Main.podspec

s.pod_target_xcconfig = {
    "LIBRARY_SEARCH_PATHS" => [
      "$(inherited)",
      "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
    "SWIFT_INCLUDE_PATHS" => [
        "$(inherited)",
        "${PODS_CONFIGURATION_BUILD_DIR}/Feature",
    ],
  }

And maybe also add

  Main.podspec

  s.pod_target_xcconfig = {
   …
    'OTHER_LDFLAGS' => [
        "$(inherited)",
        '-ObjC',
        '-weak_library -l"Feature"'
    ],
    …
  }

I’ve tried the above with both Defines module = YES/NO on the Feature‘s side.

Feature.podspec

s.pod_target_xcconfig = {
    'DEFINES_MODULE' => 'YES'
}

However, none of the above worked. Does anyone have any idea of what I might be doing wrong, or point me in some direction?

2

Answers


  1. @e_pie I think what you are trying to do is a post_install stuff if you are clear about Main‘s dependency on Feature.

    So, the things you tried are actually perfect, but should be put on post_install like this in App’s Podfile:

    post_install do |installer|
      installer.pods_project.targets.each do |target|
        if target.name == "Main"
          target.build_configurations.each do |config|
            config.build_settings['FRAMEWORK_SEARCH_PATHS'] = "${PODS_CONFIGURATION_BUILD_DIR}/Feature"
          end
        end
      end
    end
    

    I hope it helps, please let me know if it doesn’t.

    Login or Signup to reply.
  2. I ended up mocking what you need here.

    But, I could solve only half (without use_frameworks) of your problem by:

    Main.podspec
    
    # To include Swift Module
    'OTHER_SWIFT_FLAGS' => ['$(inherited)', '-Xcc -fmodule-map-file="${PODS_CONFIGURATION_BUILD_DIR}/Feature/Feature.modulemap"']
    

    Podspec Side:

    • Not sure why modulemap file path is needed with cocoapod setup (may be when a library is weakly linked)

    Podfile Side:

    • It will work without use_frameworks
    • It won’t work with use_frameworks as modulemap file won’t be found in the specified path (as it considers only for static path scenario) & Xcode will think it’s needed. Not sure how to optionally specify a modulemap file in the Podspec.

    I hope I was able to help even though it’s half way.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search