調研這個的原因,是因為有個同事在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,
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頭檔案<AvailabilityMacros.h>、<Availability.h>中有對這些宏的檢查,根據宏決定哪些符號采用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即可,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/527964.html
標籤:其他
上一篇:onps堆疊移植說明(2)——編譯器及os適配層移植
下一篇:表驅動法在STM32中的應用
