Bitriseのmachine_typeをIntelからM1に変えたらsharp関連のエラーが出た時の対策

2023/06/09に公開

はじめに

下記宣告によって、Intelマシンが非推奨になったことで、M1に変更しようとしてる方が多いんじゃないかと思います🐈
https://discuss.bitrise.io/t/intel-machine-deprecation-notice/22668

ReactNativeの場合、ビルド時にsharp関連で、

error /Users/vagrant/git/node_modules/sharp: Command failed.
Exit code: 1
Command: (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)

①vipsがないとかいうエラーとか

../src/common.cc:24:10: fatal error: 'vips/vips8' file not found

②rUは不正なモードとかいうエラーとか

File "/Users/vagrant/git/node_modules/@npmcli/run-script/node_modules/node-gyp/gyp/pylib/gyp/input.py", line 239, in LoadOneBuildFile
    build_file_contents = open(build_file_path, "rU").read()
ValueError: invalid mode: 'rU' while trying to load binding.gyp

出た時の対策です!😠

原因

① vipsとかいうのがない件

まずsharpってなんやねん

大きい画像をいい感じに最適に変換してくれたりするやつらしいです。
https://www.npmjs.com/package/sharp
その中でlibvipsなるものを使っているらしい。

libvipsってなんやねん

まぁなんか、sharpが使ってる画像処理のライブラリらしい。
https://github.com/libvips/libvips

ついでにnode-gypってなんやねん

Node.jsでC++的なネイティブの拡張モジュールのバイナリをビルドするために使うやつらしい。

結論

①については、これでビルドしようとしてて、
libvipsがなんか無い的なアレでエラーになってるくさい😱

../src/common.cc:24:10: fatal error: 'vips/vips8' file not found

② rUとかいうモードがない件

File "/Users/vagrant/git/node_modules/@npmcli/run-script/node_modules/node-gyp/gyp/pylib/gyp/input.py", line 239, in LoadOneBuildFile
    build_file_contents = open(build_file_path, "rU").read()
ValueError: invalid mode: 'rU' while trying to load binding.gyp

なんかinvalid mode: 'rU'とか言われとる。
ファイル開く時、rUなんてモードはないらしい。

rUとは

https://utokyo-ipp.github.io/4/4-1.html
pythonあんまり知らんけど、ファイルをopenするとき、第二引数でmodeを渡せるらしい。
で、rは読み込み専用らしい。
Uは指定しとくと、ファイルがOSごとに改行コード違うから開いて処理したらなんか変な感じになるかもしれんけど、全部ちゃんと改行とみなしてくれるらしい。下記がどれでも。

結論

けどUはpython3.11以降で無くなったらしいことが原因😱
https://github.com/nodejs/node-gyp/issues/2219

自分のBitrise環境だとxcode14.2を使ってるけど、pythonは3.11が使われてる香り😢
で、エラーが出ていた。
https://github.com/bitrise-io/bitrise.io/blob/master/system_reports/MACOS/M1/osx-xcode-14.2.x-ventura.log

対策

birise.ymlに下記の様なカスタムスクリプトを作って、yarn installの前とか任意の場所に入れる。
やってることは、

  • pythonのバージョンを3.10.11にする。
  • vipsをインストールする。
    steps:
    - script@1:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x
            # write your script here
            # M1だとyarn install中にsharpでこける。
            # python3.11だとnode-gypがうまく動かないので、3.10に下げる。
            # https://github.com/nodejs/node-gyp/issues/2219
            pyenv install 3.10.11
            pyenv global 3.10.11
            python --version
        title: Set python version
    - script@1:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x
            # write your script here
            # M1だとsharpのビルドに失敗するため、vipsをインストールし直す
            brew reinstall vips
        title: Reinstall vips (for sharp on M1)

おわりに

もしandroidはmachine_typeをlinuxの何かにしてる場合などは、iOSのワークフローのみに入れる様にしたらいいと思います!

ではではー

Discussion