2

ネットワーク デバイス用の API としてリリースされる静的ライブラリを構築しようとしています。ライブラリを正常にコンパイルおよびリンクして、.lib 出力ファイルを生成できます。次のように、それらをディレクトリ構造に再配置します。

EyeLib
 L-Include
 |  L-PublicInterface.h
 L-Lib
 |  L-debug
 |  |   L-MyLib.lib
 |  |   L-MyLib.pdb
 |  L-release
 |      L-MyLib.lib
 L-MyLibConfig.cmake

MyLibConfig.cmake ファイルは非常に単純で、以下が含まれています。

# the header file is relative to this cmake file, so get the path.
GET_FILENAME_COMPONENT( MyLib_TOPLEVEL_DIR ${CMAKE_CURRENT_LIST_FILE} PATH )
SET( MyLib_INCLUDE_DIR ${MyLib_TOPLEVEL_DIR}/include )

IF( WIN32 )
  FIND_LIBRARY( MyLib_DEBUG_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/debug )
  FIND_LIBRARY( MyLib_RELEASE_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib/release )
  SET( MyLib_LIBRARIES optimized ${MyLib_RELEASE_LIBRARY} debug ${MyLib_DEBUG_LIBRARY} )
ENDIF( WIN32 )
IF( UNIX )
  FIND_LIBRARY( MyLib_LIBRARY MyLib ${MyLib_TOPLEVEL_DIR}/lib )
  SET( MyLib_LIBRARIES "${MyLib_LIBRARY}" )
  MARK_AS_ADVANCED( MyLib_LIBRARY )
ENDIF( UNIX )

# handle the QUIETLY and REQUIRED arguments
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(MyLib DEFAULT_MSG MyLib_LIBRARIES MyLib_INCLUDE_DIR)

MARK_AS_ADVANCED( MyLib_INCLUDE_DIR )

このビルド構造は、過去にビルドしたいくつかのテスト ライブラリでは機能しましたが、それを使用して単純なテスト アプリをビルドしようとすると、「エラー LNK1104: ファイル 'libboost_thread-vc110- を開けません」というリンク エラーが発生します。 mt-s-1_54.lib'"

ライブラリ ビルドと同じプロジェクトにテスト アプリを追加すると、テスト アプリをビルドして正常に実行できます。これは、ライブラリ ビルドがリンク先のブースト ライブラリを見つけて、プロジェクト内の実行可能ファイルに伝播するためだと思います。

b2 link=static runtime-link=static threading=multi variant=debug,release --layout=tagged を使用して Boost 1.54 をビルドし、ライブラリ ビルドとテスト アプリ ビルドの両方を静的 MSVC ランタイム (/MT) にリンクしました。

誰でもこれでヘルプ/アドバイス/さらなるテストを提供できますか? すべてのブースト機能が API ライブラリにコンパイルされていることを確認する必要があるため、クライアントが自分でブーストをインストールする必要はありません。

追加情報

参考までに、ライブラリ ビルドの cmakelists.txt ファイルを次に示します。

set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")

set(Boost_USE_STATIC_LIBS   ON)
set(Boost_USE_MULTITHREADED ON)
find_package(Boost REQUIRED COMPONENTS system date_time regex thread chrono)
if(NOT WIN32)
  list(APPEND Boost_LIBRARIES pthread)
endif()

include_directories(${Boost_INCLUDE_DIRS})

FILE(GLOB srcs *.cpp)
FILE(GLOB headers *.h)
set(libname MyLib)

set(deps ${Boost_LIBRARIES})

#To allow compilation. std=c++0x is for accepting the access to enums, which usually is just accepted with Visual Studio
IF( NOT WIN32 )
  set (CMAKE_CXX_FLAGS "-fpermissive -std=c++0x")
ENDIF( NOT WIN32 )

SOURCE_GROUP( ${libname} FILES ${srcs} )
SOURCE_GROUP( "${libname}\\Hdr" FILES ${headers} )
add_library(${libname} ${srcs} ${headers})
target_link_libraries( ${libname} ${deps} )
4

1 に答える 1

10

これは仕様によるものです。

静的ライブラリを構築する場合、そのライブラリへの依存関係はライブラリに直接リンクされません。代わりに、実行可能ファイルをビルドするときに、すべてのライブラリの依存関係 (直接および間接) がその実行可能ファイルに直接リンクされます。

これは、ほとんどのコンパイラが静的ライブラリを処理する方法でもあります。VS は依存関係を静的ライブラリにリンクするための特別なオプションを提供しますが、たとえば gcc では、ダーティ ファイル ハックに頼らない限り、これは不可能です。CMake はサポートされているすべてのジェネレーターで使用できる機能のみをサポートするため、CMake は VS ビルドでもこれを行うことを許可しません。

現在、いくつかのオプションがあります。

  • スタティック ライブラリの代わりに dll を使用します ( add_library(${libname} SHARED ...))。静的ライブラリは基本的に、まとめられたオブジェクト ファイルの集まりですが、dll は実行可能ファイルとほぼ同じです。特に、すべての静的ライブラリの依存関係は、dll に直接リンクされます。ここでの欠点は、通常の dll の混乱に対処しなければならないことです。どの関数をエクスポートするかを指定する必要があり、dll の境界を越えて物を渡す際の通常の問題が適用されます。
  • 検索スクリプトですべての依存関係も検索します。コードの重複が最小限になるように、ライブラリの依存関係の処理を再構築できるはずです。欠点は、ライブラリ自体だけでなく、そのすべての依存関係を見つける必要があるため、サードパーティ アプリケーションの構成が (特に Windows で) より困難になることです。
  • エクスポートされたターゲットを使用します。ライブラリが最終的な実行可能ファイルと同じマシン上に構築されている場合、このアプローチは最も理にかなっています。ライブラリをビルドすると、CMake はそのライブラリを使用するための構成ファイルを自動生成します。次に、アプリケーションはそのスクリプトをインクルードする必要があるだけで、準備は完了です。欠点は、エクスポート メカニズムが CMake の最も単純な機能ではないことです。そのため、慣れるまでに時間がかかることになります。
  • ライブラリ ソースを各実行可能ファイルに直接取り込みます。基本的に、各実行可能ファイルはadd_subdirectoryライブラリ ソース ディレクトリに対して実行します。実行可能ファイルごとに依存関係を構成する必要があり、さらに実行可能ファイルごとに個別にライブラリをビルドする必要があります。あなたはおそらくこれをしたくないでしょう。
于 2013-08-21T07:59:47.850 に答える