LoginSignup
24
26

More than 5 years have passed since last update.

XcodeでArchive以外のビルド結果にはbitcodeが埋め込まれない

Last updated at Posted at 2015-11-13

Xcode7以降では、ビルドしたオブジェクトにはデフォルトでbitcodeを埋め込むようになりました。

参考:Xcode7でのembed-bitcodeオプション
http://qiita.com/gamako/items/4ebfd048c5aed4f68595

、、、と思っていたら、どうやら必ずしもそうではないようです。

参考:Carthage と Bitcode 対応についてのまとめ
https://blog.ymyzk.com/2015/10/carthage-and-bitcode/

こちらによると、Archiveするとき以外はbitcodeは埋め込まれておらず、特にライブラリをビルドするときに困るとのことです。
そんな、、、、あんまりな仕様です。

実際に確認

簡単なプロジェクトで確認してみましょう。何も表示しない簡単なSwiftアプリを作ります。

% tree .
.
├── bcapp
│   ├── AppDelegate.swift
│   ├── Assets.xcassets
│   │   └── AppIcon.appiconset
│   │       └── Contents.json
│   ├── Base.lproj
│   │   ├── LaunchScreen.storyboard
│   │   └── Main.storyboard
│   ├── Info.plist
│   └── ViewController.swift
└── bcapp.xcodeproj

buildコマンドでのビルド

ビルドコマンドで実行して、ビルドレポート画面で出力ファイルのパスを確認します。otoolコマンドで中身を見てみましょう。

AppDelegate.swiftのコンパイル結果を確認します。確かにサイズが1しかありません。ほぼ空のようです。

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/bcapp.build/Debug-iphoneos/bcapp.build/Objects-normal/arm64/AppDelegate.o

...()

Section
  sectname __bitcode
   segname __LLVM
      addr 0x0000000000004f98
      size 0x0000000000000001 # <-----サイズが1
    offset 23872
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __swift_cmdline
   segname __LLVM
      addr 0x0000000000004f99
      size 0x0000000000000001 # <-----サイズが1
    offset 23873
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000

また、リンク結果のファイルをotoolで見てみると、LLVMのセクションすら含まれていません。

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/bcapp.build/Debug-iphoneos/bcapp.build/Objects-normal/arm64/bcapp | grep LLVM
%

Archiveでのビルド

一方でArchiveした結果のほうはどうかというと、こちらはbitcodeのセクションにはそれっぽいサイズのデータが入っているようです。

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/ArchiveIntermediates/bcapp/IntermediateBuildFilesPath/bcapp.build/Release-iphoneos/bcapp.build/Objects-normal/arm64/AppDelegate.o

... (中略)

Section
  sectname __bitcode
   segname __LLVM
      addr 0x0000000000005090
      size 0x00000000000085b0   #  <--- それっぽいサイズ
    offset 24056
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __swift_cmdline
   segname __LLVM
      addr 0x000000000000d640
      size 0x000000000000006b   #  <--- それっぽいサイズ
    offset 58280
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

リンクした結果にLLVM情報が含まれています。ただし、こちらは__bundleという名前のセクションで収められているようです。

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/ArchiveIntermediates/bcapp/IntermediateBuildFilesPath/bcapp.build/Release-iphoneos/bcapp.build/Objects-normal/arm64/bcapp

... (中略)

Load command 3
      cmd LC_SEGMENT_64
  cmdsize 152
  segname __LLVM
   vmaddr 0x000000010000c000
   vmsize 0x000000000000c000
  fileoff 49152
 filesize 49152
  maxprot 0x00000003
 initprot 0x00000003
   nsects 1
    flags 0x4
Section
  sectname __bundle
   segname __LLVM
      addr 0x000000010000c000
      size 0x00000000000083db
    offset 49152
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

__bundleを抜き出してみます。

% dd if=/Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/ArchiveIntermediates/bcapp/IntermediateBuildFilesPath/bcapp.build/Release-iphoneos/bcapp.build/Objects-normal/arm64/bcapp bs=1 skip=49152 count=0x83db of=bundle
33755+0 records in
33755+0 records out
33755 bytes transferred in 0.076648 secs (440390 bytes/sec)

bundleとはなんでしょうか?先頭をダンプしてみると、中身はxar形式のアーカイブのようです。

% hexdump -C -v -n 16 bundle
00000000  78 61 72 21 00 1c 00 01  00 00 00 00 00 00 03 ab  |xar!............|
00000010

xarコマンドで展開してみます。1、2というファイルが出てきました。

% xar -x -f bundle
% ls -al
total 144
drwxr-xr-x  5 gamako  staff    170 11 13 16:53 .
drwxr-xr-x  4 gamako  staff    136 11 13 16:24 ..
-rw-r--r--  1 gamako  staff   9568 11 13 16:53 1
-rw-r--r--  1 gamako  staff  22032 11 13 16:53 2
-rw-r--r--  1 gamako  staff  33755 11 13 16:49 bundle

1, 2はbitcodeのようなので、llvm-disコマンドでLLVM−IRとして出力します。
clangのサイトからダウンロードしてきた3.7.0のコマンドだと警告がでますが、変換できました。

% /Users/xxx/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/bin/llvm-dis 1
/Users/xxx/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/bin/llvm-dis: warning: ignoring debug info with an invalid version (700000003) in 1

% /Users/xxx/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/bin/llvm-dis 2
/Users/xxx/Downloads/clang+llvm-3.7.0-x86_64-apple-darwin/bin/llvm-dis: warning: ignoring debug info with an invalid version (700000003) in 2

llファイルの中身からクラス名を検索してみると、なんとなく 1がViewController.swiftで、2がAppDelegate.swiftに対応しているようです。

% grep AppDelegate *.ll
2.ll:@7 = private unnamed_addr constant [24 x i8] c"_TtC5bcapp11AppDelegate\00"
2.ll:@8 = private unnamed_addr constant [21 x i8] c"C5bcapp11AppDelegate\00"
2.ll:  br i1 %3, label %cacheIsNull.i, label %_TMaC5bcapp11AppDelegate.exit
2.ll:  br label %_TMaC5bcapp11AppDelegate.exit
2.ll:_TMaC5bcapp11AppDelegate.exit:                    ; preds = %cacheIsNull.i, %entry
2.ll:  br i1 %7, label %cacheIsNull.i, label %_TMaC5bcapp11AppDelegate.exit
2.ll:  br label %_TMaC5bcapp11AppDelegate.exit
2.ll:_TMaC5bcapp11AppDelegate.exit:                    ; preds = %cacheIsNull.i, %entry
2.ll:  br i1 %3, label %cacheIsNull.i, label %_TMaC5bcapp11AppDelegate.exit
2.ll:  br label %_TMaC5bcapp11AppDelegate.exit
2.ll:_TMaC5bcapp11AppDelegate.exit:                    ; preds = %cacheIsNull.i, %entry
2.ll:  br i1 %8, label %cacheIsNull.i, label %_TMaC5bcapp11AppDelegate.exit
2.ll:  br label %_TMaC5bcapp11AppDelegate.exit
2.ll:_TMaC5bcapp11AppDelegate.exit:                    ; preds = %cacheIsNull.i, %entry
2.ll:  br i1 %5, label %cacheIsNull.i, label %_TMaC5bcapp11AppDelegate.exit
2.ll:  br label %_TMaC5bcapp11AppDelegate.exit
2.ll:_TMaC5bcapp11AppDelegate.exit:                    ; preds = %cacheIsNull.i, %once_done
% grep ViewController *.ll
1.ll:@"__hidden#25_" = global %"__type_hidden#0" { %"__type_hidden#0"* @"OBJC_METACLASS_$_NSObject", %"__type_hidden#0"* @"OBJC_METACLASS_$_UIViewController", %"__type_hidden#1"* @_objc_empty_cache, %"__type_hidden#1"* null, i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, i8*, i8*, i8*, i8*, i8* }* @"__hidden#26_" to i64) }
1.ll:@"OBJC_CLASS_$_UIViewController" = external global %"__type_hidden#0"
1.ll:@"OBJC_METACLASS_$_UIViewController" = external global %"__type_hidden#0"
1.ll:@3 = private unnamed_addr constant [27 x i8] c"_TtC5bcapp14ViewController\00"
1.ll:@4 = private unnamed_addr constant [24 x i8] c"C5bcapp14ViewController\00"
1.ll:@"__hidden#35_" = internal global { void (%"__type_hidden#4"*)*, i8**, i64, %"__type_hidden#0"*, %"__type_hidden#1"*, %"__type_hidden#1"*, i64, i32, i32, i32, i16, i16, i32, i32, { i64, i8*, i32, i32, i8*, %"__type_hidden#2"** (%"__type_hidden#2"*)*, %"__type_hidden#3"*, i32, i32, i32 }*, void (%"__type_hidden#4"*)*, void (%"__type_hidden#4"*)*, %"__type_hidden#4"* (%"__type_hidden#6"*, i64, %"__type_hidden#4"*)*, i64 (%"__type_hidden#7"*, %"__type_hidden#2"*)*, i64 (%"__type_hidden#7"*, %"__type_hidden#4"*)* } { void (%"__type_hidden#4"*)* @"__hidden#5_", i8** @_TWVBO, i64 ptrtoint (%"__type_hidden#0"* @"__hidden#25_" to i64), %"__type_hidden#0"* @"OBJC_CLASS_$_UIViewController", %"__type_hidden#1"* @_objc_empty_cache, %"__type_hidden#1"* null, i64 add (i64 ptrtoint ({ i32, i32, i32, i32, i8*, i8*, { i32, i32, [4 x { i8*, i8*, i8* }] }*, i8*, i8*, i8*, i8* }* @"__hidden#28_" to i64), i64 1), i32 1, i32 0, i32 16, i16 7, i16 0, i32 128, i32 16, { i64, i8*, i32, i32, i8*, %"__type_hidden#2"** (%"__type_hidden#2"*)*, %"__type_hidden#3"*, i32, i32, i32 }* @"__hidden#29_", void (%"__type_hidden#4"*)* @"__hidden#0_", void (%"__type_hidden#4"*)* @"__hidden#3_", %"__type_hidden#4"* (%"__type_hidden#6"*, i64, %"__type_hidden#4"*)* @"__hidden#6_", i64 (%"__type_hidden#7"*, %"__type_hidden#2"*)* @"__hidden#9_", i64 (%"__type_hidden#7"*, %"__type_hidden#4"*)* @"__hidden#10_" }, section "__DATA,__objc_data, regular"
1.ll:  br i1 %3, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:  br i1 %4, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:  br i1 %3, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:  br i1 %4, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:  br i1 %3, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:  br i1 %23, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %20
1.ll:; <label>:39                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:; <label>:41                                      ; preds = %39, %_TMaC5bcapp14ViewController.exit
1.ll:  br i1 %16, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:; <label>:23                                      ; preds = %40, %_TMaC5bcapp14ViewController.exit
1.ll:  %24 = phi i64 [ %44, %40 ], [ 0, %_TMaC5bcapp14ViewController.exit ]
1.ll:; <label>:40                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:  br i1 %11, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %.thread
1.ll:; <label>:24                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:; <label>:25                                      ; preds = %24, %_TMaC5bcapp14ViewController.exit
1.ll:  br i1 %4, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:; <label>:18                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:; <label>:20                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:  br i1 %4, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
1.ll:; <label>:15                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:; <label>:18                                      ; preds = %_TMaC5bcapp14ViewController.exit
1.ll:  br i1 %6, label %cacheIsNull.i, label %_TMaC5bcapp14ViewController.exit
1.ll:  br label %_TMaC5bcapp14ViewController.exit
1.ll:_TMaC5bcapp14ViewController.exit:                 ; preds = %cacheIsNull.i, %entry
2.ll:@50 = private unnamed_addr constant [68 x i8] c"@\22UIViewController\2240@0:8@\22UIApplication\2216@\22NSArray\2224@\22NSCoder\2232\00"

Buildコマンドでもbitcodeを埋め込む

BITCODE_GENERATION_MODEという隠しオプションを使うと、Archive以外のビルドでもbitcodeの埋め込みができるようになるようです。埋め込みを常に行うためには、bitcodeという値をセットします。

bcapp.png

ビルド結果をotoolでみてみると、確かにbitcodeが含まれているようです。

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/bcapp.build/Debug-iphoneos/bcapp.build/Objects-normal/arm64/AppDelegate.o

...(中略)


Section
  sectname __bitcode
   segname __LLVM
      addr 0x0000000000004eb0
      size 0x00000000000082c0 # <-- それなりなサイズ
    offset 23640
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __swift_cmdline
   segname __LLVM
      addr 0x000000000000d170
      size 0x000000000000006f # <-- それなりなサイズ
    offset 57112
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

% otool -l /Users/xxx/Library/Developer/Xcode/DerivedData/bcapp-btzqjrrqxtscqgeypwmncboajrur/Build/Intermediates/bcapp.build/Debug-iphoneos/bcapp.build/Objects-normal/arm64/bcapp

...(中略)

Load command 3
      cmd LC_SEGMENT_64
  cmdsize 152
  segname __LLVM
   vmaddr 0x000000010000c000
   vmsize 0x000000000000c000
  fileoff 49152
 filesize 49152
  maxprot 0x00000003
 initprot 0x00000003
   nsects 1
    flags 0x4
Section
  sectname __bundle           # <-- Archiveと同じように__bundleが埋め込まれている
   segname __LLVM
      addr 0x000000010000c000
      size 0x00000000000083c9 # <-- それなりなサイズ
    offset 49152
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

中身までは確認しませんが、大丈夫そうですね^^

こちらからは以上です。

24
26
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
24
26