web-dev-qa-db-ja.com

CMakeに同じライブラリの静的バージョンと共有バージョンの両方を構築させることは可能ですか?

同じソース、それだけで、静的バージョンと共有バージョンの両方が必要です。簡単ですか?

123
gct

はい、それは適度に簡単です。次の2つの「add_library」コマンドを使用します。

add_library(MyLib SHARED source1.c source2.c)
add_library(MyLibStatic STATIC source1.c source2.c)

多くのソースファイルがある場合でも、ソースのリストをcmake変数に配置するので、簡単に実行できます。

Windowsでは、共有ライブラリと静的ライブラリの両方に「.lib」ファイルがあるため、おそらく各ライブラリに異なる名前を付ける必要があります。しかし、LinuxとMacでは、両方のライブラリに同じ名前を付けることさえできます(例:libMyLib.aとlibMyLib.so):

set_target_properties(MyLibStatic PROPERTIES OUTPUT_NAME MyLib)

ただし、ライブラリの静的バージョンと動的バージョンの両方に同じ名前を付けることはお勧めしません。ライブラリにリンクするツールのコンパイル行で静的リンケージと動的リンケージを選択しやすくするため、別の名前を使用することを好みます。通常、libMyLib.so(共有)やlibMyLib_static.a(静的)などの名前を選択します。 (これはLinux上の名前です。)

115

CMakeバージョン2.8.8以降、「オブジェクトライブラリ」オブジェクトファイルのコンパイルの重複を避けるためを使用できます。 2つのソースファイルを含むライブラリのChristopher Brunsの例を使用します。

_# list of source files
set(libsrc source1.c source2.c)

# this is the "object library" target: compiles the sources only once
add_library(objlib OBJECT ${libsrc})

# shared libraries need PIC
set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)

# shared and static libraries built from the same object files
add_library(MyLib_shared SHARED $<TARGET_OBJECTS:objlib>)
add_library(MyLib_static STATIC $<TARGET_OBJECTS:objlib>)
_

CMake docs から:

オブジェクトライブラリはソースファイルをコンパイルしますが、オブジェクトファイルをライブラリにアーカイブまたはリンクしません。代わりに、add_library()またはadd_executable()によって作成された他のターゲットは、_$<TARGET_OBJECTS:objlib>_の形式の式をソースとして使用してオブジェクトを参照できます(objlibはオブジェクトライブラリ名)。

簡単に言えば、add_library(objlib OBJECT ${libsrc})コマンドは、ソースファイルを_*.o_オブジェクトファイルにコンパイルするようにCMakeに指示します。この_*.o_ファイルのコレクションは、2つのadd_library(...)コマンドで_$<TARGET_OBJECT:objlib>_と呼ばれ、オブジェクトファイルの同じセット。ソースファイルがたくさんある場合は、_*.o_ファイルのコンパイルにかなり時間がかかる可能性があります。オブジェクトライブラリでは、一度だけコンパイルします。

あなたが支払う代償は、共有ライブラリがこれを必要とするため、オブジェクトファイルを位置に依存しないコードとして構築する必要があるということです(静的ライブラリは気にしません)。位置に依存しないコードは効率が低下する可能性があるため、最大のパフォーマンスを目指す場合は静的ライブラリを使用します。さらに、静的にリンクされた実行可能ファイルを配布する方が簡単です。

74
Laryx Decidua

通常、目的のためにADD_LIBRARY呼び出しを複製する必要はありません。ただ利用する

$> man cmake | grep -A6 '^ *BUILD_SHARED_LIBS$' 
   BUILD_SHARED_LIBS
          Global flag to cause add_library to create shared libraries if on.

          If present and true, this will cause all libraries to be built shared unless the library was
          explicitly added as a static library.  This variable is often added to projects as an OPTION
          so  that each user of a project can decide if they want to build the project using shared or
          static libraries.

-DBUILD_SHARED_LIBS:BOOL = ONを使用して最初に(一方のソース外ディレクトリに)構築し、もう一方をOFFで構築します

23