- 投稿日:2022-03-22T23:02:50+09:00
ショートカットキー【VSCode】:ソースコードを整形
Mac:「Shift」+「Option(⌥)」+「F」 Windows:「Shift」+「Alt」+「F」 補足 ・上手くいかない場合は、半角英数入力になっていることを確認してみましょう。
- 投稿日:2022-03-22T21:52:06+09:00
Numpyのため趣味的にPython 3.10をmakeする(M1 Mac: arm64アークテクチャ)
はじめに M1 Mac (mac OS Monterey) を手に入れて、デフォルトで入るPython 3.8を使ってみたらNumpyが入らない。調べてみれば、下の記事にあるように、Python 3.9以上のバージョンならばpipからNumpyはインストールできるし、新しいバージョンのPython自体もcondaやHomebrewから簡単にインストールできるとの事1。 この時点で、素直に上記の方法に従えさえすれば問題 (Python3とNumpyのインストール) は解決できます。この記事ではあえてそれを傍に置き、condaもHomebrewも使わずにソースコードからPython 3.10をmakeして、M1 Macにをインストールする方法を記します。Python 3.9などバージョンが違っていてもインストール方法はほぼ変わりません。 Python 3.10のインストールは以下の手順で行います: OpenSSLとPythonソースコードのダウンロード OpenSSLのmake Pythonのmake Pythonとpipの実行 Pathの設定 また、Mac/README.rstの邦訳を付録として付けました(本編より長いです)。一通り読むと、MacOSにPythonをインストールする際に必要となる条件の理由が理解できます、 OpenSSLはなぜ必要? Pythonのインストールなのに、手順にOpenSSLが登場しています。なぜなら、OpenSSLはPython上でhttps通信等を行う為に必要となるからです。別にPythonでそんな処理なんてしないし...。と思って入れないと、次の最悪の事が起こります。 Pythonと一緒にインストールされるpipはhttpsプロトコルで通信を行う為、OpenSSL抜きでPythonをmakeした場合、通信が失敗してインターネット経由でモジュールを一つも追加できなくなります。 上の記事曰く、OpenSSLはOSにプリインストールされている物でも大丈夫らしいのですが、実はMacに標準でインストールされているOpenSSLの正体はLibreSSLなので、OpenSSLを使うならインストールが必要となります。HomebrewからOpenSSLもインストールできるそうなのだけど、今回は使わないのでこちらもmakeでインストールします。 OpenSSLとPythonソースコードのダウンロード 以下からソースコードをダウンロードします。この記事を執筆した2023年3月時点より新しいバージョン (場合によっては致命的なバグのアップデートバージョン) がリリースされている可能性があるので、配布元のサイトを確認する様にしてください。 Python 3.10 (https://www.python.org/downloads/source/) 最新安定版 (2023年3月): 3.10.3 (https://www.python.org/ftp/python/3.10.3/Python-3.10.3.tgz) OpenSSL (https://www.openssl.org/source/) 最新安定版 (2023年3月): 1.1.1n (https://www.openssl.org/source/openssl-1.1.1n.tar.gz) ダウンロードしたたtarballは、% tar zxvf XXX.tar.gz等で適当な所に解凍してください。 OpenSSLのmake この手順では、OpenSSLをシステム下の/libや/optディレクトリを汚したくないため、自分のhomeディレクトリに作った"local/"ディレクトリ下にインストールしています。趣味の問題なので、特にこだわりがなければ--prefixと--openssldirは省略して、デフォルトの場所にインストールでも良いと思います。 また、OpenSSLは"./configure"ではなく"./config"を実行することに注意してください。 $ cd openssl-1.1.1n $ ./config --prefix=/Users/hoge/local/opt/openssl --openssldir=/Users/hoge/local/ssl $ make $ make test $ make install OpenSSLのバージョンは1.1.1kだとarm64に対応していないのか、makeに失敗します。1.1.1m以上ならmakeできたので、最新版を使う場合には特に問題なくmakeできるはずです。 使用したconfigの引数 引数名 説明 デフォルト値 --prefix=DIR OpenSSLの設定ファイルおよび、デフォルトの証明書やKey Storeの保存先ディレクトリ /usr/local --openssldir=DIR インストールされるディレクトリ群に対する最上位のパス /usr/local/ssl Pythonのmake Pythonのmakeにおいてデフォルトで用いられるコンパイラはGCC (Gnu Compiler Collection) のgccとg++ですが、Apple製コンパイラを使用したいので、ここではClangを指定してコンパイルを行います。 PythonはUnix形式ではなく、フレームワーク形式でインストールを行います。フレームワーク形式の詳細は付録をご参照ください。理由を簡単に書けば、GUIを用いるコード (matplotlib等) を実行できる様にするためと、ディレクトリ管理の簡単化のためとなります。 OpenSSLをデフォルト以外の場所にインストールした場合は、"./configure"の引数"--with-openssl"に、OpenSSLのmake時に"--prefix"で指定してたディレクトリを指定します。同時に、"--with-openssl-rpath"を"auto"にします。"--with-openssl-rpath"が"no"でrpath2が指定されない場合、Python実行時に動的ライブラリがロードされる際に、システムが想定する一般的なディレクトリ (/usr/libや/usr/local/lib等) からしか目的のライブラリが探索されないため、この場合のように異なる場所にインストールしたライブラリが見つからずロードが失敗したり、場合によっては探索されたディレクトリ内に存在する異なるバージョンのライブラリがロードされて、おかしな挙動を引き起こす場合があります。 $ cd Python-3.10.3 $ ./configure --prefix=/Users/hoga/local \ --enable-framework=/Users/hoge/local/Library/Frameworks \ --enable-universalsdk --with-universal-archs=universal2 \ --with-openssl=/Users/hoge/local/opt/openssl --with-openssl-rpath=auto\ --with-ensurepip=install \ --enable-optimizations CC=clang CXX=clang $ make -j4 $ make -j4 test $ make install "./confiure"実行時に表示されるログ名の中で、以下のopenssl関係の構成が解決されていることを確認してください。 checking for openssl/ssl.h in /Users/kogata/local2/opt/openssl... yes checking for --with-builtin-hashlib-hashes... md5,sha1,sha256,sha512,sha3,blake2 解決されていない場合でも"./configure"は成功するので、気づかないままmakeした場合、インターネットからモジュールがダウンロードできないpipが出来上がり、makeのやり直しとなります。 make installに"-j"オプションを指定するとインストールに失敗します。 使用したconfigureの引数 引数名 説明 デフォルト値 --prefix=PREFIX アーキテクチャと独立したファイルを"PREFIX"にインストールする。このオプションが指定されない場合は、"/usr/local"にインストールされる。 - --enable-framework[=INSTALLDIR] 従来のUnix形式のインストールではなく、Python.frameworkを作成する。"INSTALLDIR"オプションで、Python.frameworkのインストール先を指定できる("INSTALLDIR"を指定しない場合は"/Library/Frameworks/"にインストールされる)。詳細はMac/README.rstを見よ。 no --enable-universalsdk[=SDKDIR] ユニバーサルバイナリでコンパイルされたプログラムを作成する。"SDKDIR"はビルド時にどのmac OS SDKを用いるかを指定する("SDKDIR"が指定されない場合は、現在動いているXcodeかCommand Line Toolsのdeveloperディレクトリにあるデフォルトmac OS SDKが使われる。そのため、現在のシステムで"SDKDIR"を指定する必要はまずない)。詳細はMac/README.rstを見よ。 no --with-universal-archs=ARCH どのアーキテクチャにおけるmacOS ユニバーサルバイナリが作られるかを指定する。このオプションは"--enable-universalsdk"が指定されている時のみ有効である。"ARCH"に指定できる値は次となる: "universal2", "intel-64", "intel-32", "intel", "32-bit", "64-bit", "3-way", or "all" - --with-openssl=DIR OpenSSLディレクトリのルート - --with-openssl-rpath=[DIR|auto|no] OpenSSLライブラリに対するランタイムライブラリのディレクトリ (rpath2) を指定する。指定できる値は次となり、 "no" (デフォルト): rpathを指定しない、"auto": --with-opensslで指定されたライブラリとpkg-configから、自動的にrpathを設定する、"DIR": 明示的にrpathを指定する。 no --with-ensurepip[=install|upgrade|no] 付属しているpipを用いて"install" か"upgrade"を行う。(defaultは"upgrade") - --enable-optimizations 高価かつ安定した最適化を行う(Profile-Guided Optimization等) no CC C compiler command gcc CXX C++ compiler command g++ 使用したmakeの引数 引数名 説明 デフォルト値 -j [jobの数] make時に同時に実行されるjobの数を指定する。jobの数を指定しない場合は数を制限しない。指定するジョブ数はこちらが詳しいが、どちらにせよ最大でも物理コア数程度にするのが良い。ジョブ数を指定しない場合はマシンに大きな負荷が掛かる場合があるので、jobの数は必ず指定する事。 - Pythonとpipの実行 インストールが成功しているかの確認に、ここまでの作業でインストールされたpipを使い、目的のNumpyをインストールしてみます。 $ /Users/hoge/local/bin/pip3.10 install numpy 以下の様に表示されれば成功です。PythonとOpenSSLの動的ライブラリとの連携も無事出来ています。 Collecting numpy Downloading numpy-1.22.3-cp310-cp310-macosx_11_0_arm64.whl (12.8 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.8/12.8 MB 55.4 MB/s eta 0:00:00 Installing collected packages: numpy Successfully installed numpy-1.22.3 Pythonを実行してみます。 $ /Users/hoge/local/bin/python3.10 インストールに問題なければ、インタプリタが起動されます。Numpyをインポートしたり、挙動を確認したらCtrl-Dかexit()で終了します。特にエラーや警告がでなければ、無事、M1 Mac (mac OS Monterey) 上にNumpyが動くPython環境を構築できています。 Pathの設定 ここまでで目的は達成されましたが、Python実行時に毎回/Users/~/Python3.10と打つのも面倒なので、Path環境変数を設定してコマンド名だけで実行できる様にします。自身で使用しているシェルの設定ファイル (OSデフォルトなら.zshrc) に以下を書き加えます。 Zshの場合(Bashも同じ) export PATH="/Users/hoge/local/bin:${PATH}" 設定ファイルをターミナルを再起動したり、sourceコマンドで反映させれば、以下の様にPythonが実行できる様になります。 $ python3.10 付録. Mac/README.rstの邦訳 原文はPython3.10.3ソースコード内に存在するmac/README.rstなので、本邦訳はPython Software Foundation (PSF) ライセンス下で公開されます3。この文書は、私がいちいち英語を読むのが面倒なため、私的利用を目的として訳した文書となります。内容については訳者の英語力が怪しいため、参考にする際は今一度原文をご確認ください(間違いがありましたらコメントください)。 Python on macOS README 著者: Jack Jansen (2004-07) Ronald Oussoren (2010-04) Ned Deily (2012-06) configureのmacOS用引数 --enable-framework[=DIR] この引数が指定された場合、コンパイルされるプログラムは、従来のUnixのインストール形式ではなく、Python.frameworkとして作成される。フレームワークのより詳細な情報についてはmacOSでフレームワークベースのPythonをビルドして使用するセクションを見よ。 オプションのディレクトリ引数を指定した場合、フレームワークはそのディレクトリ内にインストールされる。これにより、自身のホームディレクトリにpythonのフレームワークをインストールする事もできる: $ ./configure --enable-framework=/Users/ronald/Library/Frameworks $ make && make install 上の場合だと、フレームワーク自体が/Users/ronald/Library/Frameworksにインストールされ、Users/ronald/Applicationsにアプリケーションが、/Users/ronald/binにコマンドラインツールがインストールされる。 --with-framework-name=NAME Pythonフレームワークに対する名前を指定する(デフォルトはPython) 。このオプションは"--enable-framework"が指定された時のみ有効である。 --enable-universalsdk[=PATH] Pythonをユニバーサルバイナリのプログラムとして作成する。これは通常(訳注: Unix形式)およびフレームワーク形式の両方で使用できる。 この任意の引数は、コンパイルされるプログラムが動くために、どのmacOS SDKを用いるべきかを指定する。現在のシステムでは、大抵の場合PATHを指定す必要はなく、/だけで良い。その場合、現在動いているXcodeかCommand Line ToolsのdeveloperディレクトリにあるデフォルトmacOS SDKが使われる。より詳しい情報は、macOS xcrun man pageを見よ。現行バージョンのmacOSおよびXcodeは、システムヘッダーファイルをもはやそれらの慣習的な場所 (/usr/includeおよび/System/Library/Frameworks) に置いておらず、MacOSX SDKの内部に見つけられる。Appleが提供するビルドツールはこの事を意識せずに処理するので、現行バージョンのPythonもこれで処理する様になっている。そのため、もはやこの任意の引数は必要ではなく、 macOS 10.14以降、xcode-selectでシステムヘッダーを強制的にインストールすることもできない。 --with-universal-archs=VALUE どの種類のユニバーサルバイナルでPythonを作成するべきか指定する。このオプションは"--enable-universalsdk"が指定された場合のみ有効である。SDKがPPC (訳注: Power PC) に対応していれば、デフォルトでは32-bitとなり、そうでなければintelがデフォルトとなる。intelは32-bitと64-bit両方のユニバーサルバイナリを意味し、想定している物と違う可能性があることに注意する事:例えば、macOS 10.15 Catalina現在だと、32-bitでのバイナリの実行は、もはやオペレーティングシステムでサポートされていない。したがって、"--with-universal-archs"に対して以下の様に明示的に値を指定するか、どちらも使用しない事が最適となる。 --enable-universalsdk --with-universal-archs=intel-64 macOSでユニバーサルバイナリのPythonをビルドして使用する 1.ユニバーサルバイナリとは何か Pythonにおけるユニバーサルバイナリでコンパイルされたプログラムは、複数のCPUアーキテクチャに対応したオブジェクトコードを含む。ユニバーサルなmacOS実行可能ファイルやライブラリは、アーキテクチャ固有のコードを一つに纏めており、それにより、サポートする全てのアーキテクチャでネイティブな速さで実行できる。ユニバーサルバイナリは、当時存在するPower PC (PPC) マシンに、IntelベースのMacに対するサポートを追加するために、macOS 10.4で導入された。macOS 10.5において、64-bit Intelと64-bit PPCアーキテクチャに拡張された。この仕組みにより、使用されているmacOSのバージョンとビルドツールによって、様々なアーキテクチャの組み合わせでPythonをビルドする事を可能である。PPCのサポートはmacOS 10.7でなくなり、32-bit Intelのサポーターはmac OS 10.15でなくなった。そのため、現行のmacOS 10.15では、実行できるアーキテクチャとして64-bit Intel (x86_64) しかサポートされていない。 2.ユニバーサルバイナリのビルド方法 configureに"--enable-universalsdkフラグを指定する事でユニバーサルバイナリを有効にできる。 $ ./configure --enable-universalsdk $ make $ make install このフラグはpythonをフレームワークとしてビルドする場合だけでなく、従来のunix形式のビルドでも使用できる。ユニバーサルバイナリはmacOS 10.4におけるXcode 2.1と10.4u SDKで最初にサポートされた。Xcode 3とmacOS 10.5から、より多くの設定が利用できる様になった。 通常、ユニバーサルビルドは、AppleのXcode開発ツール含まれている、Appleから供給されるコンパイラや他のビルドツールが提供する特定の機能に依存する。現在動いているmacOSのリリースに適したXcodeかコマンドラインツールのコンポーネントのインストールが推奨される。より詳しい情報はPython Developer's Guide (https://devguide.python.org/setup/) を見よ。 2.1 ユニバーサルバイナリのタイプ 幾つかのタイプのユニバーサルバイナリをビルドすることができ、デフォルトではPPCがサポートされるビルド環境 (macOS 10.4とXcode 2, macOS 10.5および10.6とXcode 3) なら32-bitバイナリ (i386とppc) のみ、ppcをサポートしていないビルド環境 (macOS 10.6におけるXcode 4およびそれ以降のシステム) ならIntel-32/-64-bitバイナリ (i386 and X86_64) となる。そのタイプはconfigureの"--with-universal-archs=VALUE"オプションを使用して指定できる: universal2: arm64, x86_64 intel: i386, x86_64 intel-32: i386 intel-64: x86_64 32-bit: ppc, i386 3-way: i386, x86_64, ppc 64-bit: ppc64, x86_64 all: ppc, ppc64, i386, x86_64 64-bitアーキテクチャ (ppc64、x86_64およびarm64) を含むユニバーサルバイナリをビルドするためには、macOS 10.5かそれ以降が動いてるシステムでビルドしなければならない。allおよび64-bit (ppc64, x86_64)タイプのビルドは10.5 SDKのみで可能であり、なぜならppc64のサポートがmocOS 10.5にしか含まれていない為である。macOS 10.6のXcode 3にはppcサポートが遺産として含まれていたにもかかわらず、macOS 10.6でリリースされたXcode 4では削除され、macOS 10.7ではppcがサポートされない事が標準となった。まとめると、以下のSDKとuniversal-archsのタイプの組み合わせが有効となる: 10.4u SDKおよびXcode 2は32-bitのみ 10.5 SDKおよびXcode 3.1.xは全タイプ 10.6 SDKおよびXcode 3.2.xはintel、intel-32、intel-64、3-wayおよび32-bit 10.6 SDKおよびXcode 4はintel、intel-32およびintel-64 10.7から10.14 SDKsはintel、intel-32およびintel-64 10.15およびそれ以降のSDKsはintel-64のみ 11.0およびそれ以降のSDKsはuniversal2 フレームワーク形式でビルドする場合のmakefileは、ユニバーサルアーキテクチャが少なくとも1つの32-bitアーキテクチャを含む場合、python3.x-32もインストールする(すなわち、64-bitとintel-64以外の全タイプ)。また、AppleシリコンMacのRosetta 2 Intenエミュレータで簡単に実行できる様にするため、universal2ではpython3.x-intel64バイナリもインストールしている。 アーキテクチャを指定しての実行 archコマンドを使用してアーキテクチャを指定してコードを実行できる: $ arch -i386 python マシンのハードウェアに関係なく、明示的に32-bitモードとしても実行できる: $ arch -i386 -ppc python archコマンドの使用は、そのarchコマンドで実行されたPythonから起動されるサブプロセス (プログラムやテスト) に、選択されたアーキテクチャを自動的に引き継がないため、アーキテクチャの指定を完全には解決しない。もしメインのインタプリタから起動されたサブプロセスも32-bitモードで確実に起動したい場合には、python3.x-32バイナリ上で、subprocess Popen4に対してsys.executable5を実行する引数として使用する。 同じ様に、universal2バイナリのx86_64モードを強制的に実行するには、python3.x-intel64を使用する。 macOSでフレームワークベースのPythonをビルドして使用する 1.一体なぜ通常の静的版Pythonの代わりにフレームワーク版Pythonを使用するのか? この主な理由は、PythonでGUIプログラムを作れる様にする為である。X11/XDarwinベースのGUIを除いた全てのGUIプログラムは、macOSアプリケーションバンドル (".app")からの起動を必要とする。 フレームワークを用いない.appを作成することは技術的には可能であるが、これを本当に必要とするならば、自身で作成すべきである。 フレームワークを用いる第二の理由は、Pythonに関係するアイテムを、次の2つの場所にのみ配置するからである。その場所は"/Library/Framework/Python.framework"および "/Applications/Python <VERSION>"となり、ここで、 "<VERSION>"は"3.8"や"2.7"となる。これにより、バイナリ配布版からPythonをインストールしたユーザが、再びそれを取り除きたい場合に、処理が簡単となる。さらに、フレームワークとして稼働する方法を選ぶことにより、管理者権限のないユーザが、自身のホームディレクトリにバイナリ配布版を再コンパイルせずにインストールできる。 2.通常の静的版Pythonとフレームワーク版Pythonは何が違うのか? 格納場所が異なるだけで、普段使用する範囲においては特に違いはない。/Library/Frameworks/Python.frameworkを見れば、たくさんの相対シンボリックリンクが確認できる(詳しくは、Appleのドキュメントを見よ)。通常のUnix形式におけるPythonのファイルレイアウトに慣れているなら、Versions/Currentに行けば、おなじみのbinとlibディレクトリが確認できる。 3.追加パッケージは必要か? 十中八九、必要である。Tkinterのサポートを望むなら、macOS AquaTkディストリビューションを手に入れることが必要となり、これはmacOS 10.4以降にはデフォルトでインストールされている。macOS 10.6から提供が開始されあたCocoaベースのAquaTkは不安定であることが証明されているので気をつけること。もし可能であれば、macOS 10.6以降でビルドする前に、最新バージョンのインストールを検討するべきで、例えばActiveTcl 8.6等である。https://www.python.org/download/mac/tcltk/を見よ。SDKとビルドするなら、SDKのLibrary/Frameworksディレクトリ内に最新版のTclおよびTkフレームワークが含めれているか確認すること。場合によっては、それらのインストールされた場所 (/Library/Frameworks) に手動でシンボリックリンクを貼る必要がある。wxPythonを使用する場合、それを行う必要がある。Cocoaを使用する場合は、PyObjCを得る必要がある。 4.フレームワーク版Pythonのビルド方法 このディレクトリ (Mac/) は、"/Applications/Python <VERSION>"に幾つかのPython関連のアプリケーション (つまり、完全なmacOS .appアプリケーション) を、Pythonフレームワーク内にPython.app隠しヘルパーアプリケーションを、/usr/local/bin内に"python"を含むunixツールを作成するMakefileを保有する。加えて、Macサブツリーの関連部分をPython.frameworkにインストールする"installmacsubtree"ターゲットも保有する。 通常の呼び出しでは、最後のステップでメインのMakefileを間接的に呼び出す。 ./configure --enable-framework make make install この手順では、フレームワークは/Library/Framework/Python.framework、アプリケーションは/Applications/Python <VERSION>およびUnixツールは/usr/local/binに配置される。 他の場所にインストールする際、例えばマシンの管理者権限を持っていない場合に$HOME/Library/Frameworksを対象とするなら、インストール可能である。これは、--enable-framework=$HOME/Library/Frameworksをつけてconfigureすることで行うことができる。他の2つのディレクトリも、その場合は$HOME/Applications/Python-<VERSION>および$HOME/binにインストールされる。 全てではなく、一部だけインストールを行いたい場合は、メインのMakefileを見よ。frameworkinstallは、フレームワーク自身、Macサブツリー、アプリケーションおよびunixツールをインストールする幾つかのサブターゲットから成り立っている。 通常のframeworkinstallに含まれない追加ターゲットであるframeworkinstallextrasがあり、Toolsディレクトリを"/Applications/Python <VERSION>"にインストールする。これは、バイナリの配布に役立つ。 "/Applications/Python <VERSION>"下のプログラムは何をするのか? "IDLE.app"はPythonの統合開発環境 (エディタ、デバッガなど) である。 "Python Launcher.app"は、.py、.pyc および.pywがダブルクリックされれた時に実行されるヘルパーアプリケーションである。最初の二つ(.pyおよび.pyc)はターミナルウインドウが起動され、通常のコマンドラインでPythonからスクリプトを実行する。後者 (.pyc ) に対しては、Python.appインタプリタ上でスクリプトを実行され、スクリプトがGUI関連を実行できるようにするためである。Optionキーを押したままドラックかダブルクリックすると、スクリプトに実行時オプションを設定できる。これらオプションはPython Launcherの設定ダイアログから永続的に設定することもできる。 pythonx.xプログラムは、コマンドラインからpythonスクリプトとして実行する。以前は、macOS上のPythonの初期リリースでGUIプログラムを実行するために必要だったpythonwx.xを含む、さまざまな互換性を持つエイリアスもインストールされていた。3.4.0時点で、pythonwx.xエイリアスはもうインストールされていない。 バイナリ配布版をどう作るか? 公開されているソースをhttps://www.python.org/download/からダウンロードして、展開する。"Mac/BuildScript"に移動する。そこに、全ての作業を行うbuild-installer.pyスクリプトがある。これは、幾つかのサードパーティ製ライブラリをダウンロードしてビルドし、フレームワーク版Pythonの設定とビルドをしてインストールを行い、インストーラパッケージファイルを作り、それをDMGイメージとして固める。このスクリプトは加えて、このリリースに対する現在のPythonドキュメント一式のHTMLコピーを、フレームワークに含ませるためにビルドする。インストーラパッケージはIDLE、pydoc、ShellユーザおよびFinderユーザが使用するためのドキュメントへのリンクを作成する。 スクリプトはユニバーサルバイナリをビルドするので、このスクリプト(build-installer.py)はmacOS 10.4以降およびXcode 2.1以降がインストールされた環境で実行しなければならない。しかしながら、Pythonのビルドプロセスは、macOS 10.4だと追加設定なしに利用できない幾つかの依存関係を持つため、Xcode 2で提供されている物以外にも、追加のソフトウェアが必要かもしれない。 古いバージョンのSDKsやXcodeを組み合わせて、より新しいシステム上で古いシステムに互換性のあるインストーラをビルドする事は可能ではあるが、これは完全確実ではない。そのため、作成される実行バイナリ、共有ライブラリおよび.soバンドルに対して、動的リンクの依存性が適切か全てのサポートされるシステムで入念に調査およびテストする必要がある。最小限のmacOSバージョンがサポートされて稼働しているシステム上で、配布版をビルドするのが安全である。 これら全ては通常完全に /tmp/_pyに切り離されて行われるため、通常のビルドディレクトリは使用されず、/にもインストールを行う事はない。 このスクリプトはファイルを探すために、BuildScriptディレクトリ内で実行する必要がある。スクリプトは幾つかのコマンドライン引数を指定できるので、より詳細な情報は--helpを引数にスクリプトを実行して得よ。 Configureの警告 configureスクリプトは時々以下の様な警告を出す: configure: WARNING: libintl.h: present but cannot be compiled configure: WARNING: libintl.h: check for missing prerequisite headers? configure: WARNING: libintl.h: see the Autoconf documentation configure: WARNING: libintl.h: section "Present But Cannot Be Compiled" configure: WARNING: libintl.h: proceeding with the preprocessor's result configure: WARNING: libintl.h: in the future, the compiler will take precedence configure: WARNING: ## --------------------------------------- ## configure: WARNING: ## Report this to https://bugs.python.org/ ## configure: WARNING: ## --------------------------------------- ## これは大抵の場合、ユニバーサルバイナリをビルドしようろする時に、/usr/local内に必要なアーキテクチャのライブラリを保有していない事を意味する。ビルドを完了させるため、一時的に/usr/localを傍に動かせ。 フレームワーク版インストールをアンインストールする (バイナリインストーラー版インストールも含む) フレームワークのアンインストールは、インストールされた全てを手動で削除して行う。これは、ソースおよびバイナリインストーラを使用したインストールのどちらに当てはまる。mac OSはシステム自身によるアンインストーラを提供していない。 フレームワーク版のインストールにおける主な部分は、フレームワークそれ自体であり、/Library/Frameworks/Python.frameworkにインストールされている。ここには複数バージョンのPythonが存在することがあり、一つのバージョンだけを削除したい場合は、そのバージョンに対応したサブディレクトリを削除する: /Library/Frameworks/Python.framework/Versions/X.Y。その場合、/Library/Frameworks/Python.framework/Versions/Current がインストールされたバージョンのPythonをさしているシンボリックリンクか確認すること。 フレームワーク版のインストールは/Applications/Python X.Yに幾つかのアプリケーションもインストールしている。 最後に、フレームワーク版インストールは/usr/local/binにファイルをインストールし、/Library/Frameworks/Python.framework/Versions/X.Y/binに/usr/local/bin内のファイル全てのシンボリックリンクを貼っている。 Weak linkingのサポート6 CpythonのソースはmacOS 10.9をデプロイの対象とする一方、最新のSDKでビルドする事に対応している。これは、macOS 10.10以降で導入されたシンボルのweak linkingと、実行時にそれらが有効か確認して実現している。 これには、macOS 10.13以降のApple製コンパイラーのツールチェインが必要となる。 HAVE_<FUNCTION> はconfigureスクリプトによって定義される(または未定義となる)マクロ。 HAVE_<FUNCTION>_RUNTIMEは関連するソースファイル上で定義されているマクロ。このマクロは、十分に新しいApple製コンパイラが使用される場には、__builtin_availableが呼ばれる様に拡張し、そうでなければtrue値を返す。 <function>が呼び出される前に、HAVE_<FUNCTION>_RUNTIMEを使用する。このマクロは、if文の中で単体の式として使用されなければいけない: if (HAVE_<FUNCTION>_RUNTIME) { /* <function> is available */ } または、 if (HAVE_<FUNCTION>_RUNTIME) {} else { /* <function> is not available */ } 他のパターン (例えば!HAVE_<FUNCTION>_RUNTIME) はApple製コンパイラではサポートされていない。 参考 https://www.python.org/downloads/macos/ https://www.python.org/community/sigs/current/pythonmac-sig/ https://devguide.python.org/ macOS 64-bit universal2 installerという物もあり...。 ↩ プログラムが実行時に動的ライブラリを呼び出す際、検索対象として追加されるディレクトリ。プログラムのコンパイル時に、リンカーの-rpathフラグ等により指定される。 ↩ ↩2 Copyright © 2001-2022 Python Software Foundation; All Rights Reserved (参照: https://docs.python.org/ja/3/license.html#psf-license) ↩ https://docs.python.org/ja/3/library/subprocess.html ↩ https://docs.python.org/ja/3/library/sys.html ↩ CPythonのコードを弄る場合に必要となる知識なので、今回の本題的には特に理解が必要な知識ではないです。 ↩
- 投稿日:2022-03-22T19:50:50+09:00
【mac】networkQualityコマンドの紹介
networkQualityコマンドとは? ネットワークの品質を手軽に確認することができるコマンドです。 pingコマンドや回線スピードをテストするサイトなどの代わりに使うことができそうです。 macOSのMontereyから追加されました。 何がわかるか コマンドを実行すると、1分間あたりのラウンドトリップ数がわかります。 ラウンドトリップとは、ネットワーク通信でメッセージを送って、返答が送信元に戻ってくるまでのことを云います。 networkQualityでは1分間あたりのラウンドトリップ数を教えてくれます。 同時にアップロードとダウンロードの処理能力も測定してくれます。 (実行結果サンプルの再下行の(348 RPM)がラウンドトリップ数/分) 実行結果サンプル $ networkQuality ==== SUMMARY ==== Upload capacity: 71.466 Mbps Download capacity: 115.972 Mbps Upload flows: 20 Download flows: 16 Responsiveness: Medium (348 RPM) ヘルプ $ networkQuality -h USAGE: networkQuality [-C <configuration_url>] [-c] [-h] [-I <interfaceName>] [-s] [-v] -C: override Configuration URL -c: Produce computer-readable output -h: Show help (this message) -I: Bind test to interface (e.g., en0, pdp_ip0,...) -s: Run tests sequentially instead of parallel upload/download -v: Verbose output
- 投稿日:2022-03-22T16:26:50+09:00
【Mac】Ruby3.1.1がインストールできなくて辛かった
なんとなく「Rails7を使ってみよう!せっかくだからRubyも新しいの入れとくか!」と思い立ったものの、全然全くインストールできずハマったのでのでその時の対処法をメモ。 実行環境:macOS Monterey(12.2.1) エラー ruby3.1.1をインストールしようとするもエラーを吐かれてしまう。 $ rbenv install 3.1.1 Last 10 log lines: checking for llvm-strip... no checking for gcc... clang checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... configure: error: in `/var/folders/r1/x9mwdc5s12z1fj1361bzv8z00000gn/T/ruby-build.20220322144842.18804.Za253O/ruby-3.1.0': configure: error: cannot run C compiled programs. If you meant to cross compile, use `--host'. See `config.log' for more details make: *** No targets specified and no makefile found. Stop. やってみた1: Xcode再インストール ググると「Xcodeを入れ直す直すべし」との声が多数あったので、XcodeとCommandLineToolsを再インストール。 [参考] https://blog.nocorica.jp/2017/01/rbenv-failed/ →同じエラーが出た。 ログを読む See 'config.log' for more detailsと言っているのでとりあえず見てよう(先に見ればいいのに)。 $ cd /var/folders/r1/x9mwdc5s12z1fj1361bzv8z00000gn/T/ruby-build.20220322140955.1606.YESPtG/ruby-3.1.1 $ cat config.log ~~略~~ clang: error: argument to '-V' is missing (expected 1 value) clang: error: no input files configure:5773: $? = 1 configure:5762: clang -qversion >&5 clang: error: unknown argument '-qversion'; did you mean '--version'? clang: error: no input files ~~ clangが何か失敗してるっぽい。 $ clang -v Apple clang version 13.1.6 (clang-1316.0.21.2) Target: x86_64-apple-darwin21.3.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin ちゃんと入ってるのにね!なんだよ!!!! やってみた2(解決): clangのバージョンを下げる 憤りながらも残念ながら「clangのバージョンを下げてみる」くらいしかやることが思いつかなかったので実行。 [参考] https://soluna-eureka.hatenablog.com/entry/2021/01/10/201341 llvmをインストール。 $ brew install llvm パスを通す。 $ vi ~/.zshrc # 下記を追加 export PATH="/usr/local/opt/llvm/bin:$PATH" export LDFLAGS="-L/usr/local/opt/llvm/lib" export CPPFLAGS="-I/usr/local/opt/llvm/include" # 追加ここまで $ source .zshrc clangはどうなったのか? $ clang -v Homebrew clang version 13.0.1 Target: x86_64-apple-darwin21.3.0 Thread model: posix InstalledDir: /usr/local/opt/llvm/bin # 元の状態 Apple clang version 13.1.6 (clang-1316.0.21.2) Target: x86_64-apple-darwin21.3.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin ちょっと変わった。うーん意味があるか怪しいが、リベンジ。 $ rbenv install 3.1.1 ~~略~~ Installed ruby-3.1.1 to /Users/hoge/.rbenv/versions/3.1.1 インストールできました!!やったね!!!!
- 投稿日:2022-03-22T14:19:21+09:00
Finder の殺し方
殺り方 macOS の Finder.app は、デフォルトだと終了させることはできないが、以下のコマンドをターミナル1で実行すると終了させることができる。 Shell defaults write com.apple.Finder QuitMenuItem -boolean true killall Finder すると、Finder のメニューバーにアプリを終了する項目が表示されるようになる。 メリット 筆者は頻繁に command + tab でアプリケーションを切り替えるのだが、そのときにいちいち Finder が一覧に出てくると、一回分多く tab を入力しなければいけなくて煩わしい。 しかし、この方法で Finder を終了させておくと command + tab を押したときに Finder が出てこないので便利である。 ターミナルの開き方 command + space を押して Spotlight を開き、terminal.app と入力してエンターキーを押すとターミナルが開く。 ターミナルの開き方がわからない場合は、ターミナルの開き方 を参照すること。 ↩
- 投稿日:2022-03-22T10:14:16+09:00
「やっとわかったCoreData」のモノマネ
概要 @pe-taさんの「やっとわかったSwift/CoreData入門」をObjective-Cに移植したものです。(逐語訳ではありません。自己流のコードだらけです。)マックブック用ですから、よかったらアップルのDeveloperアカウントを持ってない方も使ってみてください。 バージョンはmacOSが12.3、Xcodeが13.3です。 プロジェクトの作成 Xcode→File→NewProjectとし、最上段をmacOS(iOSではない)とし、APPを指定します。次のページに移って、プロダクト名は原作と同じTestCoreData、言語はObjective-Cにします。UseCoreDataのチェックをお忘れなく。 チーム名などはNoneのままでOKです。 Entityの設定 原作と全く同じで、新しいEntityを作り、名前をMonsterとします。そのAttributeは一つだけで、NameはmonsterName、TypeはStringとします。 EntityのMonsterを選択し、右側のCodegenというところがClass Definitionになっているのを確認して下さい。多分デフォールトでそうなっている筈です。 ViewController.m ちょっと乱暴ですが、元のコードをすべて削り、代わりに次のコードをこのままペーストして下さい。これをやらないと、次の作業の間ずっとXcodeが文句をいってきます。 // // ViewController.m // TestCoreData // // Created by Myself on 2022/03/16. // #import "ViewController.h" ViewController *viewctrl_ptr; /* (referenced by 'AppDelegate') */ @implementation ViewController { #pragma mark global variables within ViewController AppDelegate *parent_ptr; NSArray<NSManagedObject *> *monstary; /* (handled by Core Data) */ NSManagedObjectModel *my_mom; NSPersistentStoreCoordinator *my_psc; NSManagedObjectContext *my_moc; NSFetchRequest *my_fetch; } #pragma mark initializers - (void)viewDidLoad { [super viewDidLoad]; viewctrl_ptr = self; /* set public variable */ tbl_view_ptr.delegate = self; tbl_view_ptr.dataSource = self; monstary = nil; /* (against some accident) */ } // viewDidLoad - (void)setRepresentedObject:(id)representedObject { [super setRepresentedObject:representedObject]; // Update the view, if already loaded. } // setRepresentedObject #pragma mark public functions - (void)setParent_ptr:(AppDelegate *)myparent /* called by 'AppDelegate' */ { parent_ptr = myparent; NSLog(@"parent ready"); } // setParent_ptr -(void)set_pc /* set persistent-container variables */ /* called by 'AppDelegate' */ /* called after AppDelegate ready */ { [self initcore]; /* initialize core data */ [tbl_view_ptr reloadData]; /* display registered Monsters */ } // set_pc #pragma mark event handler - (IBAction)editdone:(NSTextField *)sender { NSString *mystring; NSLog(@"notification from text-field"); [txtfield_ptr resignFirstResponder]; mystring = txtfield_ptr.stringValue; if ( mystring == nil ) NSLog(@"textfield not yet ready"); else if ( mystring.length == 0 ) NSLog(@"textfield empty"); else { [self createOneWithName: mystring]; /* create one Monster */ [tbl_view_ptr reloadData]; txtfield_ptr.stringValue = @""; /* clear textfield */ } } // editdone #pragma mark core data functions - (void)initcore /* initialize core data */ /* note: 'my_mom' and 'my_psc' not used */ { NSArray *temp_ary; NSError *errorptr; NSAssert(parent_ptr.persistentContainer != nil, @"persistentContainer failed"); my_mom = parent_ptr.persistentContainer.managedObjectModel; NSAssert(my_mom != nil, @"managed object managedobjectmode failed"); my_psc = parent_ptr.persistentContainer.persistentStoreCoordinator; NSAssert(my_psc != nil, @"persistent store coordinator failed"); my_moc = parent_ptr.persistentContainer.viewContext; NSAssert(my_moc != nil, @"managed object context failed"); my_fetch = [[NSFetchRequest alloc] initWithEntityName: @"Monster"]; errorptr = nil; /* (unnecessary ... result not used) */ temp_ary = [my_moc executeFetchRequest: my_fetch error: &errorptr]; if ( temp_ary == nil ) NSLog(@"monster array not yet ready"); else /* (usually array ready) */ monstary = temp_ary; } // initcore - (void)createOneWithName: (NSString *)the_name /* create and save one entity */ { NSManagedObject *one_monster; NSEntityDescription *myentity; NSError *errorptr; BOOL myresult; /* create one Monster(entity) */ NSLog(@"start creating Monster"); myentity = [NSEntityDescription entityForName:@"Monster" inManagedObjectContext: my_moc]; one_monster = [[NSManagedObject alloc] initWithEntity: myentity insertIntoManagedObjectContext: my_moc]; NSAssert(one_monster != nil, @"managed object creation failed"); /* set attribute (Monster name) */ [one_monster setValue: the_name forKey: @"monsterName"]; /* save the Monster */ /* update monster-array */ NSLog(@"start saving monster"); errorptr = nil; /* (&errorptr = '\0') */ myresult = [one_monster.managedObjectContext save: &errorptr]; if ( ( myresult == NO ) || ( errorptr != nil ) ) NSLog(@"monster '%@' save error", the_name); else /* (here errorptr == nil) */ { NSLog(@"new monster with name '%@' saved", the_name); monstary = [my_moc executeFetchRequest: my_fetch error: &errorptr]; NSAssert(monstary != nil, @"monster-array fetch failed"); } } // createOne #pragma mark delegate and datasource - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { NSInteger nbr_rows; /* number of rows */ if ( monstary == nil ) /* monster array not ready */ nbr_rows = 0; else nbr_rows = monstary.count; return nbr_rows; } // numberOfRows - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { NSString *mystring; NSManagedObject *one_monster; if ( monstary == nil ) /* array not ready (never occurs?) */ mystring = @""; else { one_monster = [monstary objectAtIndex: rowIndex]; mystring = [one_monster valueForKey: @"monsterName"]; } return mystring; } // objectValue @end Xcodeはまだ何か文句をいっていますが、先に進みましょう。 ViewController.h 変更は少しだけです。 #import <CoreData/CoreData.h> // ← これを追加する #import "AppDelegate.h" // ← これを追加する @interface ViewController : NSViewController <NSTableViewDelegate, NSTableViewDataSource> // ← これを追加する /* -- public functions (called by 'AppDelegate') -- */ // AppDelegateから呼ばれるfunctionを2行追加 - (void)setParent_ptr:(AppDelegate *)myparent; - (void)set_pc; AppDelegate.m 変更は次のとおりです。 #import "AppDelegate.h" #import "ViewController.h" // ← これを追加する extern ViewController *viewctrl_ptr; // ← これを追加する @interface AppDelegate () - (IBAction)saveAction:(id)sender; @end @implementation AppDelegate // この関数の内容を次のようにする // この関数はViewDidLoadよりも後で呼ばれる // だからviewctrl_ptrはすでにセットされている筈 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { NSAssert(viewctrl_ptr != nil, @"ViewController not ready"); [viewctrl_ptr setParent_ptr: self]; [viewctrl_ptr set_pc]; // Insert code here to initialize your application } AppDelegate.hの変更はありません。 (投稿直前になって気が付いたのですが、viewctrl_ptrの初期値をnilにしておくべきでした。このままではNSAssertの意味がありませんよね 。) ストーリーボードの設定 Viewに部品TextFieldをセット(ドラッグ・ドロップ)します。 TextFieldのActionがSent On End Editingになっているのを確認します。 TextFieldの下に部品TableViewをセットします。 TableViewのContent ModeをCell Based、列数を1にします。 TableViewにはTextCellと表示されていますが、ここにTextFieldCellをセットします。似たような部品が多いのでご注意を。 ここから3本、コネクションをやります。アシスタントエディタを開き、ViewController.mを表示させます。 TextFieldからコントロール・ドラッグして、ViewController.mの@implementationのすぐ下のブレースの中にIBOutletを作り、名前をtxtfield_ptrにします。 TableViewからコントロール・ドラッグして、さっきの下にIBOutletを作り、名前をtbl_view_ptrにします。 最後にTextFieldからコントロール・ドラッグして、ViewController.mの中程にある(IBAction)editdoneにコネクトします。 なおdelegateとdatasourceはViewController.mで手当てしているので、処理は不要です。 試運転 ビルドさせて実行し、テキストフィールドにモンスター名を入力してエンターキーを押すと、テーブルに名前が表示されます。デバッグウィンドウで作業内容がわかりますね。 試運転が終わったらストップボタンを押して下さい。 アプリケーションを作成 Xcode→Product→Archiveに進むと、アーカイブが作成されます。作成後の表示を見失ったらXcode→Window→Organizerで同じ画面が表示されます。 Distribute Appからcopy Appとし、お好きなフォルダーを選んで下さい。Finderツールを使って見ると堂々たる(?)自作アプリケーションの完成です。拡張子もちゃんとappになっていますね。 Xcodeを終了し、Finderツールでアプリケーションをダブルクリックすると、Xcodeなしでアプリが起動し、メニューバーにはアプリ名が表示されます。 モンスター名をいくつか追加し、メニューバーからアプリを終了させ、再び起動させると、追加分も正しく表示されているのがわかります。 終わりに 最初に申し上げたとおり、コードが自己流ですみません。変数名や関数名にいわゆるキャメルをほとんど使っていませんが、お見逃し下さい。 viewctrl_ptrのようなバグがほかにもありそうです。いろいろご指摘をお待ちしております。
- 投稿日:2022-03-22T00:37:50+09:00
macOS Big Surで「その他」のストレージを減らしたい時
環境 M1 macbook Air Big Sur(後述しますが、Montereyにアプデしたため、バージョンは正確に覚えていません) 要約 「その他」のデータが非常に大きい人は、Dockerのリソース設定を見直すと解決するかもしれません。Preferences->Resources->Disk image sizeを減らすと良いです。 はじめに ストレージが逼迫してきたので、必要ないデータを削除しようとした。「その他」のデータがおよそ100GBほど存在しているが、容量が大きいデータがどこにあるかがよくわからなかった。 ググると、~/Library/Caches/にあるキャッシュを減らすと解決する場合があるようだが、私の環境だと数GBしかなかった。 やったこと 別件でMontereyに更新する必要があったので、更新した。すると、「その他」のデータのうち、数十GBが「書類」に分別されており、調べるとDockerのrawファイルサイズが非常に大きいことがわかった。 ググると、Docker for Macでよくある問題らしい。参考 Dockerで使用するディスクサイズを減らすと、ストレージの空き容量を増やすことができた。 まとめ 「その他」のデータがストレージを多く占める場合、OSをアップデートしてみると、解決の糸口が見つかるかもしれません。今回だと、Docker周りの設定が原因でした。 また、よく使うソフトウェアの設定は定期的に見直すべきだと思いました。 おしまい