Apple Developer Connection
高度な検索
Member Login ログイン | ご入会 ADC連絡先

Technical Note TN2012
Building Universal QuickTime Components for Mac OS X

このテクニカルノートでは、Mac OS Xで動作するCarbon Mach-OのQuickTimeコンポーネントのビルドについてと、PowerPCベースのMacintoshとインテルベースのMacintoshの両方をサポートするUniversal Binaryコンポーネントをビルドするために、Component Managerのthing('thng')リソースを設定する方法を説明します。





バイナリフォーマット

Mac OS Xは、CFMとMach-Oの2つのアプリケーションバイナリフォーマットをサポートします。

Mach-Oは、Mac OS Xのネイティブなオブジェクトフォーマットで、gccコンパイラとXcodeによってサポートされています。

CFM(Code Fragment Manager)は、以前のMac OSが稼動するPower Macintoshコンピュータで使われていたレガシーフォーマットであり、Metrowerks CodeWarriorなどのコンパイラによってサポートされています。

Mac OS X用のCarbonコンポーネントは、Mach-OコードかCFMコードとしてビルドすることができますが、CFMの使用は現在は推奨されていません。さらに重要なことは、Mach-Oは、インテルベースのMacintosh上でネイティブに実行できる、唯一のバイナリフォーマットであるということです。

何か新しいコンポーネントをビルドする場合は、Xcodeの最新版(2.1以上)で作業を始めて、Universal Binaryコンポーネント(PowerPCベースのMacintoshとインテルベースのMacintoshの両方で実行が可能なコードを含んだ単一のコンポーネントバイナリ)をビルドします。古いコンポーネントをアップデートする場合は、まず、Xcodeの最新版に移行し、それから必要に応じてコンポーネントコードをアップデートする必要があります。Xcodeに移行するデベロッパ向けの各種ドキュメントのリンクについては、このドキュメントの最後にある「参考資料」のセクションを参照してください。

注: CodeWarriorには、Mach-Oバイナリをビルドする機能はありますが、PowerPCベースのMacintoshコンピュータとインテルベースのMacintoshコンピュータの両方でネイティブに実行できるUniversal Binaryはビルドできません。

先頭に戻る

Mach-Oコンポーネント

Mac OS X用のMach-Oコンポーネントは、データフォークにダイナミックライブラリ(dylib)を持ち、従来のMac OS用のメカニズムとよく似たメカニズムを使ってビルドされますが、以下の点が異なります。

  • エントリポイントは、Windowsの場合と同様のメカニズムを使って、シンボル名で検索されます。「コードのリソースタイプ」は'dlle'で、'dlle'リソースにはエクスポートされたシンボル名のC言語文字列が含まれます。リスト1を参照してください。

  • PowerPCベースのMacintosh用のコンポーネントをビルドしている場合、プラットフォームタイプはplatformPowerPCではなく、platformPowerPCNativeEntryPointにする必要があります。リスト2を参照してください。

  • インテルベースのMacintosh用のコンポーネントをビルドしている場合、プラットフォームタイプはplatformIA32NativeEntryPointにする必要があります。リスト3を参照してください。

リスト1: Mach-OとWindowsのエントリポイント

// PowerPCベースとインテルベースのMacとWindowsのコードエントリポイント
resource 'dlle' (256) {
    "MyComponentDispatch"
};

リスト2: Mach-O PowerPCベースのMacの'thng'リソース

// 拡張'thng'テンプレート
#define thng_RezTemplateVersion 1

#include <Carbon/Carbon.r>
#include <QuickTime/QuickTime.r>

resource 'thng' (256) { 
    kSomeComponentType, // タイプ
    'DEMO',             // サブタイプ
    'DEMO',             // 製造元
    0,                  // componentHasMultiplePlatformsを使用
    0, 
    0, 
    0, 
    'STR ',             // 名前のタイプ
    128,                // 名前ID 
    'STR ',             // Infoタイプ
    129,                // Info ID 
    0,                  // アイコンタイプ
    0,                  // アイコンID 
    kMyComponentVersion,  // バージョン
    componentHasMultiplePlatforms + // 登録フラグ
    myComponentRegistrationFlags, 
    0,                  // アイコンファミリのリソースID 
    { 
      kMyComponentFlags, 
      'dlle',           // エントリポイントはシンボル名'dlle'リソースで検索される
      256,              // 'dlle'リソースのID 
      platformPowerPCNativeEntryPoint, // アーキテクチャ
    };
};

リスト3: Mach-OインテルベースのMacの'thng'リソース

// 拡張'thng'テンプレート
#define thng_RezTemplateVersion 1

#include <Carbon/Carbon.r>
#include <QuickTime/QuickTime.r>

resource 'thng' (256) { 
    kSomeComponentType, // タイプ
    'DEMO',             // サブタイプ
    'DEMO',             // 製造元
    0,                  // componentHasMultiplePlatformsを使用
    0, 
    0, 
    0, 
    'STR ',             // 名前のタイプ
    128,                // 名前ID 
    'STR ',             // Infoタイプ
    129,                // Info ID 
    0,                  // アイコンタイプ
    0,                  // アイコンID 
    kMyComponentVersion,  // バージョン
    componentHasMultiplePlatforms + // 登録フラグ
    myComponentRegistrationFlags, 
    0,                  // アイコンファミリのリソースID 
    { 
      kMyComponentFlags, 
      'dlle',           // エントリポイントはシンボル名'dlle'リソースで検索される
      256,              // 'dlle'リソースのID 
      platformIA32NativeEntryPoint, // アーキテクチャ
    }; 
};

Universal Binaryコンポーネント

アーキテクチャ設定

ターゲットアーキテクチャの設定を、ppci386の両方をビルドするように設定し、SDKROOTを『Universal Binaryプログラミングガイド』に解説されているように設定すれば、Universal Binaryコンポーネントをビルドするための準備ができたことになります。図1を参照してください。

図1: Xcodeのアーキテクチャターゲット設定

図1 Xcodeのアーキテクチャターゲット設定

先頭に戻る

ComponentPlatformInfo

しかし、Component Managerはバイナリファイルのアーキテクチャではなく、コンポーネントの'thng'リソースを見て、QuickTimeコンポーネントがサポートするアーキテクチャを認識します。具体的には、'thng'リソース内のComponentPlatformInfo配列を調べます。

'thng'リソース内の「プラットフォーム」情報は、複数のComponentPlatformInfoエントリからなる配列であるため、複数のアーキテクチャをサポートする単一のコンポーネントを容易にビルドすることができます。従来のMac OSでは、68k/PPCの"FAT"コンポーネントはこの方法でビルドされており、このプラットフォーム配列の一部として、適切なアーキテクチャを指定する2つのエントリを含んでいました。

現在のMach-O Universal Binaryコンポーネントのビルドも同じで、リスト4に示すように、単にplatformPowerPCNativeEntryPointplatformIA32NativeEntryPointのアーキテクチャをComponentPlatformInfo配列に指定します。

リスト4: Universal Binaryコンポーネントの'thng'リソース

// File : My_Component.r

// 拡張'thng'テンプレート
#define thng_RezTemplateVersion 1

#if TARGET_REZ_CARBON_MACHO
    #include <Carbon/Carbon.r>
    #include <QuickTime/QuickTime.r>
#else
    #include "ConditionalMacros.r"
    #include "MacTypes.r"
    #include "Components.r"
    #include "QuickTimeComponents.r"
    #include "ImageCompression.r"
#endif

resource 'thng' (256) { 
    kSomeComponentType, // タイプ
    'DEMO',             // サブタイプ
    'DEMO',             // 製造元
    0,                  // componentHasMultiplePlatformsを使用
    0, 
    0, 
    0, 
    'STR ',             // 名前のタイプ
    128,                // 名前ID 
    'STR ',             // Infoタイプ
    129,                // Info ID 
    0,                  // アイコンタイプ
    0,                  // アイコンID 
    kMyComponentVersion,  // バージョン
    componentHasMultiplePlatforms + // 登録フラグ
    myComponentRegistrationFlags, 
    0,                  // アイコンファミリのリソースID
    { // コンポーネントのプラットフォーム情報 ---------------------- 
#if TARGET_OS_MAC
    #if TARGET_REZ_CARBON_MACHO
        #if !(TARGET_REZ_MAC_PPC || TARGET_REZ_MAC_X86)
            #error "Platform architecture not defined!"
        #endif
        #if TARGET_REZ_MAC_PPC
              kMyComponentFlags,
              'dlle',
              256,
              platformPowerPCNativeEntryPoint,  // PowerPCベースのMacintosh
        #endif
        #if TARGET_REZ_MAC_X86
              kMyComponentFlags,
              'dlle',
              256,
              platformIA32NativeEntryPoint,     // インテルベースのMacintosh
        #endif
    #else
        #error "TARGET_REZ_CARBON_MACHO should be defined."
    #endif
#elif TARGET_OS_WIN32
    #if TARGET_REZ_WIN32
        kMyComponentFlags,
        'dlle',
        256,
        platformWin32,
    #else
        #error "TARGET_REZ_WIN32 should be defined."
    #endif
#else
    #error "I have no idea what you're trying to do!"
#endif
    };
};

先頭に戻る

リソースファイル定義

コンポーネントリソースファイルをセットアップする簡単な方法の1つは、適切なTARGET_REZ_XXX_XXX識別子を定義するマスタリソース(.r)ファイルをインクルードし、次にこのマスタファイル内から、それ以外の個々のリソース(.r)ファイルをすべてインクルードします。図2を参照してください。

リスト5に、マスタリソースファイルの内容がどのようなものかを示します。このファイルがどのようにして適切な定義を設定し、My_Component.rというコンポーネントリソースファイルをインクルードしているかに注目してください。

図2: 単一のマスタリソースファイルの追加

図2 単一のマスタリソースファイルの追加

リスト5: マスタリソースファイル

// File : My_Component_MachO.r
//
//
// Mac OS X Mach-O Component: Set TARGET_REZ_CARBON_MACHO to 1
//
// In the target settings of your Xcode project, add one or both of the
// following defines to your OTHER_REZFLAGS depending on the type of component
// you want to build:
//
//      PPC only: -d ppc_$(ppc)
//      x86 only: -d i386_$(i386)
//      Universal Binary: -d ppc_$(ppc) -d i386_$(i386)
//
// Windows Component: Set TARGET_REZ_CARBON_MACHO to 0
// ---------------------------------------------------

// Set to 1 == building Mac OS X
#define TARGET_REZ_CARBON_MACHO 1

#if TARGET_REZ_CARBON_MACHO
    #if defined(ppc_YES)
        // PPCアーキテクチャ
        #define TARGET_REZ_MAC_PPC      1
    #else
        #define TARGET_REZ_MAC_PPC      0
    #endif

    #if defined(i386_YES)
        // x86アーキテクチャ
        #define TARGET_REZ_MAC_X86      1
    #else
        #define TARGET_REZ_MAC_X86      0
    #endif

    #define TARGET_REZ_WIN32 0
#else
    // Windows上でビルドしているはず
    #define TARGET_REZ_WIN32 1
#endif

// 個々のコンポーネントリソースファイルをインクルード
#include "My_Component.r"

先頭に戻る

その他のRezフラグ

My_Component_MachO.rは、ppc_YESi386_YESの一方または両方が定義されていることを前提としています。ビルドの対象とするターゲットアーキテクチャに応じて、一方または両方の定義を、ターゲットのOther Rez Flags (OTHER_REZFLAGS) Rez設定に追加します。

  • PPCの場合は-d ppc_$(ppc)

  • x86の場合は-d i386_$(i386)

  • 両方の場合は-d ppc_$(ppc) -d i386_$(i386)

図3: Rezの定義のセットアップ

図 3 Rezの定義のセットアップ

先頭に戻る

Resourcererツール

Mathemaesthetics, Inc.のResourcererは、QuickTimeコンポーネントデベロッパ向けの、優れたユーティリティです。これを使って、リソースの表示と編集や、'thng'リソースが正しいかどうかの素早い確認を行うことができます。図4に、ComponentPlatformInfo配列に2つのエントリがあるUniversal Binary設定でビルドされた'thng'リソースを示します。

図4: Resourcererで表示したUniversal Binaryコンポーネントの'thng'

図4 Resourcererで表示したUniversal Binaryコンポーネントの'thng'

先頭に戻る

バンドルコンポーネント

バンドルとは、関連のあるリソースを1つの場所に集めた、ファイルシステム上のディレクトリです。Xcodeでは、コンポーネントを、バンドルとしても単一ファイルのdylibとしてもビルドすることができます。しかし、QuickTimeコンポーネントは、Mac OS Xバンドルとしてビルドする必要があります。単一ファイルのMach-Oコンポーネントdylibのビルドは推奨されません。

単一ファイルのバイナリとして設定された古いコンポーネントがある場合は、ターゲットを更新し、コンポーネントバンドルをビルドする必要があります。さらに、古いツールを使用している場合は、Mach-Oバイナリのリソースフォークにリソースをビルドしないようにする必要があります。

コンポーネントバンドルをビルドするには、Xcodeの「New Project」ダイアログから「Carbon Bundle」を選択するか、または既存のXcodeプロジェクトにターゲットを追加している場合は「New Target」ダイアログから「Loadable Bundle」を選択します。

先頭に戻る

lipo

lipoコマンドは、Universal Binaryのビルドプロセスの中でXcodeによって使用され、Universal Binaryの作成と処理を行います。-detailed_infoオプションを使用することにより、lipoはUniversal Binaryファイルに組み込まれるアーキテクチャのリストを取得できます。リスト6を参照してください。

注: lipoコマンドの詳細情報を見るには、「ターミナル」アプリケーションでman lipoと入力してください。

リスト6: lipoを使用したUniversal Binaryについての情報の取得

toronto:~ ed$ lipo -detailed_info /ElectricImageUniversal.component/Contents/MacOS/ElectricImageUniversal

Fat header in: /ElectricImageUniversal.component/Contents/MacOS/ElectricImageUniversal
fat_magic 0xcafebabe
nfat_arch 2
architecture ppc
    cputype CPU_TYPE_POWERPC
    cpusubtype CPU_SUBTYPE_POWERPC_ALL
    offset 4096
    size 128176
    align 2^12 (4096)
architecture i386
    cputype CPU_TYPE_I386
    cpusubtype CPU_SUBTYPE_I386_ALL
    offset 135168
    size 132084
    align 2^12 (4096)

先頭に戻る

Rosetta

Rosettaは、PowerPCバイナリをインテルベースのMacintosh上で実行させる翻訳プロセスです。このテクノロジーにより、アプリケーションを非ネイティブバイナリとして実行することが可能になっています。しかしRosettaでは、ネイティブコードと翻訳されたコードを1つのプロセスに混在させることはできません。従来のMac OSの「Mixed Mode(混在モード)」テクノロジーに相当する機能は提供していません。

PowerPC専用のコンポーネントは、インテルベースのMacintoshでネイティブに実行するUniversal Binaryアプリケーションには読み込まれません。つまり、コンポーネントをUniversal Binaryとしてビルドする必要があります。そうしないとユーザは、ネイティブアプリケーション内で非ネイティブのコンポーネントを必要とするコンテンツを扱うことができなくなります。

逆に、Rosettaの下で実行しているアプリケーションは必ず、x86バージョンではなく、PowerPCバージョンのUniversal Binaryコンポーネントを読み込みます。つまり、メディア再生のパフォーマンスは、Universalでないアプリケーションでは制限される可能性があります。

重要: QuickTimeコンポーネントのデベロッパは、Universal Binaryバージョンのコンポーネントをビルドすることが推奨されます。これにより、期待されるタスクをネイティブアプリケーション内から実行する際に問題に直面するといった状況を回避することができます。

先頭に戻る

ファイルの拡張子と場所

コンポーネントファイルには、ファイル名拡張子「.component」を付け、「/Library/QuickTime」ディレクトリに置きます。

先頭に戻る

サンプルコード

Electric Image Component - このサンプルは、このドキュメントで概要を示したテクニックの実例で、5つのQuickTimeコンポーネント、すなわち、Graphics Importer、Graphics Exporter、Movie Importer、Movie Exporter、Image Decompressorのビルド方法を示します。これらのコンポーネントが連携して、Electric Image形式の画像ファイルをQuickTimeで扱えるようにします。

先頭に戻る

参考資料

先頭に戻る

ドキュメント改訂履歴

日付メモ
2005-07-21Tiger向けのアップデート。Universal Binaryの情報を追加。
2001-03-08新規ドキュメント

掲載日: 2005-07-21




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.