問題タブ [parallel-builds]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - C プログラムの並行ビルド
*.c
多くのユニットファイルで構成される中規模のプロジェクトがあります。
「通常の」コンパイルでは、プログラムは、レシピ*.o
でメイン プログラムの前提条件として渡されるオブジェクト ファイルから構築されます。Makefile
これは、並列ビルドに適しています。 を使用するとmake -j
、これらすべてのオブジェクト ファイルが並列にコンパイルされ、最後にリンクされます。これにより、ビルド全体のエクスペリエンスが大幅に高速化されます。
ただし、それ以外の場合、前提条件のリストは、オブジェクト ファイルではなく*.c
、ユニット ファイルのリストとして渡されます。当初の意図は、キャッシュを汚染する可能性があるため、これらのオブジェクト ファイルを構築しないことです。さて、これはおそらく別の方法で行うことができますが、この特定のプロジェクトでは、は不変オブジェクトであるため、更新できず、それと一緒に暮らす必要があります。 *.o
Makefile
この場合、単一のコマンドラインでユニットの完全なリストを直接受け取るため、 を使用しても効果的ではありませんmake -j
。つまり、並列処理を整理できなくなりました。gcc
make
私に残された唯一の機会は、フラグとパラメータを に渡すことmake
です。gcc
内部でユニットのリストを並行してコンパイルするものを見つけようとしていました。何も見つかりませんでした。make
インターネットで検索すると、「並列ビルドができるので、gcc
この機能を複製する必要はない」という推測が見つかりました。しかし、解決策はありません。
問題は、それをどのように処理するかです。
標準フラグ ( 、、、 )gcc *.c -o final_exe
を介して変更できるのようなコンパイル行を想定すると、これらのユニットを並行して構築するために使用できるオプションはありますか?CC
CFLAGS
CPPFLAGS
LDFLAGS
cmake - 並列モードで複数回生成された ADD_CUSTOM_TARGET() で作成された cmake ターゲット
最初にツールを作成するプロジェクト名libtldがあります¹:
次に、そのツールを使用してtld_data.c
、すべての TLD を含むテーブルであるファイルを生成します (ライブラリの新しいバージョンでは、これは、フォールバックとして内部でコンパイルされる RIFF/TLDS バイナリ ファイルのコピーです)。add_custom_command()
上記のファイルを生成するために使用するのは次のとおりです。
次に、tld の動的ライブラリと静的ライブラリを生成します。
add_dependencies()
私はtld_static
プロジェクトにを追加してtld
、私のケースに役立つと考えていますが、まだ 2 つの実行が表示されtld_parser
ます ...
また、ファイルを直接インクルードするテストも行いました(そうすれば、関数が正確なソース データから期待されるものを返すことをtld_data.c
直接確認できます)。tld()
add_dependencies()
をテストに追加すると、期待どおりに機能しました。tld_data.c
ファイルを 3 回作成する代わりに、 2 回だけになりました。
並列ビルド機能を無効にすることで、期待どおりに機能しますが、そうする正当な理由はないはずです (この cmake の質問を参照してください)。
しかし、私が疑問に思っているのは次のとおりです。
このような問題をどのようにデバッグしますか?
cmake の Makefile は巨大なので、それらを読むのは非常にキラーです。何を検索すればよいかがわかっていれば、そこで起こっていることすべてを理解しようとするのではなく、少なくとも特定のターゲットを見ることができると思います (そのほとんどは私の問題とは関係ありません)。
¹ 現在、コードはブランチにあります。メインブランチを置き換える時点で、すぐにすべてをまとめたいと思っています。関数インターフェイスはtld()
あまり変更されていません。ただし、実装はまったく異なり、より柔軟で、動的に更新可能です。