2017-12-30 19 views
2

私はちょっと混乱した質問があります。私はスタティック(libthird.a)と共有のpic形式(libthird.so)になるサードパーティの依存関係を持っています。サードパーティのライブラリと異なるリンケージを使用した推移的な依存性

私はライブラリutilを持っています。これはlibthirdに依存しています。

そして私は、静的libthirdをリンクしたいutilに依存するアプリケーションを持っている、と私はutilに依存して動的にlibthirdリンクする必要があり、その生産する必要があるいくつかの共有ライブラリを持っています。

add_library(third INTERFACE) 
target_link_libraries(third INTERFACE /path/to/libthird.a) 
add_library(third_shared INTERFACE) 
target_link_libraries(third_shared INTERFACE /path/to/libthird.so) 

add_library(util ${UTIL_SOURCES}) 
add_library(util_shared ${UTIL_SOURCES}) # same sources again!! 
target_link_libraries(util PUBLIC third) 
target_link_libraries(util_shared PUBLIC third_shared) 

add_executable(some_app ...) 
target_link_libraries(some_app PRIVATE util) 

add_library(some_shared_object ...) 
target_link_libraries(some_shared_object PUBLIC util_shared) 

これは動作します:

私の現在(作業)のアプローチは、以下のようなものです。しかし、私はutilをビルドしています(そして、実際には、他の半ダースのライブラリなど)... 2回...異なるリンカの依存関係を取得するだけです。これをcmakeでやってもらうのが賢明な方法はありますか?

utilthirdに依存しないので、私はちょうどtarget_link_libraries()トップレベルsome_appsome_shared_objectに、私は、間違った順序で放出されるリンカのフラグを取得する場合。

+0

util_sharedをutillの周りに薄いラッパーにすることは可能でしょうか、あるいは本当に-fPICなしで静的util libに接続していますか? –

答えて

1

あなたが取っているアプローチは間違いなく私が見たものであり、前に自分自身も使っています。小規模のアーカイブや一回限りの使用に使用されていれば問題ありません。以下の例については

、私は次のようなプロジェクト構造を前提としています

foo/ 
    CMakeLists.txt 
    include/ 
    foo.h 
    src/ 
    foo.c 

だから、私は(単純?)もしましたあなたはUnix上で(作成できる知識に基づいて、次のアプローチを使用ベースのシステム少なくとも)静的なアーカイブからの共有ライブラリ。

project(foo C) 

set(SOURCES 
    "src/foo.c") 

set(LIBNAME "foo") 

add_library(${LIBNAME} STATIC ${SOURCES}) 

target_include_directories(${LIBNAME} PUBLIC "include") 
target_compile_options(${LIBNAME} PUBLIC "-fPIC") 

# 

get_property(CUR_PREFIX TARGET ${LIBNAME} PROPERTY PREFIX) 
get_property(CUR_SUFFIX TARGET ${LIBNAME} PROPERTY SUFFIX) 
get_property(CUR_NAME TARGET ${LIBNAME} PROPERTY NAME) 
get_property(CUR_OUTPUT_NAME TARGET ${LIBNAME} PROPERTY OUTPUT_NAME) 
get_property(CUR_ARCHIVE_OUTPUT_NAME TARGET ${LIBNAME} PROPERTY ARCHIVE_OUTPUT_NAME) 

message(STATUS "prefix: ${CUR_PREFIX}") 
message(STATUS "suffix: ${CUR_SUFFIX}") 
message(STATUS "name: ${CUR_NAME}") 
message(STATUS "output name: ${CUR_OUTPUT_NAME}") 
message(STATUS "archive name: ${CUR_ARCHIVE_OUTPUT_NAME}") 

add_custom_command(TARGET ${LIBNAME} POST_BUILD 
    COMMAND ${CMAKE_C_COMPILER} -shared -o libfoo.so -Wl,--whole-archive libfoo.a -Wl,--no-whole-archive 
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 

このアプローチと私の未解決の問題は、私は、静的なアーカイブ(libfoo.a)の名​​前を取得するには、信頼性と移植方法を発見していないということです。したがって、messageはすべてtarget propertiesのコマンドです。彼らのプラットフォームでは異なる動作をする可能性があります。


最も効率的な方法は、それはまたcmakeによくサポートされ、object libraryを使用することです:

# cmake file 

cmake_minimum_required(VERSION 3.2) 

project(foo C) 

set(SOURCES 
    "src/foo.c") 

set(LIBNAME "foo") 
set(LIBNAME_OBJ "${LIBNAME}_obj") 

add_library(${LIBNAME_OBJ} OBJECT ${SOURCES}) 

target_include_directories(${LIBNAME_OBJ} PUBLIC "include") 
target_compile_options(${LIBNAME_OBJ} PUBLIC "-fPIC") 

# 

add_library(${LIBNAME} SHARED $<TARGET_OBJECTS:${LIBNAME_OBJ}>) 
add_library(${LIBNAME}_static STATIC $<TARGET_OBJECTS:${LIBNAME_OBJ}>) 

すべての例は、cmakeのバージョン3.6.1でテストしました。

これが役に立ちます。もしあなたがより良い方法を見つけたら、私たちに知らせてください。

関連する問題