アプリやファイルをdmg(ディスクイメージ)にまとめて配布したい場合は、hdiutil createでフォルダからdmgを作る。-srcfolderには、dmgに入れるファイルを置いたフォルダを指定する。-volnameには、dmgをマウントしたときのボリューム名を指定する。

$ hdiutil create -volname "[ボリューム名]" -srcfolder [フォルダ] -ov [dmgのファイル名].dmg

ここでは、フォルダからdmgを作る手順と、作成したdmgの中身を確認する方法を紹介する。実行例はmacOS 27.0.1のもの。

フォルダからdmgを作る

dmgに入れるアプリやファイルを、1つのフォルダにまとめる。ここでは、Demo.appを入れたsrc-appフォルダからdmgを作る。

$ hdiutil create -volname "Demo App" -srcfolder src-app -ov app.dmg
created: [app.dmgのフルパス]
hdiutil: WARNING: 'hdiutil create -volname -format ...' is deprecated. Please use 'diskutil image create from/blank --volumeName --format ...' instead.

created:の行が表示されれば、dmgが作成されている。

2行目の警告は、hdiutil createが非推奨になったことを知らせる。警告が表示されても、dmgは作成され、終了コードは0である。hdiutil createの移行先は、diskutil image createである。

参考: 【diskutil】image createでdmgを作る

フォルダの中身がdmgのルートに入る

-srcfolderに指定したフォルダ自体ではなく、フォルダの中身が、dmgのルートに入る。src-appフォルダの中のDemo.appが、dmgのルートに入る。

src-app/
  Demo.app/

↓ dmg をマウントしたときのルート

Demo App/
  Demo.app/

隠しファイル(.で始まるファイル)も、dmgに含まれる。dmgに入れたくないファイルは、フォルダから取り除いてから、dmgを作る。

ボリューム名を指定する

-volnameには、dmgをマウントしたときのボリューム名を指定する。Finderのサイドバーや、/Volumesの下に、この名前で表示される。

-volnameを省略すると、-srcfolderに指定したフォルダの名前がボリューム名になる。

$ hdiutil create -srcfolder src-files -ov novol.dmg
$ diskutil info [マウントポイント] | grep 'Volume Name'
   Volume Name:               src-files

ボリューム名は、dmgを開いたユーザーが目にする名前である。アプリ名など、分かりやすい名前を指定する。

同名のファイルがあるとエラーになる

作成先に同名のdmgがある場合、-ovを付けないとエラーになる。

$ hdiutil create -volname "Demo App" -srcfolder src-app app.dmg
hdiutil: WARNING: 'hdiutil create -volname -format ...' is deprecated. ...
hdiutil: create failed - ファイルが存在します
$ echo $?
1

-ovを付けると、既存のdmgを上書きして作成する。dmgを作り直すスクリプトでは、-ovを付ける。

作成したdmgの中身を確認する

作成したdmgは、マウント(attach)すると、中身を確認できる。確認だけの場合は、読み取り専用(--readOnly)でマウントする。--mountOptions nobrowseを指定すると、マウントしたボリュームがGUIに表示されない。

$ diskutil image attach --mountOptions nobrowse --readOnly --mountPoint [マウントポイント] app.dmg
/dev/disk22  	GUID_partition_scheme
/dev/disk22s1	Apple_APFS
/dev/disk23  	Apple_APFS_Container
/dev/disk23s1	Apple_APFS_Volume    	[マウントポイント]

マウントポイントには、あらかじめ作成した空のディレクトリを指定する。省略すると、/Volumesの下にボリューム名でマウントされる。

マウントしたディレクトリの中を、lsで確認する。

$ ls -R [マウントポイント]
Demo.app

[マウントポイント]/Demo.app:
Contents

[マウントポイント]/Demo.app/Contents:
Info.plist
MacOS

Demo.appが、dmgのルートに入っている。dmgに入れたアプリの実行ファイルは、マウントしたdmgの中から実行できる。

$ [マウントポイント]/Demo.app/Contents/MacOS/Demo
hello app

確認が終わったら、diskutil ejectでマウントを解除する。

$ diskutil eject [マウントポイント]
Disk [マウントポイント] ejected

hdiutilでマウントする場合

hdiutil attachとhdiutil detachでも、dmgをマウントして解除できる。

$ hdiutil attach app.dmg -nobrowse -readonly -mountpoint [マウントポイント]
$ hdiutil detach [マウントポイント]

hdiutil attachは、チェックサムの検証の進捗を表示する。また、hdiutil createと同様に、非推奨の警告が表示される。警告は、diskutil image attachとdiskutil ejectへの移行を勧めている。

hdiutil: WARNING: 'hdiutil attach -nobrowse -readonly -mountpoint ...' is deprecated. Please use 'diskutil image attach --mountOptions nobrowse --readOnly --mountPoint ...' instead.
hdiutil: WARNING: 'hdiutil detach ...' is deprecated. Please use 'diskutil eject ...' instead.

作成されるdmgの形式とファイルシステム

形式を指定しない場合、dmgは読み取り専用の圧縮形式(UDZO)で作成される。hdiutil imageinfoで確認できる。

$ hdiutil imageinfo app.dmg | grep 'Format Description'
Format Description: UDIF読み出し専用圧縮(zlib)

macOS 27.0.1では、dmgの中のファイルシステムは、APFSだった。

$ diskutil info [マウントポイント] | grep 'File System Personality'
   File System Personality:   APFS

ボリュームの容量は、中身が小さくても、約10 MBになった。圧縮が効く中身では、dmgのファイルのサイズは、中身より小さくなる。

参考: 【hdiutil】dmgの圧縮形式を選ぶ

参考: 【hdiutil】dmgのファイルシステムを指定する

署名と公証

配布用のdmgは、作成したあとに、署名と公証が必要になる。署名と公証の手順は、別の記事で紹介している。

参考: 【notarytool】dmgを公証する (submit)