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 的版本才能支持. 而我的 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 文件. 具体步骤如下:
把指定版本 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
Osx10.14升级watchman踩坑记的更多相关文章
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- EOS踩坑记
[EOS踩坑记] 1.每个account只能更新自己的contract,即使两个account的秘钥相同,也不允许. 如下,使用alice的权限来更新james的contract.会返回 Missin ...
- 十年老苹果(A1286)强升Catalina及Win10踩坑记(续)
背景 自上次发布十年老苹果(A1286)强升Catalina及Win10踩坑记以来,因为后半部分-----系统安装上的细节描述过于简略,一些朋友在安装过程中总是又遇到坑,由此特意详述这一过程,让园友少 ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
- vue踩坑记
vue踩坑记 易错点 语法好难啊qwq 不要把'data'写成'date' 在v-html/v-bind中使用vue变量时不需要加变量名 在非vue事件中使用vue中变量时需要加变量名 正确 < ...
随机推荐
- form enctype="multipart/form-data" ajax 文件上传
<form method="post" enctype="multipart/form-data" id="resource"> ...
- 第二章:seaborn调色板
1.系统默认调色板 1 import seaborn as sns 2 import matplotlib.pyplot as plt 3 4 # 设置画布的大小 5 sns.set(context= ...
- Scanner例题讲解
Scanner例题讲解 题:输入多个平均数,求其总和与平均数;每输入一个数用回车确认,通过输入非数字来结束输入并输出执行结果 public class Demo05 { //输入多个平均数, ...
- 搭建漏洞环境及实战——在Windows系统中安装WAMP
安装成功之后,打开显示 链接:https://pan.baidu.com/s/1NpU7fUYOO_CSM8dNXKdnCw 提取码:mxvw
- 【转载】SQL SERVER 中单字节和双字节互转自定义函数(全角半角转换)
一.首先创建一个自定义函数,代码如下: alter function f_convert( @str nvarchar(4000), --要转换的字符串 @flag bit --转换标志,0转换成半角 ...
- Azure DevOps 的架构窥探
工作的缘故,接触 TFS (Team Foundation Server)挺多的,现在改名为 Azure DevOps,分为 可私有化部署版本 Azure DevOps Server,简称ADS,以及 ...
- [数据与分析可视化] D3入门教程2-在d3中构建形状
d3.js入门教程2-在 d3.js中构建形状 文章目录 d3.js入门教程2-在 d3.js中构建形状 形状的添加 圆形的添加 矩形的添加 线段的添加 文本的添加 折线的添加 区域的添加 圆弧的添加 ...
- [OpenCV实战]1 基于深度学习识别人脸性别和年龄
目录 1基于CNN的性别分类建模原理 1.1 人脸识别 1.2 性别预测 1.3 年龄预测 1.4 结果 2 代码 参考 本教程中,我们将讨论应用于面部的深层学习的有趣应用.我们将估计年龄,并从单个图 ...
- Spark详解(07) - SparkStreaming
Spark详解(07) - SparkStreaming SparkStreaming概述 Spark Streaming用于流式数据的处理. Spark Streaming支持的数据输入源很多,例如 ...
- python31 网络并发编程方法
同步与异步 用来表达任务的提交方式 同步 提交完任务之后原地等待任务的返回结果 期间不做任何事 异步 提交完任务之后不原地等待任务的返回结果 直接去做其他事 有结果自动通知 阻塞与非阻塞 用来表达任务 ...