0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift PackageをZIP圧縮するときはswift package archive-source を使おう

Last updated at Posted at 2025-06-08

TL;DR

Swift Packageをzip -rで圧縮すると、解凍後にビルドエラーが発生することがあります。
swift package archive-sourceコマンドを使うとシンボリックリンクが正しく保持されたり、.buildディレクトリも自動的に除外されるなど、配布に適した形で圧縮されるためおすすめです。

cd swift-package-directory
swift package archive-source --output output/path/package-name.zip

はじめに

Swift Packageの配布や移動のためにZIP圧縮することは珍しくありませんが、通常のzipコマンドを使うと思わぬビルドエラーに遭遇することがあります。本記事では、realm-swiftを例にその原因と解決法を解説します。

通常のZIP圧縮を使うとどうなる?

例として、realm-swiftをZIP圧縮・解凍してビルドしてみます。

git clone https://github.com/realm/realm-swift.git && cd realm-swift
swift build
...
Build complete! (70.11s)

もちろん、クローン時点ではswift buildは成功します。
では、続けてrealm-swiftを一度ZIP圧縮・解凍してビルドしてみます。

zip -r realm-swift.zip realm-swift # 圧縮
rm -rf realm-swift # 元のディレクトリを削除
unzip realm-swift.zip && cd realm-swift # 解凍
swift build 
...
realm-swift/Realm/RLMNetworkTransport.h:24:34: error: redefinition of 'RLMHTTPMethod'
   24 | typedef RLM_CLOSED_ENUM(int32_t, RLMHTTPMethod) {
      |                                  ^  
...
fatal error: too many errors emitted, stopping now [-ferror-limit=]
2 warnings and 20 errors generated.
[34/309] Compiling timestamp_logger.cpp

はい、ビルドに失敗しました。

原因はシンボリックリンクの消失

解凍後にgit statusでリポジトリの状態を確認すると、いつのまにか差分が出ていることがわかります。

git status

On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	typechange: Realm/ObjectServerTests/include/RLMSyncTestCase.h
	typechange: Realm/ObjectServerTests/include/RLMUser+ObjectServerTests.h
	typechange: Realm/Tests/Swift/RLMSupport.swift
	typechange: RealmSwift/RealmSwift-Info.plist
	typechange: RealmSwift/Tests/RealmSwiftTests-Info.plist
	...
	typechange: include/Realm/RLMNetworkTransport.h
	...

no changes added to commit (use "git add" and/or "git commit -a")

typechangeとはなんでしょうか。
こちらのQiita記事によると、ファイルの種類が変更されたことを示しており、通常はシンボリックリンクが通常ファイルに変わったり、その逆の場合に発生します。

今回エラーの原因となったファイル
https://github.com/realm/realm-swift/blob/master/include/Realm/RLMNetworkTransport.h
の中身は、

../../Realm/RLMNetworkTransport.h

となっており、もともとシンボリックリンクだったことがわかります。

realm-swiftのような複雑なライブラリでは、ヘッダーファイルの重複を避けるためにシンボリックリンクが使用されることがあります。zipコマンドはデフォルトでシンボリックリンクを実ファイルに展開してしまうため:

  1. 同じ内容のファイルが複数箇所に実体として配置される
  2. C/C++コンパイラが重複定義エラー(redefinition error)を報告する
  3. ビルドが失敗する

ような事態が発生してしまったようです。

もちろん、すべてのSwift Packageがシンボリックリンクを使っているわけではないので、ビルドエラーが必ず起きるわけではないです。
ただ、あらかじめ予防できるのであればそれに越したことはないでしょう。

解決策 swift package archive-sourceの使用

そこでタイトルに戻りますが、ZIP圧縮する際は、swift package archive-sourceを使うとシンボリックリンクが正しく保持されるため、先ほどのようなビルドエラーを避けることができます。
さらには、.buildディレクトリなどの再配布に不必要なファイルも自動的に除外されます。

swift package archive-source -h
OVERVIEW: Create a source archive for the package

USAGE: swift package archive-source [--output <output>]

OPTIONS:
  -o, --output <output>   The absolute or relative path for the generated source archive
  --version               Show the version.
  -h, -help, --help       Show help information.

では、swift package archive-sourceを使ってrealm-swiftをZIP圧縮して解凍してビルドしてみます。

swift package archive-source --output ../realm-swift.zip
cd .. && rm -rf realm-swift # 元のディレクトリを削除
unzip realm-swift.zip && cd realm-swift # 解凍
swift build
...
Build complete! (75.28s)

無事にビルドが成功しました。

ちなみにrealm-swiftの場合、除外されたファイルは以下の通りでした。

  • .git
  • .build
  • .swiftpm

代替策 zip -yオプション

ちなみに、今のディレクトリをありのままの状態でZIP圧縮したい場合は、以下のように-yオプションを使えばシンボリックリンクを保持したまま圧縮できるため、先の例のようなビルドエラーを避けつつ、zipコマンドを使うこともできます。

zip -r -y realm-swift.zip realm-swift
# -y オプション:  store symbolic links as the link instead of the referenced file
# 訳: シンボリックリンクを参照先のファイルではなく、リンクとして保存する

まとめ

swift package archive-sourceを使うことで、シンボリックリンクの問題を回避しつつ、再配布に適した形でSwift PackageをZIP圧縮できることがわかりました。
Swift PackageをZIP圧縮する際は、ぜひswift package archive-sourceを使うことをおすすめします。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?