18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Apple Silicon版 Mac(M1)で開発するときのメモ

Last updated at Posted at 2021-03-28

どこにでもありそうな内容だが、Apple Silicon版 Mac(M1)で開発する時によく使うコマンドをまとめた。

1. ビルド編

CMakeのビルド設定

CMAKE_OSX_ARCHITECTURESを設定しないとデフォルトでは M1 macのarm64環境でビルドしたらApple Silicon版(arm64)ができる。Intel MacならIntel Mac(Rosetta2)版(x86_64)ができる。CMake 3.19.4以降でUniversal Binaryに対応している。

Build_Universal_Binary
cmake -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

CMake v3.19.2からはCMAKE_APPLE_SILICON_PROCESSORでビルドする環境を指定することができる。

Build_AppleSiliconApp
cmake -DCMAKE_APPLE_SILICON_PROCESSOR="arm64" -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

cmake --version で3.19.4より古かったら更新したほうがよい( brew upgrade cmake )。

CMakeLists.txt内での処理の切り替え

CMAKE_SYSTEM_PROCESSORはコンパイル対象のプロセッサー、CMAKE_HOST_SYSTEM_PROCESSORは実行しているシステムのプロセッサーを返す。

if(APPLE)
    message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
    message(STATUS "CMAKE_HOST_SYSTEM_PROCESSOR: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
    message(STATUS "CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}")
    message(STATUS "CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
    foreach(ARCH IN LISTS CMAKE_OSX_ARCHITECTURES)
        if(${ARCH} MATCHES "arm64")
            # arm64設定
            message(STATUS "CMAKE_OSX_ARCHITECTURES: arm64")
        elseif(${ARCH} MATCHES "x86_64")
            # x86_64設定
            message(STATUS "CMAKE_OSX_ARCHITECTURES: x86_64")
        else()
             # 未知のプロセッサ or 未設定
            message(STATUS "CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}")
        endif()
    endforeach()
endif()

node-gypのx86_64版ビルド設定

そのままM1 macでビルドするとarm64版ができる。x86_64版は--arch=x86_64を指定する。
この方法だとUniversal binaryは作れなそう(2021/10/14現在)。

"node-gyp clean configure build --verbose --arch=x86_64"

node-gypのUniversal binaryビルド

まだ試せていないのでメモのみ(2021/10/14現在)。node-gyp-buildここで変更が入っているのでver.4.3.0 (Sep 12, 2021)以降を使うとできそう。オプションで--arch=arm64+x86_64を指定してビルドする?

2. コマンド編

M1 Macを使っている時によく使うコマンド。

uname -m: 使っているTerminalがx86_64かarm64かを確認する。

% uname -m
arm64

arch -x86_64: arm64 terminalでx86_64コマンドを呼び出す。

"uname"コマンドをx86_64で呼び出した例。

% arch -x86_64 uname -m
x86_64

x86_64版Terminalへの切り替え

使っているターミナルをx86_64版に切り替えてからビルドする時などに使う。

% arch -x86_64 /bin/zsh

lipo -archs: 実行ファイルの対応アーキテクチャを確認する。

% lipo -archs /System/Applications/Notes.app/Contents/MacOS/Notes 
x86_64 arm64e

コマンドのパスを探してアーキテクチャを確認するにはwhich ***で囲んで戻りを使う

% lipo -archs `which node`
arm64

otool -L: リンクしているライブラリをリスト表示

M1と関係ないけど。WindowsのDependenciesみたいなもの。リンクしているライブラリを調べるのに使う。

% otool -L /System/Applications/Notes.app/Contents/MacOS/Notes
/System/Applications/Notes.app/Contents/MacOS/Notes:
	/System/Library/Frameworks/PencilKit.framework/Versions/A/PencilKit (compatibility version 1.0.0, current version 1.0.0)
	/System/Library/PrivateFrameworks/NotesShared.framework/Versions/A/NotesShared (compatibility version 1.0.0, current version 1872.0.0)
	/System/Library/PrivateFrameworks/NotesUI.framework/Versions/A/NotesUI (compatibility version 1.0.0, current version 1872.0.0)
	...

install_name_tool : リンクしているdylibを変更

otool -L と一緒によく使うコマンドでinstall_name_toolがある。リンクしているdylibのパスを @rpath に後から変更したい時やdylibのパスを修正するときなどに利用する。"a.out"という実行ファイルのlibc++.1.dylibのリンクパスを /usr/lib/libc++.1.dylib に変更する例。

% install_name_tool -change /usr/local/opt/llvm/lib/libc++.1.dylib /usr/lib/libc++.1.dylib a.out

@rpathを追加した場合、% otool -l b.out してcmd LC_RPATHという出力が出て来なかったら @rpathが設定されていないのでadd_rpathする。

% install_name_tool -add_rpath "@executable_path" b.out

おまけ(/usr/libにシステムのdylibがない件)

Apple Siliconと共に登場したBig Surから“dynamic linker cache”という仕組みが導入され、/usr/libにシステムのdylibが置かれなくなった。

New in macOS Big Sur 11.0.1, the system ships with a built-in dynamic linker cache of all system-provided libraries. As part of this change, copies of dynamic libraries are no longer present on the filesystem. Code that attempts to check for dynamic library presence by looking for a file at a path or enumerating a directory will fail. Instead, check for library presence by attempting to dlopen() the path, which will correctly check for the library in the cache. (62986286)

3. シェルスクリプト例

動作環境(x86_64/arm64)を見て処理を切り替える

Apple SiliconかIntel Macかを見分けるビルドスクリプトを作る時に利用したものから抜粋。

checkMacOS.sh
if uname -m | grep --quiet "arm64" 2>&1 > /dev/null ; then
    echo 'is Apple Silicon'
else
    echo 'is Intel/Rosetta2'
fi

M1 Macのターミナルから実行すると、

% zsh ./checkMacOS.sh 
is Apple Silicon

M1 MacのRosette2上のVSCodeターミナルから実行すると、

% zsh ./checkMacOS.sh
is Intel/Rosetta2

となる。

18
7
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
18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?