posted in Mac开发环境 

TL;DR

I repeatedly failed building a React Native 0.81 + RNFirebase Messaging iOS app on an Apple Silicon (M1/arm64) machine due to a combination of:

  • C/C++ header include-order pitfalls (RCT-Folly, Yoga, glog) amplified by custom header tweaks
  • CocoaPods quirks (bundled version vs system pod, encoding)
  • Firebase module map exposure (missing modular headers)

The final green build came from reverting to standard RN 0.81 Pod settings, keeping architecture defaults, and enabling modular headers for GoogleUtilities, FirebaseCoreInternal, and FirebaseCore — plus using the system pod to avoid a known Bundler/CocoaPods issue.


Environment

  • Machine: Apple Silicon (M1, arm64)
  • macOS: 15.6.x (Darwin 24.6.0)
  • Xcode: 16.1 (Build 17A400), iPhoneSimulator SDK 26.0
  • React Native: 0.81.x (Hermes enabled)
  • CocoaPods:
    • Bundled pod had an intermittent “pathname contains null byte” bug
    • System pod worked reliably
  • iOS Deployment Target: 15.1
  • Firebase: RNFirebase (App + Messaging)

Symptoms Observed

  1. Yoga headers not found, e.g. 'yoga/Yoga.h' file not found.
  2. RCT-Folly errors referencing <cstdio>/<cstring>/<cmath> with C headers taking precedence over libc++ wrappers (leading to FILE/pthread issues).
  3. glog mutex-related build breaks (mutex.h/pthread macros).
  4. CocoaPods “pathname contains null byte” during pod install with the bundled Ruby/CocoaPods.
  5. Firebase compile errors: Module 'FirebaseCore' not found in FirebaseInstallations sources.
  6. Intermittent Xcode/Ruby locale hiccups (resolved by ensuring UTF-8 env and re-running).

Root Causes

  • Over-customized header search paths for Pods (global HEADER_SEARCH_PATHS, SYSTEM_HEADER_SEARCH_PATHS, OTHER_CPLUSPLUSFLAGS, -isystem) changed include order, making C headers shadow libc++ and breaking RCT-Folly.
  • Attempting to “fix” headers globally (Pods + App target) unintentionally polluted multiple targets (glog, Yoga, Folly, React-*), causing cascading failures.
  • Using frameworks / modular header toggles globally introduced module map mismatches for Swift pods and RNFirebase transitive deps.
  • Bundled CocoaPods path/encoding edge-case (“pathname contains null byte”) blocked deterministic installs.
  • FirebaseCore module was not exposed as a modular header in our setup, causing Module 'FirebaseCore' not found.

What Actually Fixed It

  • Reset Podfile to the standard RN 0.81 shape; don’t globally alter header search paths or C++ flags.
  • Keep Legacy Architecture (disable New Architecture explicitly) and target iOS 15.1 to satisfy React Native codegen.
  • Avoid forcing use_frameworks!; stick to default static libraries.
  • Make only the necessary Firebase pods modular:
    • GoogleUtilities, FirebaseCoreInternal, and critically FirebaseCore.
  • Use system pod install (not Bundler) to avoid the “pathname contains null byte” error.
  • Build on an arm64 simulator (M1 host), letting headermap/modulemaps drive includes.
  • Do not add Yoga paths manually; rely on Yoga’s own modulemap and RN defaults.
  • Only if needed: for glog, ensure pthread defines via target-specific settings (but avoid global hacks).

Result: Build succeeded. App runs, and FCM token logs as expected.


Minimal Podfile (Working Shape)

# Resolve react_native_pods.rb with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
  'require.resolve(
    "react-native/scripts/react_native_pods.rb",
    {paths: [process.argv[1]]},
  )', __dir__]).strip

platform :ios, '15.1'
ENV['RCT_NEW_ARCH_ENABLED'] = '0'
prepare_react_native_project!

target 'EchoReadApp' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  # Ensure Swift pods expose module maps for Firebase
  pod 'GoogleUtilities', :modular_headers => true
  pod 'FirebaseCoreInternal', :modular_headers => true
  pod 'FirebaseCore', :modular_headers => true

  post_install do |installer|
    react_native_post_install(
      installer,
      config[:reactNativePath],
      :mac_catalyst_enabled => false
    )
    # No global header/cxx overrides here. Keep RN defaults.
  end
end

Key point: No global use_frameworks!, no global HEADER_SEARCH_PATHS/SYSTEM_HEADER_SEARCH_PATHS hacks, no project-wide -isystem injections.


Verified Working Build Path

  1. Clean CocoaPods integration
    cd ios
    pod deintegrate
    rm -rf build Pods Podfile.lock
    
  2. Install with system CocoaPods
    pod install
    
  3. Xcode clean + build (arm64 simulator)
    xcodebuild \
      -workspace EchoReadApp.xcworkspace \
      -scheme EchoReadApp \
      -sdk iphonesimulator \
      -configuration Debug \
      -destination 'platform=iOS Simulator,name=iPhone 17 Pro' \
      ONLY_ACTIVE_ARCH=YES \
      build
    
  4. Run the app (will print FCM token on first launch after permission)
    # ensure Metro is running
    npm start   # or: npx react-native start
    
    # then run on simulator
    npx react-native run-ios --simulator "iPhone 17 Pro"
    

Guidance for Future Changes

  • Prefer target-scoped tweaks over global Podfile-wide settings.
  • Let RN’s react_native_post_install do the heavy lifting; avoid overriding header maps.
  • For Firebase on RN iOS, keep GoogleUtilities, FirebaseCoreInternal, and FirebaseCore as modular headers when using static libs.
  • On Apple Silicon, prefer arm64 simulators and avoid x86_64-specific workarounds.
  • If pod install misbehaves under Bundler, try system pod as a fallback.
  • Treat any “fix” that alters global include order with suspicion; verify by reverting to defaults first.
posted in Mac开发环境 

I realized my git was not working when I executed `git status. It was all of a sudden to me because I did nothing, and I was in the middle of an important job. I have to complain about this to Apple.

I got this popup message "The "git" command requires the command line developer tools...". And when I successfully installed the Command Line Developer Tools again, it won't resolve this problem. The popup message will pop up again and again. I tried to download the "Command Line Developer Tools" from Apple's website and install it manually with no luck.

After searching online, I noticed that other people ran into this issue in the past too. That means this case happens not only on this version (Monterey) but also on previous versions.

Finally, I found this work for me.

sudo xcode-select -switch /Library/Developer/CommandLineTools
posted in Mac开发环境 

Motivation

For developers who are accustomed to Linux-like OS systems, Windows 10 is not a productive working environment. This toolset will make their eyes shine. Because it is providing an equivalent experience to working in Mac OS with iTerms2+Oh-my-zsh equipped.

Final Result Screenshot

Xnip2022-05-09_14-52-38

Explanation:

  • cdcode and gst are my aliases for entering the EMS project folder and executing git status
  • ipconfig is a Windows built-in command-line tool used for showing information of network interfaces. Whereas grep is a Linux built-in command-line tool used for printing lines that match patterns which could not be used in Windows before, no matter how desperately a Linux-like OS developer wanted to use it. However, with WSL installed, it has become a reality to execute Linux commands directly in Windows now. dig is another similar example of executing Linux commands in Windows.

Features at a glance

  • define command aliases
  • use Linux built-in command-line tools directly
  • mixed use Windows PowerShell and Linux command line directives
  • selection as a copy
  • git status support
  • tabs
  • split panes
    ...

Installation

1. Install PowerShell

PowerShell is shipped with most Windows 10 distributions. If you already have it, don't bother to install it again, unless you want to use PowerShell 7.x which is not installed by default.

2. Install WSL

WSL is short for "Windows subsystems for Linux". It will enable you to use Linux tools in Windows. To install it is quite easy, just execute wsl --install in PowerShell. Go to here for more details.

3. Install Windows Terminal

Microsoft’s new Windows Terminal is finally stable. Windows finally has a more modern terminal environment including features like tabs, split panes, multiple session types, and settings that let you configure everything from keyboard shortcuts to animated GIF backgrounds. This is an alternative tool to iTerm2 in Mac. It is a console enhancement tool, so it must run based on one of your existing command-line shell instances, such as PowerShell.
You can get it from Microsoft Store
Please google its configuration details. It's up to you how deeply custom configuration you like to do.

4. Install Oh-My-Posh

With the previous 3 steps, you are now having a modern terminal in Windows. Now it's time that we customize the command line prompt to make the terminal working environment more powerful. Oh-My-Posh is a custom prompt engine for any shell that has the ability to adjust the prompt string with a function or variable.
Get Oh-My-Posh and its documentation from its official website
Now, you can use the full-colour set of your terminal, adjust existing themes or create your own, and keep track of git status automatically.
To switch between the pre-defined themes, execute the following command and replace theme_name with your favourite theme.

oh-my-posh init pwsh --config C:\Users\wharvey\AppData\Local\Programs\oh-my-posh\themes\{theme_name}.omp.json | Invoke-Expression

Conclusion

With the power of WSL, we can now use Linux tools in Windows directly.
Windows Terminal is a modern terminal tool enabling developers to use tabs, multiple panes, background images and much other advanced functionality. Windows Terminal is based on command-line shell instances, such as PowerShell.
Oh-My-Posh is an extension to the command-line shell. It enables developers to make good use of the command line prompt.
Enjoy this toolset!

posted in Mac开发环境 

光标移动

  • 下一个当前单词:*
  • 上一个当前单词:#
  • 下一个单词第一个字符:w
  • 当前单词最后一个字符:e
  • 下一个以空白字符为分隔的单词第一个字符:W
  • 当前以空白字符为分隔的单词最后一个字符:E
  • 前一个单词第一个字符:b
  • 前一个以空白字符为分隔的单词第一个字符:B
  • 下一个特定字符之前:t+字符 till
  • 上一个特定字符之后:T+字符
  • 下一个特定字符之上:f+字符 find
  • 上一个特定字符之上:F+字符
  • 当前行最后一个字符上:$
  • 当前行最后一个非空字符上:g_
  • 当前行第一个字符上:0
  • 当前行第一个非空字符上:^
  • 第一行:gg 或 :1
  • 最后一行:G
  • 第N行: :N
  • 迅速移动到下一句开头:)
  • 迅速移动到上一句开头:(
  • 迅速移动到下一段开头:}
  • 迅速移动到上一段开头:{

滚动屏幕

  • 向下翻页:<C+f> forward
  • 向上翻页:<C+b> backward
  • 向下翻半页:<C+d> down
  • 向上翻半页:<C+u> up
  • 光标不动,向下逐行滚动:<C+e> elder
  • 光标不动,向上逐行滚动:<C+y> younger
  • 光标不动,使光标所在行翻到屏幕最上方:zt title
  • 光标不动,使光标所在行翻到屏幕最下方:zb bottom
  • 光标不动,使光标所在行翻到屏幕中间:zz
  • 使光标移动到屏幕最上方:H high
  • 使光标移动到屏幕最下方:L low
  • 使光标移动到屏幕中间:M middle

文本修改

  • d 加动作来进行删除(dd 删除整行);D 则相当于 d$,删除到行尾。
  • c 加动作来进行修改(cc 修改整行);C 则相当于 c$,删除到行尾然后进入插入模式。
  • s 相当于 cl,删除一个字符然后进入插入模式;S 相当于 cc,替换整行的内容。
  • i 在当前字符前面进入插入模式;I 则相当于 ^i,把光标移到行首非空白字符上然后进入插入模式。
  • a 在当前字符后面进入插入模式;A 相当于 $a,把光标移到行尾然后进入插入模式。
  • o 在当前行下方插入一个新行,然后在这行进入插入模式;O 在当前行上方插入一个新行,然后在这行进入插入模式。
  • r 替换光标下的字符;R 则进入替换模式,每次按键(直到 )替换一个字符。
  • u 撤销最近的一个修改动作;U 撤销当前行上的所有修改。
  • gU gu 使用v选中字符后,输入gU或gu可使选中文本变成大写或小写

文本选择

  • i: 如:di), 删除()内所有内容,不包括()
  • a: 如:ca", 修改""内包括""在内的所有内容
  • 用v选中后
    • < >, 左右缩进
    • = 自动缩进
    • J 内联成一行
  • [C-v], 选中多行文本
    • 用A或I插入文本,输入ESC,会在选中的多行文本重复执行相同插入文本操作

重复执行

  • ; 重复最近的字符查找(f、t 等)操作
  • , 重复最近的字符查找操作,反方向
  • n 重复最近的字符串查找操作(/ 和 ?)
  • N 重复最近的字符串查找操作(/ 和 ?),反方向
  • . 重复执行最近的修改操作

多文件操作

  • :args 列出打开文件列表
  • :n 打开下一个文件
  • :N 打开上一个文件
  • :ls 列出缓冲区列表
  • :bnext 切换到下一个缓冲区
  • :bprev 切换到前一个缓冲区
  • :b 序号 切换到对应序号的缓冲区
  • [C-^] 在最近编辑的文件之间切换Aug 16, 2020S

多窗口操作

  • :sp 或 [C+w]s 水平拆分
  • :vs 或 [C+w]v 垂直拆分
  • [C+w]w 窗口切换
  • [C+w]c 关闭窗口,最后一个窗口无效
  • [C+w]q 退出窗口,最后一个窗口退出整个vim
  • [C+w]= 平均调整每个窗口大小
  • :tabnew 新建标签页
  • :gt, :gT 切换标签页
posted in Mac开发环境 

ls的替代工具

# brew info exa
# exa -l --tree -L 1

用列表加树状展示一级目录下的目录和文件

cat的替代工具

# brew info bat
# bat README.md

比cat增加高亮和对git状态的支持

find的替代工具

# brew info fd
# fd README.md

语法比find简单,默认忽略.gitignore里的文件和隐藏文件

grep的替代工具

# brew info rg
# rg xxx

显示漂亮,默认忽略.gitignore文件和隐藏文件,默认递归所有子文件夹,可以指定文件类型

cd的替代工具

# brew info z
# z de [Tab]

自动基于历史访问过的以de开头的目录进行补全

# brew info fzf
# cd $(find * -type d | fzf)

通过上下键选择需要访问的目录,回车进入。

fzf会把标准输出变成交互式下拉列表共用户选择。

文件管理的替代工具

# brew info nnn

看日志tail的替代工具

# brew info lnav

支持各种日志的高亮显示,支持正则匹配

man的替代工具

# brew info

posted in Mac开发环境 

苹果发布了MacOS Sierra 10.12版本之后,原来需要用于安装从网上下载的软件的功能不见了,即系统中“任何来源”选项。可以使用如下方法找回“任何来源”的选项。

在终端中输入

sudo spctl --master-disable