博客 / 詳情

返回

Osx10.14升級watchman踩坑記

背景

使用 watchman 檢測文件變化通知非常的好用, 但有些時候會出現 watchman 佔用內存和 CPU 特別瘋狂, 通過 watch-del 也無濟與事, 由於 watchman 的版本 2021.09.13 比較老, 於是就想着升級一下版本.

正常來説, 在 mac 下使用 brew upgrade 升級非常的簡單, 但是我的 OS 系統版本比較老, 一直使用的是 10.14 的 Mojave ( 之前也升級過 Bigsur, 後面因為休眠問題又退回了) . 眾所周知, 官方已經不維護這個系統版本了, 所以 brew 上安裝和更新軟件也特別麻煩, 不能使用 bottle 安裝已編譯好的二進制, 必須要自己編譯安裝, 不光編譯時間是個問題, 而且編譯失敗的概率也很高.

趁着週末的時間, 於是就準備通過 brew upgrade 升級 watchman, 但是杯具也是從這裏開始了.

升級 watchman

  • 首先更新 brew 的 formula 倉庫, 把相關軟件的版本和依賴數據庫更新.

    brew update
    
  • 更新 watchman

    brew upgrade watchman
    
    # output
    ==> Would upgrade 1 outdated package:
    watchman 2021.09.13.00 -> 2022.12.12.00
    ==> Would install xx dependencies for watchman:
    folly 2021.09.13.00 -> 2022.12.12.00 edencommon 2022.12.12.00 fizz 2021.09.13.00 -> 2022.12.12.00 wangle 2021.09.13.00 -> 2022.12.12.00 fbthrift 2021.09.13.00 -> 2022.12.12.00 fb303 2022.12.12.00
    
    ...
    

結果就是漫長的等待, 一堆一堆的依賴軟件編譯和安裝, 包含 rust 和 llvm 這些大型軟件, 結果整整編譯了半天才編譯完這些大型軟件, 到最後編譯 folly 時候居然失敗了.

"std::__1::__fs::filesystem::path::__filename() const", referenced from:
std::__1::__fs::filesystem::path::operator/=[abi:v15006](std::__1::__fs::filesystem::path const&) in AsyncBase.cpp.o
"std::__1::__fs::filesystem::path::__root_directory() const", referenced from:
std::__1::__fs::filesystem::path::operator/=[abi:v15006](std::__1::__fs::filesystem::path const&) in AsyncBase.cpp.o
"std::__1::__fs::filesystem::path::lexically_normal() const", referenced from:
folly::fs::lexically_normal_fn::operator()(std::__1::__fs::filesystem::path const&) const in Filesystem.cpp.o
"std::__1::__fs::filesystem::__read_symlink(std::__1::__fs::filesystem::path const&, std::__1::error_code*)", referenced from:
folly::AsyncBaseOp::fd2name(int) in AsyncBase.cpp.o

通過分析 debug 的編譯日誌, 編譯應該都是成功的, 但在最後鏈接的時候失敗了. 通過查詢相關的資料得知, filesystem 相關的函數是定義在 <filesystem.h> 頭文件中的, 這個頭文件在 Xocde 11.x 版本有定義, 但是系統的支持應該是在 10.15 的版本才能支持1. 而我的 Xocde 版本確實是 11.3.1, 所以在編譯時沒出錯, 但在鏈接的階段失敗了 .

# 查看當前的 xocde 版本
➜  xcodebuild -version

# output
Xcode 11.3.1
Build version 11C505

嘗試方案

基於其它版本的 folly 編譯

既然 2022.12.12.00 版本編譯安裝失敗, 那就嘗試指定其它的版本編譯, 可以通過 https://formulae.brew.sh/ 找到 folly 其它版本的 formula 文件. 具體步驟如下:

image.png

把指定版本 watchman.rb 下載後, 通過 brew 指定 rb 文件編譯.

brew install -s -v -d watchman.rb

但是不幸的是, 還是編譯錯誤. 換了多個版本折騰了半天, 還是會出現各種各樣的編譯錯誤, 沒法了, 這條路是行不通了.

還原版本也不容易

既然無法成功更新 watchman 版本, 那打算接着使用原始的版本吧, 但問題又是一堆一堆的, 不讓人安心了.

但當我執行 watchman 命令, 系統居然提示找不到這個命令了. 查看 /usr/local/bin/ 目錄, 確實沒有 watchman 的鏈接文件了, 應該是執行 brew upgrade 時, 會取消掉原來版本的鏈接.
那就通過 brew link 重新鏈接吧.

brew link watchman

重新鏈接後命令是回來了, 但是執行後系統會提示如下錯誤:

➜  Cellar watchman -h

# output
dyld: Library not loaded: /usr/local/opt/glog/lib/libglog.0.dylib
  Referenced from: /usr/local/bin/watchman
  Reason: image not found
[1]    11397 abort      watchman -h

應該是之前更新依賴時, 把依賴庫的版本升級了, 而原來版本的 watchman 無法找到老版本的依賴庫了. 但當時更新了那麼多的依賴庫, 誰也不知道哪些庫會不兼容, 看來只能走一步算一步, 人肉把出錯的依賴庫鏈接一個一個還原了.

# 查詢鏈接的版本
➜  ls -l /usr/local/opt/ | grep glog
lrwxr-xr-x 20 guoxiangxun 19 Dec 16:13 glog -> ../Cellar/glog/0.6.0

# 刪除連接版本
➜  cd /usr/local/opt
➜  rm glog

# 重新連接版本
➜ ln  -s ../Cellar/glog/0.5.0 glog

其它還包含依賴庫 llvm, fmt, icu4c, boost 等, 全部都要重新連接到原始版本. 如:

ln  -s ../Cellar/llvm/13.0.1_1 llvm
ln  -s ../Cellar/fmt/8.1.1_1 fmt
ln  -s ../Cellar/icu4c/70.1 icu4c
ln  -s ../Cellar/boost/1.78.0_1 boost

最終 watchman 版本終於還原成功, 能正常執行了. 但問題應該還沒有結束, 後面看其它軟件有哪些升級的依賴還需要還原吧, 因為 watchman 依賴庫太多了. 可以通過 brew deps 看看, 具體的就不列出來了.

➜ brew deps --tree --installed watchman

# output
watchman
├── boost
│   ├── icu4c
│   ├── xz
│   └── zstd
│       ├── lz4
│       └── xz
├── edencommon
│   ├── folly
│   │   ├── boost
│   │   │   ├── icu4c
│   │   │   ├── xz
│   │   │   └── zstd
│   │   │       ├── lz4
│   │   │       └── xz
│   │   ├── double-conversion
│   │   ├── fmt

... more and more
... more and more

總結

針對系統不維護的系統版本, 儘量還是不要通過 brew upgrade 升級吧, 花費的編譯時間長不説, 而且編譯問題也是一堆一堆的, 到最後還原版本也不容易, 最好的方式還是升級系統或者將就着使用吧.

實在要更新的話, 先要先看下要更新軟件所依賴的庫的數量再決定, 如果要更新的依賴庫太多的話, 風險可能更大. 可以 upgrade 時加上-n 參數測試下, 更新時把相關的日誌記錄下來, 究竟更新了哪些庫的哪些版本, 以便於搞不定時還原.

References


  1. https://stackoverflow.com/a/58668083/2538322 ↩
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.