1

autotools を使用して OS X でビルドしているプロジェクトがあります。ユニバーサル バイナリをビルドしたいのですが、複数の-archオプションを gcc (automake が依存関係の追跡に使用) とOBJCFLAGS競合するようにします。-Mいくつかの回避策がありますが、どれも簡単ではないようです。

前処理を強制的にコンパイルから分離する方法はありますか (そのため、-M が に渡されCPP、-arch が に渡されOBJCます)。

automake は、依存関係の追跡を無効にするオプションと、副作用として実行できない場合に有効にするオプションをサポートしていることがわかります。副作用ベースの追跡が利用可能な場合でも、古いスタイルの追跡を強制的に使用する方法はありますか?

の経験はありませんlipo。それをautotoolsワークフローに結び付ける良い方法はありますか?

4

2 に答える 2

2

ここにはいくつかの解決策があります。そしておそらく私を回避した人。

  1. 最も簡単で最速の方法は、--disable-dependency-tracking./configure の実行に追加することです。

    これにより、依存関係をまったく生成しないように指示されます。依存関係フェーズは、コード生成中に -M 依存関係オプションが使用されているため、あなたを殺しているものです。複数のアーキテクチャがターゲットになっている場合、これは実行できません。

    したがって、他の人のパッケージでクリーン ビルドを行っている場合は、これで問題ありません。または、各ビルドの前に「クリーンにする」ことを気にしません。ソース、特にヘッダー ファイルをハッキングしている場合、これは良くありません。おそらく、make は何を再構築すればよいかわからず、古いバイナリが残るからです。

  2. より良いですが、より危険なのは次のようなことです:

    CC=clang CXX=clang++ ./configure

    これにより、gcc の代わりにコンパイラが clang になります。最近の Xcode をお持ちの場合は、clang があります。configure は、clang がコンパイル要件を満たしていることを認識しますが、自動依存関係の生成には安全ではないと判断します。自動依存性生成を無効にする代わりに、古いスタイルの 2 パス生成を行います。

    1 つの注意点: アーキテクチャ フラグの設定方法によっては、説明したように機能する場合と機能しない場合があります。すべてのコンパイラ呼び出しに渡したいフラグがある場合 (つまり、インクルード パスの場合は -I)、CPPFLAGS を設定する必要があります。コード生成のために、C および C++ の場合は CFLAGS および CXXFLAGS を設定します (ObjC の場合は COBJFLAGS を想定しています)。通常、それらに $CPPFLAGS を追加します。私は通常、次のようなシェルスクリプトを作成します。

    #!/bin/bash
    
    export CC=clang
    export CXX=clang
    
    export CPPFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -fvisibility=hidden"
    export CFLAGS="-arch i386 -arch x86_64 -O3 -fomit-frame-pointer -momit-leaf-frame-pointer -ffast-math $CPPFLAGS"
    export CXXFLAGS=$CFLAGS
    
    ./configure
    

    おそらくこれらの正確なフラグは必要ありませんが、アイデアが得られるはずです。

  3. リポ。あなたはこの道を進んできたようですね。私が見つけた最良の方法は次のとおりです。

    を。.X86_64とのような最上位ディレクトリを作成し.i386ます。「.」に注意してください。前に。ビルドのターゲットをソース ディレクトリにする場合は、後で「クリーンにする」作業を避けるために、通常はドットで始める必要があります。

    b. --prefix=`pwd`/.i386` のようなもので ./configure を実行しますが、アーキテクチャを設定します (この場合は i386 に)。

    c. make を実行make installし、すべてがうまくいったと仮定して、 アーキテクチャごとmake cleanに繰り返します。再構成によってクリーンアップされるものが変更される可能性があり、古いアーキテクチャ ファイルでアーキテクチャを汚染しないようにする必要があるため、各フェーズの最後は非常に重要です.i386make clean

    d. すべてのビルドが思い通りにできていると仮定すると、私は通常、このような見た目と感じのシェル スクリプトを作成して、最後に実行し、リポを行います。

    # move the working builds for posterity and debugging
    mv .i386 ./Build/i386
    mv .x86_64 ./Build/x86_64
    
    for path in ./Build/i386/lib/*
    do
        file=${path##*/}
        # only convert 'real' files                                                                                                   
        if [ -f "$file" -a ! -L "$file" ]; then
            partner="./Build/x86_64/Lib/$file"
            if [ -f $partner -a ! -L $partner ]; then
                target="./Build/Lib/$file"
                lipo -create "$file" "$partner" -output "$target" || { echo "Lipo failed to get phat"; exit 5; }
                echo Universal Binary Created: $target
            else
                echo Skipping: $file, no valid architecture pairing at: $partner
            fi
        else
            # this is a pretty common case, openssl creates symlinks                                                                  
            # echo Skipping: $file, NOT a regular file                                                                                
            true
        fi
    done
    
  4. 私が理解していないのは、gcc と古い学校の 2-pass dep gen を使用できるようにする魔法です。率直に言って、clang/llvm にますます感銘を受けるにつれて、私は毎日ますます気にしなくなりました。

幸運を!

于 2012-02-17T19:34:30.767 に答える
2

このApple Technical Noteは有望に見えますが、私はまだ行っていません。リリースを準備するときにユニバーサルビルドを行うだけでよいと思いますので、おそらく依存関係の追跡なしで行うことができますか?

于 2011-05-26T12:10:48.447 に答える