49

コードをコンパイルする必要がある 10 個の *.hpp および *.cpp ファイルがあるとします。多くの異なるコードに対して同じファイルが必要になることはわかっています。簡単に書けるファイルで「パッケージ」を作成できますか?

#include <mypackage>

それ以外の:

#include "file1.hpp"
#include "file2.hpp"
...
#include "file10.hpp"

この「パッケージ」が必要になるたびにメイクファイルを作成する必要はありません。

より正確には、Linuxを使用しています。

4

5 に答える 5

79

CPP ソース (H ファイルと CPP ファイル) のコレクションをまとめて「ライブラリ」にコンパイルし、それを他のプログラムやライブラリで使用できます。これを行う方法の詳細は、プラットフォームとツールチェーンに固有であるため、詳細を発見するのはあなたに任せます。ただし、読むことができるいくつかのリンクを提供します。

gnu コンパイラを使用した共有および静的ライブラリの作成 [gcc]

チュートリアル: ダイナミック リンク ライブラリの作成と使用 (C++)

ライブラリは、ソース コード ライブラリとバイナリ ライブラリの 2 種類に分けることができます。これら 2 つのタイプのハイブリッドも存在する可能性があります。ライブラリは、ソース ライブラリとバイナリ ライブラリの両方になることができます。ソース コード ライブラリは、単にソース コードとして配布されるコードのコレクションです。通常、ヘッダー ファイル。Boost ライブラリのほとんどはこのタイプです。バイナリ ライブラリは、クライアント プログラムによって実行時に読み込み可能なパッケージにコンパイルされます。

バイナリ ライブラリの場合でも (もちろんソース ライブラリの場合も)、ライブラリのユーザーにヘッダー ファイル (または複数のヘッダー ファイル) を提供する必要があります。これにより、クライアント プログラムのコンパイラに、ライブラリで検索する関数などを伝えます。ライブラリの作成者がよく行うのは、ライブラリによってエクスポートされるすべての宣言で構成された単一のマスター ヘッダー ファイルであり、クライアントは#includeそのヘッダーを使用します。後で、バイナリ ライブラリの場合、クライアント プログラムはライブラリに「リンク」し、これにより、ヘッダーに記載されているすべての名前が実行可能なアドレスに解決されます。

クライアント側のヘッダー ファイルを作成するときは、複雑さを念頭に置いてください。一部のクライアントが、ライブラリのいくつかの部分のみを使用したい場合がよくあります。ライブラリのすべてを含む 1 つのマスター ヘッダー ファイルを作成すると、クライアントのコンパイル時間が不必要に長くなります。

この問題に対処する一般的な方法は、ライブラリの相関部分に個別のヘッダー ファイルを提供することです。Boost のすべてを 1 つのライブラリと考える場合、Boost はその一例です。Boost は膨大なライブラリですが、正規表現機能だけが必要な場合は、正規#include表現関連のヘッダーだけでその機能を取得できます。正規表現だけが必要な場合は、すべての Boostを含める必要はありません。

Windows と Linux の両方で、バイナリ ライブラリはさらに動的と静的の 2 つのタイプに分けることができます。静的ライブラリの場合、ライブラリのコードはクライアント プログラムの実行可能ファイルに実際に「インポート」されます (適切な用語がないため)。静的ライブラリはあなたによって配布されますが、これはコンパイル ステップ中にクライアントによってのみ必要とされます。これは、クライアントにプログラムで追加のファイルを配布することを強制したくない場合に便利です。また、依存地獄を回避するのにも役立ちます. 一方、動的ライブラリはクライアント プログラムに直接「インポート」されず、実行時にクライアント プログラムによって動的にロードされます。これにより、クライアント プログラムのサイズが削減され、複数のプログラムが同じ動的ライブラリを使用する場合にディスク フットプリントが削減される可能性がありますが、クライアント プログラムと共にライブラリ バイナリを配布およびインストールする必要があります。

于 2013-05-22T13:53:06.573 に答える
5

Linux の場合:

g++ フラグ -shared -Wl,-soname,libLIBNAME.so.1 -o libLIBNAME.VERSION OBJECT_FILES

どこ

FLAGS: 典型的なフラグ (例: -g、-Wall、-Wextra など)

LIBNAME: ライブラリの名前

OBJECT_FILES: cpp ファイルをコンパイルした結果のオブジェクト ファイル

VERSION: ライブラリのバージョン

于 2013-05-22T13:59:50.233 に答える
2

はいといいえ。

#include "myLib.h"単一のヘッダーを介してこれらすべてのヘッダーを含めるため、それで十分な include-all ヘッダーを作成できます。ただし、1 つのインクルードで 10 個の '.cpp' ファイルのコンテンツがプロジェクトに自動的にリンクされるという意味ではありません。それらをライブラリにコンパイルし、(すべてのオブジェクト ファイルではなく) その単一のライブラリを "myLib.h" を使用するプロジェクトにリンクする必要があります。ライブラリ バイナリは静的および動的ライブラリとして提供されます。ファイルは通常、静的および動的ライブラリに対してそれぞれ.liband .dll(windows).aおよび(linux) という名前が付けられます。.so

そのようなライブラリをビルドしてリンクする方法は、ビルド システムによって異なります。これらの用語をネット上で検索することをお勧めします。

1 つの代替方法は.cpp、ヘッダーですべての関数を定義してファイルを削除することです。そうすれば、追加のライブラリをリンクする必要はありませんが、ビルド時間が長くなります。これは、ヘッダーを翻訳単位の 1 つに直接的または間接的に含めるたびに、コンパイラがこれらすべての関数を処理する必要があるためです。

于 2013-05-22T13:46:11.283 に答える
2

「file1.hpp」と「file2.hpp」などが密接に関連しており、(ほぼ) 常に一緒に使用されていると仮定すると、他のコンポーネントのインクルードを含む「mypacakge.h」を 1 つ作成することをお勧めします (そうではありません)。それ自体でライブラリにします-それはまったく別のプロセスです)。

それらが密接に関連していないか、一緒に使用されていない場合、そのような「メガインクルード」は必要ありません。必要のないものをたくさん引き込むだけだからです。

ライブラリを作成するには、コードを一度ビルドし、.lib ファイルまたは共有ライブラリ (.dll または .so ファイル) を生成する必要があります。これを行うための正確な手順は、使用しているシステムによって異なります。ここで説明するには少し複雑すぎます。

編集: さらに説明すると: すべての C++ ライブラリは、実際には 1 つのライブラリ ファイルまたは共有ライブラリ ファイルです [ライブラリ内のコードを使用するために必要なコードと宣言の一部を含む多数のヘッダー ファイルと共に]。しかし、<iostream>と を別々に含める -たとえタイピングがはるかに少なくても、<vector>すべての異なる C++ ライブラリ ヘッダーのすべてを 1 つの に含めるのはかなりひどいことになります。<allcpplibrary>これは、ヘッダーファイルごとに 1 つのことを行うセクションに分割されています。したがって、1 つのヘッダー ファイルから「完全な」セットを取得できますが、実際には必要のないものはあまり多くありません。

于 2013-05-22T13:42:18.257 に答える
1

クライアントが「パッケージ」(ライブラリ) を実際に利用するために 10 個のヘッダーすべてを必要とする場合、それはかなり悪いインターフェイス設計です。

ライブラリのどの部分が使用されているかに応じて、クライアントが一部のヘッダーのみを必要とする場合は、クライアントに適切なヘッダーを含めさせて、最小限の識別子セットのみが導入されるようにします。これにより、スコープ、モジュール化、およびコンパイル時間が短縮されます。

他のすべてが失敗した場合は、ライブラリを実際にコンパイルするために内部で使用するものとは異なる、外部使用用の「インターフェースヘッダー」を作成できます。これはインストールされるものであり、他のヘッダーからの必要なコンテンツで構成されます。(ライブラリ内のすべてのヘッダーのすべてが必要になるとはまだ思いません。)

私はSalgarの解決策を思いとどまらせます。個別のヘッダーまたはモノリシックヘッダーがあります。個々のヘッダーに加えて、他のヘッダーを単に含む中央のヘッダーを提供すると、かなり貧弱なレイアウトに思えます。

私が理解していないのは、Makefileがこれにどの程度関与しているかです。ヘッダーの依存関係は、Makefile / ビルド システムによって自動的に解決される必要があります。つまり、ヘッダー ファイルがどのように配置されているかは問題ではありません。

于 2013-05-22T13:41:45.017 に答える