2017-06-26 22 views
1

インターフェイスライブラリを使用してプリプロセッサマクロを定義しようとしています。これらのインタフェースライブラリは、これらのマクロを伝播するために他のライブラリにリンクされます。このアプローチは私が作成している共有ライブラリでも動作していますが、CMakeオブジェクトライブラリでは動作しません。CMakeインターフェイスライブラリをオブジェクトライブラリにリンクする

インターフェイスライブラリをオブジェクトライブラリに直接リンクすることはできませんが、TARGET_OBJECTSをインターフェイスライブラリに間接的にリンクすることができます。

Docs

オブジェクトライブラリがtarget_link_libraries()コマンドの呼び出しに直接名前を付けることはないかもしれないが、彼らはそのINTERFACE_SOURCESターゲットプロパティは$<TARGET_OBJECTS:objlib>に名前を付けるために設定されているインタフェースライブラリを使用することにより、間接的に「リンク」することができます。

これを実行しようとしましたが、オブジェクトファイルはまだ適切な定義でコンパイルされていません。

// a.cpp  
int a() { 
    return 
#ifdef MY_DEF 
    5; 
#endif 
    } 

CMakeLists:ここでは、最小限の作業例がある

cmake_minimum_required(VERSION 3.0.1) 
project(my_question) 

add_library(object_lib OBJECT a.cpp) 

add_library(interface_lib INTERFACE) 
target_compile_definitions(interface_lib INTERFACE MY_DEF) 

# This does not set the MY_DEF flag 
target_sources(interface_lib INTERFACE $<TARGET_OBJECTS:object_lib>) 

add_library(main_lib SHARED $<TARGET_OBJECTS:object_lib>) 
target_link_libraries(main_lib) 

出力:これはCMakeのでは可能なはずの文書に基づいて

/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/object_lib.dir/build.make CMakeFiles/object_lib.dir/build 
[ 50%] Building CXX object CMakeFiles/object_lib.dir/a.cpp.o 
/Library/Developer/CommandLineTools/usr/bin/c++  -o CMakeFiles/object_lib.dir/a.cpp.o -c /Users/umar/devel/so_question/a.cpp 
/Users/umar/devel/so_question/a.cpp:7:5: error: expected expression 
    } 
    ^
1 error generated. 
make[2]: *** [CMakeFiles/object_lib.dir/a.cpp.o] Error 1 
make[1]: *** [CMakeFiles/object_lib.dir/all] Error 2 
make: *** [all] Error 2 

。私は何か間違っているのか、これがCMakeの問題なのかどうかはわかりません。私はこれをDebianとOSXのCMakeバージョン3.6と3.8で再現できました。

編集:

私はユートピアのアプローチ@使用してこの問題を回避することができましたが、私は私の例で使用したアプローチが機能しなかった理由を、私は興味がありました。私がこれを間違ってやっているのか、それともツールに問題があるのか​​分かりませんでした。おそらくStackOverflowはこのタイプの質問の正しいプラットフォームではないので、プロジェクトに対してバグレポートを提出する必要があります。

EDIT2:

CMakeの(3.8)の最新バージョンのように、これではない可能CMakeの(see discussion)です。これは、thisマージリクエストによって3.9でサポートされるものです。古いバージョンの場合、ユートピアの答えが行く方法です。

+0

'target_link_libraries(main_lib)' target_link_libraries(main_libのinterface_lib)であるべきです。 – Tsyvarev

+0

これは、 'main_lib'ターゲットのソースに定義を適用したい場合にのみ必要であると思います。 'object_lib'ソースファイルは別々にコンパイルされているので、定義はそれに適用されません。それにもかかわらず、 'tll(main_lib interface_lib)'を試しましたが、object_libソースに定義を適用しませんでした。 –

+0

いずれの場合でも、単一の引数を持つ 'target_link_libraries'は*役に立たない*です。エラーログに従って、 'object_lib'の* object file *をコンパイルしています。このファイルに特定の定義が必要な場合は、 'main_lib'ターゲットではなく' object_lib'ターゲットをリンクする必要があります: 'target_link_libraries(object_lib interface_lib)'。 * OBJECT *ライブラリは**プリコンパイルされた**オブジェクトファイルのセットとして考える: 'main_lib'がこれらのファイルに* compile *オプションを割り当てるのは遅すぎる。 – Tsyvarev

答えて

1

インターフェイスライブラリからコンパイル定義をプロパティを介して直接コピーするだけです。 target_sources()が初めてではない3.0.1それはそう、バージョン3.1で導入されました

cmake_minimum_required(VERSION 3.1) 
project(my_question) 

add_library(interface_lib INTERFACE) 
target_compile_definitions(interface_lib INTERFACE MY_DEF) 

add_library(object_lib OBJECT a.cpp) 
target_compile_definitions(object_lib PUBLIC 
    $<TARGET_PROPERTY:interface_lib,INTERFACE_COMPILE_DEFINITIONS>) 

add_library(main_lib b.cpp) 
target_sources(main_lib PRIVATE 
    $<TARGET_OBJECTS:object_lib>) 

注:情報は、通常のコマンドを経由して、それのためだけでは直接サポート、ありません。 cmake_minimum_requiredバージョンを更新することをお勧めします。

+0

私はこのアプローチを認識しており、私は自分のプロジェクトでこれを行うことができましたが、質問にリンクされたドキュメントに基づいてオブジェクトライブラリにインターフェイスライブラリを適用する必要があるようです。 –

+0

@Umar Arshadは、CMakeプロジェクトの代わりにstackoverflow.comにバグレポートを書いていますか、あるいはあなたの質問を解決する答えが必要でしたか?彼らの質問と言葉のための最小実行可能なプログラムを作成するために明らかに苦労した人のために、それは十分に答えるために、あなたの回答へのあなたの反対は今あなたの質問に全くこのアプローチを言及して以来、特に奇妙です。 – utopia

+0

私はあなたの答えを感謝し、私はあなたの努力を否定しようとしていませんでした。私はこれを間違ってやっているのか、CMakeに問題があるのか​​不思議でした。私は最近この方法でCMakeを使い始めましたが、これはツールではなく私の無能さの症状だと思いました。私はこれが再び起こらないように質問を更新します –

-1

については、特定のコンパイル定義を使用するOBJECTライブラリ自体を作る、あなたはどちらかのはず:

  • は、ライブラリのターゲット自体にこれらの定義を追加します。

    target_compile_definitions(object_lib PUBLIC MY_DEF) 
    
  • あるいはリンクこれらの定義を必要とする別のライブラリを持つライブラリ:

    0123そのローミングサービスで

OBJECTライブラリはcmakeの内のライブラリの他のタイプの違いはありません。オブジェクトライブラリがtarget_link_libraries()コマンドの呼び出しに直接名前を付けることはないかもしれないが

、彼らはそのINTERFACE_SOURCES対象財産であるインタフェースライブラリを使用することにより、間接的に「リンク」することができます:cmakeのドキュメントから引用


$<TARGET_OBJECTS:objlib>という名前に設定します。

コンパイル定義から別のものへOBJECTライブラリを伝播する方法について説明します。それはOBJECTライブラリ自体に定義にを伝播する方法についてないです。

+1

'target_link_libraries(object_lib interface_lib)'これは間違っています。オブジェクトライブラリは何かにリンクすることはできません(あなたは実際にその正確なエラーを取得します)。オブジェクトライブラリは、リンクするインタフェースに関して他のライブラリと同じではありません。 "あなたはtarget_link_libraries()への呼び出しでオブジェクトライブラリを直接指定することはできませんが、"と書いてあるだけです。あなたは通常あなたの記事、Tsyvarev、あなたのアカウントを使用して他の誰かの非常に正確ですか、あなたは今日疲れていますか? :) – utopia

+0

ドキュメントの前の段落では、 'OBJECTライブラリはtarget_link_libraries()。**の右側に**使われないかもしれません。'ということで、最初の引数としてこのようなライブラリを使うことが許されていると仮定しました。私はいくつかのことを確認し、答えを更新します... – Tsyvarev

関連する問題