Skip to content

About static framework used

ShenYj edited this page Mar 15, 2022 · 1 revision

About static framework used

准备一个空项目、两个framework 静态库和 .xcconfig 文件

  • 目录结构

    .
    ├── AFNetworking
    │   ├── AFAutoPurgingImageCache.h
    │   ├── AFCompatibilityMacros.h
    │   ├── AFHTTPSessionManager.h
    │   ├── AFImageDownloader.h
    │   ├── AFNetworkActivityIndicatorManager.h
    │   ├── AFNetworkReachabilityManager.h
    │   ├── AFNetworking-umbrella.h
    │   ├── AFNetworking.h
    │   ├── AFSecurityPolicy.h
    │   ├── AFURLRequestSerialization.h
    │   ├── AFURLResponseSerialization.h
    │   ├── AFURLSessionManager.h
    │   ├── UIActivityIndicatorView+AFNetworking.h
    │   ├── UIButton+AFNetworking.h
    │   ├── UIImageView+AFNetworking.h
    │   ├── UIKit+AFNetworking.h
    │   ├── UIProgressView+AFNetworking.h
    │   ├── UIRefreshControl+AFNetworking.h
    │   ├── WKWebView+AFNetworking.h
    │   └── libAFNetworking.a
    ├── AFNetworking2
    │   ├── AFAutoPurgingImageCache.h
    │   ├── AFCompatibilityMacros.h
    │   ├── AFHTTPSessionManager.h
    │   ├── AFImageDownloader.h
    │   ├── AFNetworkActivityIndicatorManager.h
    │   ├── AFNetworkReachabilityManager.h
    │   ├── AFNetworking-umbrella.h
    │   ├── AFNetworking.h
    │   ├── AFSecurityPolicy.h
    │   ├── AFURLRequestSerialization.h
    │   ├── AFURLResponseSerialization.h
    │   ├── AFURLSessionManager.h
    │   ├── UIActivityIndicatorView+AFNetworking.h
    │   ├── UIButton+AFNetworking.h
    │   ├── UIImageView+AFNetworking.h
    │   ├── UIKit+AFNetworking.h
    │   ├── UIProgressView+AFNetworking.h
    │   ├── UIRefreshControl+AFNetworking.h
    │   ├── WKWebView+AFNetworking.h
    │   └── libAFNetworking2.a
    ├── StaticFrameworkUsed
    │   ├── AppDelegate.swift
    │   ├── Assets.xcassets
    │   ├── Base.lproj
    │   │   ├── LaunchScreen.storyboard
    │   │   └── Main.storyboard
    │   ├── Config.xcconfig
    │   ├── Info.plist
    │   ├── SceneDelegate.swift
    │   └── ViewController.swift
    └── StaticFrameworkUsed.xcodeproj

这里面两套 AFN 的代码完全相同,只是最终链接生成的静态库名称不同
项目中没有 import和使用 AFN

  • .xcconfig 配置

    // 1. -I: 头文件
    HEADER_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
    // 2. -L: library 所在目录
    LIBRARY_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
    // 3. -l 名称
    OTHER_LDFLAGS = $(inherited) -l "AFNetworking" -l "AFNetworking2"

此时编译、运行都正常

由于链接一个静态库时默认采用的是 noall_load,所以链接的时候已经找到了 AFNetworking,后面再去找 AFNetworking2的时候就会被剥离

  • 将其改成 all_load-ObjC

    OTHER_LDFLAGS = $(inherited) -all_load -l "AFNetworking" -l "AFNetworking2"
    
  • 再次编译,提示符号冲突

    
    ...省略
    
    duplicate symbol '_OBJC_IVAR_$_AFRefreshControlNotificationObserver._refreshControl' in:
        /Users/shenyj/Desktop/StaticFrameworkUsed/AFNetworking/libAFNetworking.a(UIRefreshControl+AFNetworking.o)
        /Users/shenyj/Desktop/StaticFrameworkUsed/AFNetworking2/libAFNetworking2.a(UIRefreshControl+AFNetworking.o)
    ld: 223 duplicate symbols for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    
    

使用force_load与load_hidden解决符号冲突

  • load_hidden 的介绍

    -load_hidden path_to_archive
        Uses specified static library as usual, but treats all global symbols from the static library to as if they are
        visibility hidden.  Useful when building a dynamic library that uses a static library but does not want to export
        anything from that static library.

    man ld -> 搜索关键字即可

    将隐藏所有的全局符号,相当于设置为本地符号,这样将其隐藏,也就不会产生符号冲突了

  • 使用 force_loadload_hidden, 修改 .xcconfig 如下

    // 1. -I: 头文件
    HEADER_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
    // 2. -L: library 所在目录
    LIBRARY_SEARCH_PATHS = $(inherited) "${SRCROOT}/AFNetworking" "${SRCROOT}/AFNetworking2"
    // 3. -l 名称
    //OTHER_LDFLAGS = $(inherited) -all_load -l "AFNetworking" -l "AFNetworking2"
    OTHER_LDFLAGS = $(inherited) -l "AFNetworking" -l "AFNetworking2" -Xlinker -force_load -Xlinker "${SRCROOT}/AFNetworking/libAFNetworking.a" -Xlinker -load_hidden -Xlinker "${SRCROOT}/AFNetworking2/libAFNetworking2.a"
    

这样也能解决符号冲突的问题

示例项目 下载链接

Getting Started

Social

Clone this wiki locally