2

私はQtに基づく巨大なプロジェクトに取り組んでいます。これは、6コアのマシンでもコンパイルするのに数時間かかります。

これは、コアの1つだけを実行makeすると、ソースをコンパイルするためです。他のコアはアイドル状態のままです。

解決策は、私のマシンの6つのコアすべてを使用してmake-jオプション(のようなもの)で実行することです。make -j6

これに伴う問題はmake、再帰でスポーンしないことです。

例えば:

A、B、C、Dの4つのモジュールがあります。-DはA、B、Cに依存します。-BはAに依存します。-Cはシステムライブラリのみに依存します。-Aはシステムライブラリのみに依存します。

アプリは、上記qmakeの各モジュールのMakefileと、すべてのモジュールをコンパイルするための1つのMakefileを生成しました。

を実行するmake -j6と、6つのジョブが1つずつコンパイルするのではなく、すべてのモジュールのコンパイルを開始します。モジュールDを他のモジュールに対してリンクする必要がある場合、それらのモジュールの準備ができておらず、not foundエラーがスローされる可能性があるため、この動作は問題です。

オプションでこの動作を変更することは可能makeですか?これはソフトウェアエンジニアリングの問題かもしれません(モジュールはうまく投影されていません)?

4

3 に答える 3

1

再帰的なmake呼び出しの間に依存関係が欠落しているようです。再帰的なmakeを呼び出すトップレベルのmakefileは表示されていませんが、次のようになっていると思います。

all: A B C D

A B C D:
    $(MAKE) -C $@

これを修正するには、再帰的なmake間に必要な依存関係を追加します。

all: A B C D

A B C D:
    $(MAKE) -C $@

B: A

D: A B C

この戦略により、正しい並列ビルドが得られますが、パフォーマンスは多少犠牲になります。これらのサブメイク間で安全に並列化できる作業はたくさんあり、1つまたは1つだけのためにすべてをシリアル化するのは残念です。それぞれに2つのコマンドがあり、実際にシリアル化する必要があります。より良い解決策は、makefileのより深刻なリファクタリングを必要とする非再帰makeを使用するか、makefileをまったく変更せずに(追加することなく)この問題を解決できるElectricMakeを使用することです。追加の依存関係)。ElectricMakeが再帰的なmakeを修正する方法についてブログに書いています。

(免責事項:私はElectric Makeのアーキテクトです)

于 2012-12-25T19:48:18.520 に答える
1

makeppでビルドしてみてください。これにより、makefileが最初からきれいに設計されているかのように、サブmakeのターゲットをメインプロセスにパイプで戻すことにより、再帰を解明します(Recursive Make Thought Harmfulを参照)。

次に、ディレクトリレベルで抽象的にではなく、ディレクトリツリー全体の実際のファイルごとの依存関係にドリルダウンすることにより、通常の依存関係分析を実行します。したがって、安全に可能な最大値を並列化できます。

実際、cmakeがmakefileを生成する理由はわかりません...彼らが行うのは、cmakeを呼び出してmakeの背後にあるすべてのことを実行することだけです。そのため、makeppには、監視を行う依存関係に対して、無限の再帰を回避するためのcmakeの特別な処理があります。現在、qmakeは正確にはcmakeではありません。動作するのに十分近いかどうかを聞いて、うれしく思います。

于 2012-12-29T22:12:47.470 に答える
0

私はついにこれを自動的に行う方法を発見しましたqmake

これ以上簡単なことはありません。ファイルに追加CONFIG += orderedするだけで、すべてが機能します。.proこのフラグの詳細については、qmake変数リファレンスを参照してください。

これはプロジェクトテンプレートでのみ機能することに注意してください。ただしsubdirs、並列コンパイルは異なるバイナリ間に依存関係がある場合にのみ問題になるため、これは問題ではありません。

例:

# ABC.pro

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \
    A \
    B \
    C
于 2014-06-02T03:05:01.850 に答える