LoginSignup
10
5

More than 1 year has passed since last update.

M1 Mac で MeCab の configure に失敗する (cannot guess build type; you must specify one)

Last updated at Posted at 2021-05-30

事象

M1 Mac 上の Docker で MeCab 含む DockerFile のビルドを行なってきたところ configure: error: cannot guess build type; you must specify one と怒られてしまった。

configure: error: cannot guess build type; you must specify one

解決策

configure さんが aarch64 なにそれ?おいしいの?っていってるから、 arm さんだよ〜。って教えてあげる

## --build=arm を追加する ("--build=arm" だけではその後の mecab-python3 の python setup.py install でコケた(後述))
# ./configure --enable-utf8-only --with-charset=utf8 --build=arm

# アーキテクチャを指定する
./configure --enable-utf8-only --with-charset=utf8 --build=arm-unknown-linux-gnu --host=arm-unknown-linux-gnu --target=arm-unknown-linux-gnu

AppleSilicon や ARM 版 Windows が普及してくると開発メンバで複数のアーキテクチャが混在する状況も増えてくると思う。

少なくともベストプラクティスではないと思っているが、 aarch64 とそれ以外 ( amd64 ) に対応した、 Dockerfile の一例を載せておく。

Dockerfile
FROM python:3.9.5-alpine3.13

ARG _ARM_ARCH="arm-unknown-linux-gnu"

RUN apk add --update bash git curl swig gfortran openssl perl
RUN apk add gcc g++ build-base linux-headers

RUN git clone --depth 1 https://github.com/taku910/mecab.git \
    && cd ./mecab/mecab \
    && if [ `uname -m` =  "aarch64" ]; then \
        ./configure --enable-utf8-only --with-charset=utf8 --build=${_ARM_ARCH} --host=${_ARM_ARCH} --target=${_ARM_ARCH}; \
    else \
        ./configure --enable-utf8-only --with-charset=utf8; \
    fi \
    && make \
    && make install
...

長くなるので、全体は GitHub で公開します。

setup.py がコケる原因について

--build=arm で MeCab のビルドが通って安心していたが、 pip install mecab-python3 でビルドエラーが発生した。

stderr
g++ -pthread -shared build/temp.linux-aarch64-3.9/src/MeCab/MeCab_wrap.o -L/usr/local/lib -lmecab -lstdc++ -o build/lib.linux-aarch64-3.9/MeCab/_MeCab.cpython-39-aarch64-linux-gnu.so
/usr/bin/ld: /usr/local/lib/libmecab.a(char_property.o): relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `_ZSt4cerr@@GLIBCXX_3.4' which may bind externally can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: /usr/local/lib/libmecab.a(char_property.o)(.text+0x3b0): unresolvable R_AARCH64_ADR_PREL_PG_HI21 relocation against symbol `_ZSt4cerr@@GLIBCXX_3.4'
/usr/bin/ld: final link failed: Bad value

mecab-python3 側のコードを確認したが、原因となりそうな箇所は見当たらなかったので、 mecab 本体のビルドオプションにアタリをつけて調査。

結果、動かせたわけだが、正直、何が作用して動いたのかはわからない(爆) :bomb::boom:

恐らく、 "arm" と指定するだけでは古い ARM 用のファイルが吐かれて、それをリンクしようとしてエラーになったものと推測される。

詳しく書くと、動的リンクを行う際には、メモリアドレスのオフセットを行う。 (「ぼた餅は上から5番目の棚にあるよ」と指定するところを、「ぼた餅は上から3番目の棚の2つ下の棚にあるよ」と相対的に指定するイメージ。棚ぼたを期待して間違った棚を手をかけると後ろに死神が立っていることになるのだが、この話は別の記事でします。)
これを実現する仕組みを GOT (Global Offset Table) と呼ぶ。

x86/x64 では GOT のサイズ制限が無制限らしい(らしい)が、 単に "arm" と指定された場合、 GOT の制限に引っかかるタイプの ELF が吐き出されるんだと思う(適当)

recompile with -fPIC

エラー内で -fPIC を指定しろと言っているように --build --host --target のいずれかに arm-unknown-linux-gnu が指定されたことで、 新しめの ARM に対応した ELF が吐かれたか -fPIC オプションが適用されたかのいずれかの理由でうまく動いたんだと思う。

さいごに

arm64amd64 見分けづらいよね。

10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5