OK、私はそれを理解しました。これは、本来あるべきよりもはるかに苦痛です. ごく最近まで、Kitware の人々は、静的ライブラリから DLL を作成したい理由を理解していませんでした。彼らの主張は、top_project
それが実質的に独自のプロジェクトであるため、メイン (たとえば私の場合) ディレクトリにソース ファイルが常に存在する必要があるというものです。私は物事の見方が異なり、top_project
独立して存在してはならない小さなサブプロジェクトに分割する必要があります(つまり、それらのために本格的なプロジェクトを作成し、それらを使用して追加しても意味がありませんExternalProject_Add
)。さらに、共有ライブラリを (たとえば Java Native Interface で使用するために) 出荷する場合、プロジェクトの内部レイアウトを公開することになるため、何十もの共有ライブラリを出荷したくありません。とにかく、静的ライブラリから共有ライブラリを作成することを主張したと思いますが、技術的な詳細に進みます。
subproject1
およびの CMakeLists.txt でsubproject2
、OBJECT ライブラリ機能 (CMake 2.8.8 で導入) を使用してターゲットを作成する必要があります。
add_library(${PROJECT_NAME} OBJECT ${SRC})
whereSRC
はソース ファイルのリストを指定します (ファイルの追加や削除など、CMakeLists.txt の変更が検出されたときに make が CMake を再起動できるようにするため、これらは CMakeLists.txt ファイルで明示的に設定する必要があることに注意してください)。
でtop_project
、次を使用してサブプロジェクトを追加します。
add_subdirectory(subproject1)
add_subdirectory(subproject2)
スタティック ライブラリのシンボルを表示するには、次を使用します。
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
次に、以下を使用して共有ライブラリを作成できます。
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
「通常の」ライブラリ (つまり、オブジェクトではない) は別のコマンドで追加する必要があることがわかりましたadd_library
。そうしないと、単純に無視されます。
実行可能ファイルの場合、次を使用できます。
add_executable(name_of_executable $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive")
target_link_libraries(name_of_executable ${PROJECT_NAME}
繰り返しますが、これは CMake のバージョン 2.8.8 以降でのみ機能します。同様に、CMakeは依存関係を非常にうまく管理し、クロスプラットフォームです。これは、単純な古いMakefileよりも痛みが少なくなく、柔軟性が確かに低いためです.