JPMartha's Pancake

This blog is the way to brush up my poor English.

ワークスペースでのビルドとプロジェクトでのビルドの違い ?

すごくしょうもないことですが 土日にハマり続けたのがくやしくて 記録しておきます。?

前提

  • 作成中の 自作ツール での話です。
    • Pancake.xcworkspace
      • Pancake.xcodeproj
      • DemoKit.xcodeproj
      • Commandant.xcodeproj
      • Himotoki.xcodeproj
      • Result.xcodeproj
      • sourcekitten.xcodeproj
      • SWXMLHash.xcodeproj

github.com

ハマった経緯

次の 2 通りの方法を並行して使用していました。

  1. Xcodeワークスペース(Pancake.xcworkspace)を開いてビルド

  2. xcodebuild コマンドでビルド*1

$ xcodebuild -target pancake -configuration Release

それぞれ結果が異なりますが、同じことを実行していたつもりだったのでハマり続けました。

違い(雑)

  1. ワークスペース(Pancake.xcworkspace)をビルドします。
  2. プロジェクト(Pancake.xcodeproj)をビルドします。

比較

このままではくやしいのでざっと比較しました。

Build Settings の比較

ワークスペース

スキームを指定して Build Settings をファイルに出力しました。*2

$ xcodebuild -workspace Pancake.xcworkspace -scheme pancake -configuration Release -showBuildSettings > WorkspaceBuild.txt
プロジェクト

ターゲットを指定して Build Settings をファイルに出力しました。

$ xcodebuild -target pancake -configuration Release -showBuildSettings > ProjectBuild.txt
差分

差分をファイルに出力しました。

$ diff WorkspaceBuild.txt ProjectBuild.txt > DiffPancake.txt

?

DerivedData の下のフォルダが異なるだけでそれ以外は同じ設定です。

25,26c25,26
<     BUILD_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products
<     BUILD_ROOT = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products
---
>     BUILD_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products
>     BUILD_ROOT = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products
29c29
<     BUILT_PRODUCTS_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release
---
>     BUILT_PRODUCTS_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release
54c54
<     CLASS_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/JavaClasses
---
>     CLASS_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/JavaClasses
57c57
<     CODESIGNING_FOLDER_PATH = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release/pancake.app
---
>     CODESIGNING_FOLDER_PATH = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release/pancake.app
63,64c63,64
<     CONFIGURATION_BUILD_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release
<     CONFIGURATION_TEMP_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release
---
>     CONFIGURATION_BUILD_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release
>     CONFIGURATION_TEMP_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release
86,88c86,88
<     DERIVED_FILES_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
<     DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
<     DERIVED_SOURCES_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
---
>     DERIVED_FILES_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
>     DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
>     DERIVED_SOURCES_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/DerivedSources
105c105
<     DWARF_DSYM_FOLDER_PATH = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release
---
>     DWARF_DSYM_FOLDER_PATH = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release
124,125c124,125
<     FILE_LIST = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects/LinkFileList
<     FIXED_FILES_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/FixedFiles
---
>     FILE_LIST = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects/LinkFileList
>     FIXED_FILES_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/FixedFiles
203c203
<     LD_DEPENDENCY_INFO_FILE = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects-normal/x86_64/pancake_dependency_info.dat
---
>     LD_DEPENDENCY_INFO_FILE = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects-normal/x86_64/pancake_dependency_info.dat
205c205
<     LD_MAP_FILE_PATH = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/pancake-LinkMap-normal-x86_64.txt
---
>     LD_MAP_FILE_PATH = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/pancake-LinkMap-normal-x86_64.txt
239,241c239,241
<     OBJECT_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects
<     OBJECT_FILE_DIR_normal = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects-normal
<     OBJROOT = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates
---
>     OBJECT_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects
>     OBJECT_FILE_DIR_normal = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/Objects-normal
>     OBJROOT = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates
251c251
<     PKGINFO_FILE_PATH = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/PkgInfo
---
>     PKGINFO_FILE_PATH = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/PkgInfo
267c267
<     PRECOMP_DESTINATION_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/PrefixHeaders
---
>     PRECOMP_DESTINATION_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/PrefixHeaders
277c277
<     PROJECT_DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/DerivedSources
---
>     PROJECT_DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/DerivedSources
281,282c281,282
<     PROJECT_TEMP_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build
<     PROJECT_TEMP_ROOT = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates
---
>     PROJECT_TEMP_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build
>     PROJECT_TEMP_ROOT = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates
290,291c290,291
<     REZ_COLLECTOR_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/ResourceManagerResources
<     REZ_OBJECTS_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build/ResourceManagerResources/Objects
---
>     REZ_COLLECTOR_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/ResourceManagerResources
>     REZ_OBJECTS_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build/ResourceManagerResources/Objects
311c311
<     SHARED_DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release/DerivedSources
---
>     SHARED_DERIVED_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release/DerivedSources
313c313
<     SHARED_PRECOMPS_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/PrecompiledHeaders
---
>     SHARED_PRECOMPS_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/PrecompiledHeaders
326c326
<     SYMROOT = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products
---
>     SYMROOT = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products
349c349
<     TARGET_BUILD_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Products/Release
---
>     TARGET_BUILD_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Products/Release
351,355c351,355
<     TARGET_TEMP_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build
<     TEMP_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build
<     TEMP_FILES_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build
<     TEMP_FILE_DIR = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates/Pancake.build/Release/pancake.build
<     TEMP_ROOT = /.../DerivedData/Pancake-...(ワークスペース).../Build/Intermediates
---
>     TARGET_TEMP_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build
>     TEMP_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build
>     TEMP_FILES_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build
>     TEMP_FILE_DIR = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates/Pancake.build/Release/pancake.build
>     TEMP_ROOT = /.../DerivedData/Pancake-...(プロジェクト).../Build/Intermediates

ビルドでの生成物の比較

それぞれのフォルダで次のコマンドを実行しました。

$ ls -1FR
ワークスペース

多いので一部のみ抜粋します。

  • フォルダ直下

Build/

FindHistory.xcfind ? ?

Index/

Logs/

TextIndex/

info.plist

cm.plist

  • ./Build/Intermediates:

ArchiveIntermediates/

Commandant.build/

DemoApp.build/

DemoKit.build/

Himotoki.build/

Pancake.build/

PancakeKit.build/

Result.build/

SWXMLHash.build/

sourcekitten.build/

  • ./Build/Products/Release:

Commandant.framework/

Commandant.framework.dSYM/

Himotoki.framework/

Himotoki.framework.dSYM/

PancakeKit.framework/

PancakeKit.framework.dSYM/

Result.framework/

Result.framework.dSYM/

SWXMLHash.framework/

SWXMLHash.framework.dSYM/

SourceKittenFramework.framework/

SourceKittenFramework.framework.dSYM/

pancake*

pancake.app/

pancake.app.dSYM/

pancake.swiftmodule/

プロジェクト

ビルドが失敗しているので完全ではありません。

  • フォルダ直下

Build/

Index/

Logs/

TextIndex/

info.plist

scm.plist

  • ./Build/Intermediates:

Pancake.build/

  • ./Build/Products/Release:

PancakeKit.framework/

違いは明らかですね。特にワークスペースでビルドしたときに生成される FindHistory.xcfind が気になる ところですが今日はもう限界です ?

$ file FindHistory.xcfind

?

FindHistory.xcfind: Apple binary property list

? 追記 ?

xcodebuild コマンドでプロジェクトをビルドするとプロジェクトフォルダ直下に build フォルダが生成されます。

Xcode でビルドしたとき /.../DerivedData/Pancake-...(プロジェクト).../Build に生成される構成と似ています。

多いので一部のみ抜粋します。

  • ./build:

Pancake.build/

Release/

  • ./build/Pancake.build:

Release/

all-product-headers.yaml

  • ./build/Pancake.build/Release:

PancakeKit.build/

pancake.build/

  • ./build/Release:

PancakeKit.framework/

PancakeKit.framework.dSYM/

pancake.app/

補足

プロジェクトのビルド失敗理由

SourceKittenFramework ? そんなもんねーよ!です。

たしかにありません。

error: no such module 'SourceKittenFramework'
import SourceKittenFramework
       ^

** BUILD FAILED **


The following build commands failed:
    CompileSwift normal x86_64
    CompileSwiftSources normal x86_64 com.apple.xcode.tools.swift.compiler
(2 failures)

xcodebuild コマンド

  • プロジェクトもワークスペースも指定しない場合はフォルダ直下のプロジェクトがビルドされます。

To build an Xcode project, run xcodebuild from the directory containing your project (i.e. the directory containing the projectname.xcodeproj package). If you have multiple projects in the this directory you will need to use -project to indicate which project should be built. By default, xcodebuild builds the first target listed in the project, with the default build configuration. The order of the targets is a property of the project and is the same for all users of the project.

xcodebuild(1) Mac OS X Developer Tools Manual Page

To build an Xcode workspace, you must pass both the -workspace and -scheme options to define the build.

xcodebuild(1) Mac OS X Developer Tools Manual Page


エラーメッセージ

xcodebuild: error: You cannot specify targets with a workspace.

xcodebuild: error: If you specify a workspace then you must also specify a scheme. Use -list to see the schemes in this workspace.

参考

*1:プロジェクトもワークスペースも指定しない場合はフォルダ直下のプロジェクトがビルドされます。

*2:ワークスペースをビルドするにはスキームを指定する必要があります。