ライブラリにリンクする代わりに、ライブラリのソースを追加する必要がありますか?


14

私は比較的C ++に慣れていないため、小さな依存関係(スクリプト言語、JSON / YAML / XMLパーサーなど)をどのように処理するのが最適かはわかりません。

個別のプロジェクトを作成して静的ライブラリとしてリンクする必要がありますか、それとも.h / .cppファイルをメインプロジェクトに配置するだけの欠点がありますか?

後者は、互換性のないライブラリ(ライブラリをビルドするときに異なるコンパイラ設定)を扱うのに数時間費やしたため、はるかに簡単に思えますが、C ++を間違った方法で学習し始めたくありません。

それらを個別のライブラリとして保持することが望ましい場合、.lib / .aファイルがアプリケーションに正常にリンクされるように、コンパイルフラグを同期させるにはどうすればよいでしょうか?

(私は現在MSVC 2015で作業していますが、目標はXCode / clangを使用してMac OS XおよびiOSでコンパイルすることです。そのため、少なくとも3つの異なるタイプのライブラリ(Win x86、Mac x64、ARM)に対処する必要があります)


5
ABIssをじっと見つめると、彼らはあなたを見ます
バシレフ

1
一部のライブラリはこの方法で使用すること意図していることに注意してください。SQLiteのライブラリの好ましい使用パターンは、実行可能ファイルにコンパイルするCまたはC ++アプリケーションのソースツリーにアマルガムソースおよびヘッダファイルをドロップすることです。
マークベニングフィールド

回答:


6

TLDR;

ソース追加する必要がありますか?はいXはソースを追加する
必要がありますか?依存する

ここに理由があります...

当時、コンパイル時間はさらに小さなプロジェクトが抱えていた問題でした。ソースをコンパイルし、コンパイラの結果をキャッシュすることを心配しないことは、間違いなく魅力的でした。それはあなたにとって関係のないライブラリにとって一つのポイントです。

別の重要なものはバージョン管理です。各ライブラリを個別にバージョン管理する必要が本当にありますか?それぞれに対してテストを実行しますか?多くのチームメンバーに配布しますか?あなたがそうするならば、図書館は素晴らしいです、そして、動き回るのは便利ですが、再び、あなたもこれを気にしないようです。

最後のポイントは、追加のオーバーヘッドであり、ソースファイルをドロップする方が簡単な場合です。これは、ライブラリを使用するのではなく、ソースをドロップすることの非常に強力なポイントになります。お気づきのとおり、コンパイラーの設定を1回変更したら、依存関係をすべて追跡する必要があります。

私は経験からこれをすべて知っています:

Swiftプロジェクトでは、Xcodeを使用して簡単に設定できるため、フレームワーク(ライブラリ)を使用し、それらに対してリンクします。また、バージョン管理、テスト、およびデカップリングが本当に必要なので、それが理由です。

モノ(C#)プロジェクトの場合、Unityの場合、プロジェクトをライブラリに分割し、各プロジェクトをコンパイルおよびテストするというヒップなアプローチから始めました。 、Mono Unityのハッキングされたバージョンから、プラットフォームを変更するときにコードが示す動作が異なる場合があります。すべてのライブラリを管理するためにここに単一のIDEを持たないことは本当の苦痛でした。そのため、すべてのソースをUnity内に置くことは生産性にとって大きな勝利でした。

最後に、あなたに最も関係のある、私が取り組んだC ++ゲームプロジェクト。ゲームエンジン、ネットワークリアルタイムクライアント、ネットワークHTTPクライアント、AI、および永続ストアは、このゲーム用にクライアント側で作成されました。何を選びましたか?CLion +ライブラリ。ライブラリを使用していたとしても、私はそうではありませんでした。すべてのソースはCLion IDEプロジェクトにあり、CMakeListを作成することで、すべてのビルドをトリガーし、それらを1回のストロークでリンクすることができました。

結論として、ライブラリの使用は将来性のあるソリューションですが、必要でない場合は時期尚早な最適化でもあります。あなたの状況から確認できる限り、MSVCからXcodeへの切り替えは、複数のビルドターゲットを使用する場合に苦痛になります。そのため、ライブラリを使用する必要ある場合に備えて、できるだけドロップインして、可能な限り分離を維持してください。

PS:最近、ドッカーと同様のジレンマを抱えています。作曲すべきですか?ローカルで実行する必要がありますか?..など。Elixirも、同じアプリケーション内でアプリケーションを構築できるためです。または、アプリをいわゆるマイクロサービスに分離しますか?...など。YMMVのように、常に自分自身を測定する特効薬はありません。


2

C ++ライブラリとのリンクには多くの手間が必要であり、それを正しく行うには多くの知識と努力が必要です。C ++の学習者にとっては恐ろしいことです。


多くの場合、特定のC ++ライブラリの作成者/保守者はこれを念頭に置いて、いずれかの方法を推奨します。

言い換えると、著者/維持者がライブラリをヘッダー(* .hおよび.hppのみ)に含めるか、ソース( .h *または.c)に含めることを意図している場合、readmeでそのように明確に述べているはずです。またはドキュメント。


クロスプラットフォーム(および複数のC ++コンパイラベンダーと環境と互換性がある)に設計および保守されているライブラリには、多くの場合、メイクファイルシステムまたはビルド構成システム(CMakeなど)があります。これらのシステムは、プラットフォームの違いを滑らかにするヘッダーシムを生成し、適切なコマンドラインオプションを使用して正しい順序でソースファイルでコンパイラとリンカーを呼び出すスクリプトを生成するために使用されます。プラットフォームと構成に応じて、これらのビルドシステムは特定のヘッダーまたはソースファイルを含めるか除外するか、特定のプリプロセッサシンボルを定義または未定義にすることができます。


著者/保守者の推奨に反することは可能ですが、それには常に大規模な移植作業が必要です。その移植作業に必要な作業量は、異なるC ++環境への移植に匹敵します。


Visual C ++はプロジェクト記述ファイル(一部はXMLベース)に基づく独自のビルドシステムを使用するため、Linuxで使用されるスクリプトベースのビルドシステムとはまったく異なります。CMakeで使用されるアプローチは、CMakeが構成設定を取得し、Visual C ++プロジェクト構造全体を出力し、構成オプションを* .vcxprojファイルにベイクすることです。

Visual C ++とのC ++リンク中に問題が発生した場合、*。vcxprojファイルのビルド設定は、Visual Studio GUIを使用して(プロジェクトプロパティページダイアログを使用して)変更できます。これは、多数の重要なC ++コンパイルおよびリンク設定の意味と結果を十分に理解していることを前提としています。

今、Visual C ++を使用する最も愚かな部分:ダースの異なるサードパーティライブラリを使用している場合、それらすべてのビルド設定を変更することは、各* .vcxprojファイルに移動し、ダースのGUIで同じ変更を繰り返すことを意味します回。面倒ですが、それを正しく行う方法を知っていれば、それを行うことができます。

ほとんどのVisual C ++学習者は、エラーコードで識別されるVisual C ++コンパイラとリンカーのエラーを観察することにより、これらの設定を困難な方法で学習します。たとえば、「シンボルシンボルが複数回定義された」という表面的な意味でLNK2005を検索できますが、重複した定義は不注意なプログラミングの誤りから生じたものではなく、代わりにコンパイルおよびリンクオプションの競合または誤用。


状況に対してより具体的かつ有用な回答を提供するには、使用するライブラリの名前と、リンクエラーまたは発生したその他の問題を知る必要があります。これらの質問に対する既存の回答は、それぞれのライブラリのディスカッションボードで見つけることができます。これらの質問には、「リンクの問題」、「ウィンドウ」、「ビジュアルC ++」というタグが付けられる傾向があります。

この問題に関する初心者から専門家へのガイドは可能ですが、プロジェクト固有のものになるでしょう。さまざまなプロジェクトで選択されたさまざまな設定では、ガイドを完全に書き直す必要があります。


.vcxprojを変更するのではなく、CMakeを使用して.vcxprojを出力する場合、CMake構成を変更できます
-Caleth

1

それが簡単である限り、私はイエスと言うでしょう。非常に多くの利点があります。

  1. 特にリンク時間の最適化を有効にすると、より高速で優れたコードが得られます。

  2. あなたのIDEはそれをもっと好きになります。例えば、(うまくいけば)インターフェース(.h)だけでなく、ライブラリコードの実装(.cpp)にジャンプできるようになります。ほとんどのコード)。

  3. 多くの場合、依存関係をgitサブモジュールとして追加できます。これは、少しハックですが、実際には依存関係を持つのに非常に良い方法です(とにかくC ++の場合、ほとんど正常なビルドシステムはありません)。ライブラリの更新と異なるバージョンのテストが非常に簡単になります。

  4. たとえば2017を使用している場合、MSVC ++ 2013で依存関係がコンパイルされることを心配する必要はありません。または、共有vs静的MSVCRT。

  5. デバッグモードで簡単にビルドし、ライブラリにステップインできます。

あなたがこれをしたくないと思う唯一の理由は、ライブラリが大きく、BoostやLLVMなど、自分の中で複製したくない複雑なビルドシステムがある場合です。しかし、単純なライブラリの場合、実際にはマイナス面はありません。

例として、いくつかのプロジェクトでlibusbを使用していますが、Windowsをサポートする必要があります。libusbは、ビルドシステムのジョークであるautotoolsを使用しますが、Windowsでは実際には動作しません。それらはプリコンパイルされたバイナリを提供しますが、MSVC ++ 2013でビルドされ、2017では動作しません。これまでで最も簡単な解決策は、関連するすべての.cおよび.hファイルをプロジェクトに追加することでした。


2
1)本当に?静的ライブラリは、オブジェクトファイルのコレクションであり、コンパイルしたばかりの場合と同じです。
Baldrickk

.oコンパイルされたファイルのアーカイブを作成できます-fltoが、これらは実際には静的ライブラリではありません。Clangの場合、LLVMビットコードファイルです。そして、他の誰かが提供する静的ライブラリを使用すると、明らかに動作しません。
Timmmm

わかりました、この議論をアップグレードしましょう -私はもっと多くのことを学ぶことを楽しみにしています:)
Baldrickk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.