インターフェイスライブラリを使用してプリプロセッサマクロを定義しようとしています。これらのインタフェースライブラリは、これらのマクロを伝播するために他のライブラリにリンクされます。このアプローチは私が作成している共有ライブラリでも動作していますが、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でサポートされるものです。古いバージョンの場合、ユートピアの答えが行く方法です。
'target_link_libraries(main_lib)' target_link_libraries(main_libのinterface_lib)であるべきです。 – Tsyvarev
これは、 'main_lib'ターゲットのソースに定義を適用したい場合にのみ必要であると思います。 'object_lib'ソースファイルは別々にコンパイルされているので、定義はそれに適用されません。それにもかかわらず、 'tll(main_lib interface_lib)'を試しましたが、object_libソースに定義を適用しませんでした。 –
いずれの場合でも、単一の引数を持つ 'target_link_libraries'は*役に立たない*です。エラーログに従って、 'object_lib'の* object file *をコンパイルしています。このファイルに特定の定義が必要な場合は、 'main_lib'ターゲットではなく' object_lib'ターゲットをリンクする必要があります: 'target_link_libraries(object_lib interface_lib)'。 * OBJECT *ライブラリは**プリコンパイルされた**オブジェクトファイルのセットとして考える: 'main_lib'がこれらのファイルに* compile *オプションを割り当てるのは遅すぎる。 – Tsyvarev