Makefileで並列処理 / jオプション その2 エラー回避策

並列処理するため”make all -j12″を実行した場合に初回エラーになる不具合の解決策が見つかりました。

エラー内容を確認すると、オブジェクトファイルが揃わないうちにリンクしていることが判明しました。そこでMakefile内の順番を変えて、必ずコンパイルが全て終わってからリンクするようにしました。

これで確実に並列処理できるようになりました。

# コンパイル後リンク ← この部分を前にもってきた
.PHONY: all
all: $(TARGET)

# oファイルから実行ファイルとappファイル作成
$(TARGET): $(OBJS)
	$(COMPILER) -o $(TARGETDIR)/$@ $(OBJS) $(LIBRARY0) $(LDFLAGS) $(LIBRARY)
	mkdir -p $(TARGET).app/Contents/MacOS
	mkdir -p $(TARGET).app/Contents/Resources
	cp $(TARGETDIR)/$(TARGET) $(TARGET).app/Contents/MacOS/$(TARGET)
	cp ./images/$(TARGET).icns $(TARGET).app/Contents/Resources
	echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" > $(TARGET).app/Contents/Info.plist
	echo "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" >> $(TARGET).app/Contents/Info.plist
	echo "<plist version=\"1.0\">" >> $(TARGET).app/Contents/Info.plist
	echo "<dict>" >> $(TARGET).app/Contents/Info.plist
	echo "  <key>CFBundleExecutable</key>" >> $(TARGET).app/Contents/Info.plist
	echo "  <string>$(TARGET)</string>" >> $(TARGET).app/Contents/Info.plist
	echo "  <key>CFBundleIconFile</key>" >> $(TARGET).app/Contents/Info.plist
	echo "  <string>$(TARGET).icns</string>" >> $(TARGET).app/Contents/Info.plist
	echo "  <key>CFBundleIdentifier</key>" >> $(TARGET).app/Contents/Info.plist
	echo "  <string>com.yourcompany.$(TARGET)</string>" >> $(TARGET).app/Contents/Info.plist
	echo "  <key>CFBundleName</key>" >> $(TARGET).app/Contents/Info.plist
	echo "  <string>$(TARGET)</string>" >> $(TARGET).app/Contents/Info.plist
	echo "  <key>CFBundleVersion</key>" >> $(TARGET).app/Contents/Info.plist
	echo "  <string>1.0</string>" >> $(TARGET).app/Contents/Info.plist
	echo "</dict>" >> $(TARGET).app/Contents/Info.plist
	echo "</plist>" >> $(TARGET).app/Contents/Info.plist

# 全ファイル削除
.PHONY: clean
clean:
	rm -rf $(OBJS) $(TARGETDIR)/$(TARGET) $(TARGET).app

Makefileで並列処理 / jオプション その1

CPUのコアをフルに使ってビルドする場合はjオプションを追加します。諸説ありますが、基本的にはコア数を付けてビルドします。

# M2 Pro Mac miniは12コア
make all -j12

Makefileはそのまま使えます。今のところ最初のmakeコマンドでは失敗しますが、2回目で正常にビルドできます。

オブジェクトファイルの作成を並列処理できるので、その工程は大体1/cppファイル数(12以下)の処理時間に短縮できます。今回は8ファイルなので約1/8です。かなりの高速化になります。ただしMakefileを複数用いる場合は何らかの工夫が必要になるようです。

比較的簡単なプログラムであればものの数秒でビルドできてしまいます。ここまで高速化できると、C++を扱うホビープログラマにとってはM1で十分です。

ただXcodeでSwiftのプロジェクトをビルドするとそれなりに時間がかかるため、M2 Proでもまだ足りないですね。

今は1回目に必ずビルド失敗する状況ですから、最初からmake allコマンドでシングルコア・ビルドしていれば良いわけでちょっと微妙な改良ではあります。ビルドに数分かかるような大きめのプログラムでしたら導入の価値ありです。

M2 Pro Mac miniをクリーンインストール 2024年11月

昨年2023年8月に購入したMac mini 整備品の内部ストレージ1TBが一杯になったのでクリーンインストールしました。外部ストレージ1TBも余裕がなく2TBにサイズアップしました。

折しも発売になったM4 Pro Mac mini 2TBへの買い替えも考えましたが、さすがに思いとどまりました。

手順

1.Mac miniのデータを外部SSD 1TBに移行し、起動ディスクにした。移行前にmacOS SequoiaをmacOSユーティリティを使ってインストールしている(ユーティリティ画面は電源ボタン長押しで出現)。

2.Mac miniのデータを消去し、macOS Sonomaをインストール。ユーティリティからはSonomaだったので、後でSequoiaにアップデートした。

3.起動ディスクをストレージとして接続した状態でMac miniを起動する。

4.前環境の移行
・用意しておいたHomebrewのBrewfileやPyPIのrequirements.txtを起動ディスクのホームディレクトリからMac miniホームディレクトリへコピーし、下記記事に従って導入する。
・.bash_profileや.vscodeディレクトリをコピーする。
・デスクトップディレクトリをコピーする。
・iCloudカレンダーを共有する。
・Time Machineを設定する。
・モニターのアンチエイリアスを有効にする(下記記事参照)。
・メール環境を移行する。
 メール環境移行の参考サイト

5.Xcode、Excel、VScodeなど常用アプリをインストールする。

6.シェルを常用しているものに変更する(Zsh → Bash)。

7.Homebrew以外のライブラリをGitHubなどからインストールし、C++プロジェクトからmakefileでビルドできるようにする。今回はwxWidgetsをGitHubからダウンロード、ビルドした(下記の記事参照)。

8.Pythonを導入
・最新のPythonを公式サイトからダウンロードして、インストールする(今回は3.13.0)。
・pythonコマンドでpython3が動作するようにシンボリックリンクを作成する。

ln -s /usr/local/bin/python3 /usr/local/bin/python

・適当なスクリプトを実行して足りないライブラリをpipコマンドで導入する。

9. 起動ディスクのファイル構成をFinderで確認しながら、足りないアプリを順次インストールする。

ゆっくり時間をかけて2日で前環境の主要な部分を再構成できました。前環境は起動ディスクとして残しているので、至急の際はこちらで対応できます。起動ディスク環境では最初音が出ませんでしたが、ヘッドホンジャック挿し直しで出るようになりました。

手間はかかりますが、工夫次第で本体1TB(プラス外部2TB)でも開発環境の維持は可能なようです。