• clang在编译时指定目标文件所需的最低macOS版本


    调研这个的原因,是因为有个同事在macOS 12.2上打包好的程序,放在macOS 10.15上运行时报错:

    Dyld Error Message:
      Symbol not found: __ZNKSt3__115basic_stringbufIcNS_11char_traitsIcEENS_9allocatorIcEEE3strEv
      Referenced from: /Library/Application Support/XXX.dylib (which was built for Mac OS X 12.2)
      Expected in: /usr/lib/libc++.1.dylib

    调研了一番,发现这个是因为Apple的SDK使用weak linking来支持不同版本的macOS。

    中有对这些宏的检查,会导致生成不同的二进制代码。","marks":[]}]}],"state":{}},{"type":"block","id":"UiU2-1667533383300","name":"heading","data":{"level":"h2"},"nodes":[{"type":"text","id":"AWuh-1667533383298","leaves":[{"text":"通过环境变量","marks":[]},{"text":"设置deployment target","marks":[{"type":"bold"}]}]}],"state":{}},{"type":"block","id":"L084-1667532954811","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"tkXT-1667532954810","leaves":[{"text":"这个参数也可通过环境变量来设置。命令行优先于环境变量。","marks":[]}]}],"state":{}},{"type":"block","id":"RqDm-1667533224306","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"ZKfB-1667533224305","leaves":[{"text":"MACOSX_DEPLOYMENT_TARGET","marks":[]}]}],"state":{}},{"type":"block","id":"pwrG-1667533228861","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"MDPl-1667533228859","leaves":[{"text":"IPHONEOS_DEPLOYMENT_TARGET","marks":[]}]}],"state":{}},{"type":"block","id":"bEuH-1667533232338","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"8JOt-1667533232336","leaves":[{"text":"TVOS_DEPLOYMENT_TARGET","marks":[]}]}],"state":{}},{"type":"block","id":"iTjL-1667533237741","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"HxdW-1667533237740","leaves":[{"text":"WATCHOS_DEPLOYMENT_TARGET","marks":[]}]}],"state":{}},{"type":"block","id":"8dUX-1667533247860","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"RBax-1667533247859","leaves":[{"text":"DRIVERKIT_DEPLOYMENT_TARGET","marks":[]}]}],"state":{}},{"type":"block","id":"tpW4-1667533659704","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"CiS1-1667533659702","leaves":[{"text":"","marks":[]}]}],"state":{}},{"type":"block","id":"8i3I-1667533442923","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"gsOy-1667533442921","leaves":[{"text":"我们的工程以及我们的工程所直接/间接依赖的所有静态库/动态库,都需要在编译时指定相同的deployment target。","marks":[]}]}],"state":{}},{"type":"block","id":"FVLX-1667533572034","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"LrGQ-1667533572033","leaves":[{"text":"省事的办法是通过环境变量来统一设置,在开始整个打包之前设置一下","marks":[{"type":"color","value":"#CC0000"}]},{"text":"。","marks":[]}]}],"state":{}},{"type":"block","id":"4gem-1667534252416","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"1a9G-1667534252414","leaves":[{"text":"其次是命令行开关。不同工程类型的命令行开关设置方法有差异。以下是命令行开关的设置。","marks":[]}]}],"state":{}},{"type":"block","id":"PsjN-1667533631113","name":"heading","data":{"level":"h2","style":{"indent":0}},"nodes":[{"type":"text","id":"mQrg-1667533631112","leaves":[{"text":"通过vcpkg install编译的库","marks":[]}]}],"state":{}},{"type":"block","id":"om1J-1667533675273","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"kJP2-1667533675272","leaves":[{"text":"需要更改vcpkg/triplets/x64-osx.cmake文件的内容,增加下面三行:","marks":[]}]}],"state":{}},{"type":"block","id":"eqi3-1667533746390","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"E8xS-1667533746388","leaves":[{"text":"set(VCPKG_OSX_DEPLOYMENT_TARGET \"10.15\")","marks":[]}]}],"state":{}},{"type":"block","id":"mYt6-1667533756773","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"tKFA-1667533756774","leaves":[{"text":"\r","marks":[]}]}],"state":{}},{"type":"block","id":"nBmL-1667533756775","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"mxTT-1667533756776","leaves":[{"text":"set(VCPKG_C_FLAGS -mmacosx-version-min=10.15)\r","marks":[]}]}],"state":{}},{"type":"block","id":"XI1V-1667533756777","name":"paragraph","data":{"version":1,"style":{"indent":28}},"nodes":[{"type":"text","id":"5qBI-1667533756778","leaves":[{"text":"set(VCPKG_CXX_FLAGS -mmacosx-version-min=10.15)","marks":[]}]}],"state":{}},{"type":"block","id":"Ywkw-1667533780274","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"12Pj-1667533780273","leaves":[{"text":"也可以复制这个文件到某个目录下,在复制出来的文件中增加上面这三行,然后给vcpkg install传递--overlay-triplets参数以使用这个修改过的triplet文件。这样通过vcpkg install安装的所有库的deployment target都是10.15。","marks":[]}]}],"state":{}},{"type":"block","id":"8UMI-1667533952008","name":"heading","data":{"level":"h2","style":{"indent":0}},"nodes":[{"type":"text","id":"9uPE-1667533952007","leaves":[{"text":"autoconf类型的工程","marks":[]}]}],"state":{}},{"type":"block","id":"ouFq-1667533995146","name":"paragraph","data":{"version":1,"style":{"indent":0}},"nodes":[{"type":"text","id":"VRRA-1667533995145","leaves":[{"text":"比如qzhddrfileidentify中使用的libiconv库目前是手动执行autoconf编译的,需要在configure时增加参数:","marks":[]}]}],"state":{}},{"type":"block","id":"hmte-1667534068733","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"w469-1667534068732","leaves":[{"text":"./configure CFLAGS=-mmacos-version-min=10.15 CPPFLAGS=-mmacos-version-min=10.15","marks":[]}]}],"state":{}},{"type":"block","id":"9TVW-1667534294178","name":"heading","data":{"level":"h2"},"nodes":[{"type":"text","id":"J1Lt-1667534294177","leaves":[{"text":"CMake工程","marks":[]}]}],"state":{}},{"type":"block","id":"UMvp-1667534299207","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"Yb3c-1667534299206","leaves":[{"text":"在CMakeLists.txt里的project()语句","marks":[]},{"text":"之前","marks":[{"type":"color","value":"#CC0000"}]},{"text":"增加一句:","marks":[]}]}],"state":{}},{"type":"block","id":"iJuE-1667534358158","name":"paragraph","data":{"version":1,"style":{"textIndent":28}},"nodes":[{"type":"text","id":"wAcl-1667534358157","leaves":[{"text":"set(CMAKE_OSX_DEPLOYMENT_TARGET \"10.15\")","marks":[]}]}],"state":{}},{"type":"block","id":"MF1e-1667534795802","name":"paragraph","data":{"version":1,"style":{"textIndent":0}},"nodes":[{"type":"text","id":"0MPq-1667534795801","leaves":[{"text":"或者","marks":[]}]}],"state":{}},{"type":"block","id":"5TXr-1667534800127","name":"paragraph","data":{"version":1,"style":{"textIndent":28}},"nodes":[{"type":"text","id":"ePYz-1667534800126","leaves":[{"text":"set(CMAKE_OSX_DEPLOYMENT_TARGET \"10.15\" CACHE STRING \"\" FORCE)","marks":[]}]}],"state":{}},{"type":"block","id":"A1DK-1667534100597","name":"heading","data":{"level":"h2"},"nodes":[{"type":"text","id":"VZfq-1667534100595","leaves":[{"text":"Xcode工程","marks":[]}]}],"state":{}},{"type":"block","id":"Dk34-1667534118817","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"X3IF-1667534118815","leaves":[{"text":"在界面的工程属性中可以设置deployment target。","marks":[]}]}],"state":{}},{"type":"block","id":"MWpV-1667534547837","name":"heading","data":{"level":"h2"},"nodes":[{"type":"text","id":"vEcZ-1667534547836","leaves":[{"text":"Makefile工程","marks":[]}]}],"state":{}},{"type":"block","id":"Son4-1667534552214","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"HYyQ-1667534552213","leaves":[{"text":"在makefile里自行给clang传递参数-mmacos-version-min=10.15即可。","marks":[]}]}],"state":{}},{"type":"block","id":"vMwz-1667535471635","name":"paragraph","data":{"version":1},"nodes":[{"type":"text","id":"fka6-1667535471634","leaves":[{"text":"","marks":[]}]}],"state":{}}]">
    目标文件所需的最低macOS版本有个专有名称“deployment target”。
     
    查看库的deployment target
    查看*.dylib、*.a或者主程序的deployment target属性、sdk版本:
    otool -l 7z.dylib | grep -E "(minos|sdk)"
    find . -name "*.a" | xargs otool -l | grep -E "(minos|sdk)"

    通过命令行参数设置deployment target
    clang/clang++在编译时指定deployment target的命令行参数是-mmacos-version-min,比如:-mmacos-version-min=10.15,指定最低为Catalina的最后一个版本10.15。
    针对iOS等有类似的开关如-miphoneos-version-min、-mtvos-version-min、 -mwatchos-version-min。
    -mmacos-version-min有个别名-mmacosx-version-min,别名只是为了兼容,尽量不使用这个别名。
    clang会根据这个命令行参数来定义编译器内置宏MAC_OS_X_VERSION_MIN_REQUIRED等,而SDK头文件中有对这些宏的检查,根据宏决定哪些符号采用weak linking。weak linking的符号在编译时不会报错,dylib加载时也不会报错,在用到对应的符号时如果不存在才会报错。
     
    通过环境变量设置deployment target
    clang的这个参数也可通过环境变量来设置。命令行参数优先于环境变量。
    MACOSX_DEPLOYMENT_TARGET
    IPHONEOS_DEPLOYMENT_TARGET
    TVOS_DEPLOYMENT_TARGET
    WATCHOS_DEPLOYMENT_TARGET
    DRIVERKIT_DEPLOYMENT_TARGET
     
    我们的工程以及我们的工程所直接/间接依赖的所有静态库/动态库,都需要在编译时指定相同的deployment target。
    省事的办法是通过环境变量来统一设置,在开始整个打包之前设置一下
    其次是命令行开关。不同工程类型的命令行开关设置方法有差异。以下是命令行开关的设置。
     
    通过vcpkg install编译的库
    需要更改vcpkg/triplets/x64-osx.cmake文件的内容,增加下面三行(理论上只要第一行即可,但vcpkg目前貌似有bug,导致VCPKG_OSX_DEPLOYMENT_TARGET只对CMake工程生效,对其他类型的工程不生效。所以需要第二行、第三行):
    set(VCPKG_OSX_DEPLOYMENT_TARGET "10.15")
    set(VCPKG_C_FLAGS -mmacosx-version-min=10.15)
    set(VCPKG_CXX_FLAGS -mmacosx-version-min=10.15)
    也可以复制这个文件到某个目录下,在复制出来的文件中增加上面这三行,然后给vcpkg install传递--overlay-triplets参数以使用这个修改过的triplet文件。这样通过vcpkg install安装的所有库的deployment target都是10.15。
     
    autoconf类型的工程
    比如libiconv库是手动执行autoconf编译的,需要在configure时增加参数:
    ./configure CFLAGS=-mmacos-version-min=10.15 CPPFLAGS=-mmacos-version-min=10.15
     
    CMake工程
    在CMakeLists.txt里的project()语句之前增加一句:
    set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15")
    或者
    set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "" FORCE)
     
    Xcode工程
    在界面的工程属性中可以设置deployment target。
     
    Makefile工程
    在makefile里自行给clang传递参数-mmacos-version-min=10.15即可。
  • 相关阅读:
    android 12 framework开发第53节-Activity的reLaunch及onConfigurationChanged android源码分析
    H5\CSS\JS 盒子拖动mousedown、mousemove、mouseup、pageX、pageY、offsetLeft、offsetTop
    Jetpack Compose 重写TopAppBar 实现标题多行折叠
    2022 年你需要知道的增强现实统计数据
    今年的 618 不行了?
    照片水印怎么去除?这些方法一看就会
    记录一次makefile + dockerfile + dockerfile-compose + shell 部署项目
    [spring]spring注解开发
    【JavaScript高级】05-JavaScript中with、eval语句及严格模式的使用
    matlab学习2022.7.4
  • 原文地址:https://www.cnblogs.com/z16166/p/16861268.html