CMakeの`INTERFACE_POSITION_INDEPENDENT_CODE`プロパティ:詳細解説とサンプルコード
"INTERFACE_POSITION_INDEPENDENT_CODE" プロパティは、CMake において、ターゲットが位置独立コード(PIC)であるかどうかを指定するために使用されます。PIC は、実行時にアドレスが変更される可能性のあるオブジェクトを含むコードです。これは、共有ライブラリやダイナミックリンクライブラリなどの動的にロードされるモジュールでよく使用されます。
構文
set_target_properties(target_name PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE {BOOL})
{BOOL}
: ターゲットがPICであるかどうかを示す真偽値。TRUE
はPICであることを示し、FALSE
はそうでないことを示します。target_name
: プロパティを設定するターゲットの名前
デフォルト値
デフォルトでは、INTERFACE_POSITION_INDEPENDENT_CODE
プロパティは FALSE
に設定されます。
使い方
INTERFACE_POSITION_INDEPENDENT_CODE
プロパティは、ターゲットがPICである必要があることを明示的に示すために使用されます。これは、ターゲットが共有ライブラリやダイナミックリンクライブラリなどの動的にロードされるモジュールの一部である場合に重要です。
以下の例は、foo
という名前のターゲットがPICであることを示す方法を示しています。
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
注意点
INTERFACE_POSITION_INDEPENDENT_CODE
プロパティは、ターゲットがPICである必要があることを示すためだけに使用されます。PIC コードを実際に生成するには、コンパイラオプションを設定する必要があります。これは、CMake の target_link_libraries
コマンドを使用して行うことができます。
以下の例は、foo
ターゲットと bar
ターゲットをリンクし、bar
ターゲットが foo
ターゲットの INTERFACE_POSITION_INDEPENDENT_CODE
プロパティを継承することを示しています。
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
add_library(bar SHARED bar.cpp)
target_link_libraries(bar foo)
- 以前のバージョンの CMake では、
POSITION_INDEPENDENT_CODE
プロパティを使用する必要がありました。 - この説明は、CMake 3.20 以降で使用できる
INTERFACE_POSITION_INDEPENDENT_CODE
プロパティにのみ適用されます。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
例 2: 動的にロードされるモジュールのリンク
以下の例では、foo
と bar
という名前の2つのターゲットを作成し、bar
ターゲットが foo
ターゲットの INTERFACE_POSITION_INDEPENDENT_CODE
プロパティを継承するようにします。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
add_library(bar SHARED bar.cpp)
target_link_libraries(bar foo)
例 3: コンパイラオプションの設定
以下の例では、foo
ターゲットと bar
ターゲットを作成し、bar
ターゲットが foo
ターゲットの INTERFACE_POSITION_INDEPENDENT_CODE
プロパティを継承し、-fPIC
コンパイラオプションを設定するようにします。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
add_library(bar SHARED bar.cpp)
target_link_libraries(bar foo)
target_compile_options(bar PUBLIC "-fPIC")
説明
- 最後の例では、
-fPIC
コンパイラオプションをbar
ターゲットに設定して、PIC コードを実際に生成します。 bar
ターゲットはfoo
ターゲットのINTERFACE_POSITION_INDEPENDENT_CODE
プロパティを継承するため、PICであることも指定されます。bar
ターゲットは共有ライブラリとして作成され、foo
ターゲットとリンクされます。foo
ターゲットは共有ライブラリとして作成され、INTERFACE_POSITION_INDEPENDENT_CODE
プロパティを使用してPICであることを指定します。- 上記の例では、
foo
とbar
という名前の2つのターゲットを作成します。
これらの例は、INTERFACE_POSITION_INDEPENDENT_CODE
プロパティをさまざまな状況で使用する方法を示しています。
- 実際のプロジェクトでは、より複雑な設定が必要になる場合があります。
しかし、"INTERFACE_POSITION_INDEPENDENT_CODE" プロパティにはいくつかの制限があります。
- 以前のバージョンの CMake では、
POSITION_INDEPENDENT_CODE
プロパティを使用する必要がありました。 - PIC コードを実際に生成するには、コンパイラオプションを設定する必要があります。
- ターゲットがPICである必要があることを明示的に示すためだけに使用されます。
これらの制限を回避するために、"INTERFACE_POSITION_INDEPENDENT_CODE" プロパティの代替方法を使用することができます。
代替方法
"INTERFACE_POSITION_INDEPENDENT_CODE" プロパティの代替方法はいくつかあります。
- コンパイラオプションを設定する
最も一般的な代替方法は、コンパイラオプションを設定することです。これは、CMake の target_compile_options
コマンドを使用して行うことができます。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
add_library(bar SHARED bar.cpp)
target_link_libraries(bar foo)
target_compile_options(bar PUBLIC "-fPIC")
target_link_libraries
コマンドのINTERFACE_LINK_LIBRARIES
オプションを使用する
target_link_libraries
コマンドの INTERFACE_LINK_LIBRARIES
オプションを使用して、PIC である必要があるターゲットを指定することもできます。
以下の例は、foo
ターゲットと bar
ターゲットを作成し、bar
ターゲットが foo
ターゲットとリンクし、foo
ターゲットがPICであることを指定するようにします。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
add_library(bar SHARED bar.cpp)
target_link_libraries(bar foo INTERFACE_LINK_LIBRARIES foo)
add_executable
コマンドのPOSITION_INDEPENDENT_CODE
オプションを使用する
add_executable
コマンドの POSITION_INDEPENDENT_CODE
オプションを使用して、PIC である必要がある実行ファイルを作成することもできます。
以下の例は、foo
という名前の実行ファイルを作成し、それがPICであることを指定します。
cmake_minimum_required(VERSION 3.20)
project(foo)
add_executable(foo foo.cpp)
set_target_properties(foo PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
どの方法を使用するか
使用する方法は、状況によって異なります。
add_executable
コマンドのPOSITION_INDEPENDENT_CODE
オプションを使用する 方法は、実行ファイルを作成する場合に便利です。target_link_libraries
コマンドのINTERFACE_LINK_LIBRARIES
オプションを使用する 方法は、ターゲットが他のターゲットとリンクされている場合に便利です。- コンパイラオプションを設定する 方法は、最も汎用性があり、ほとんどの状況で使用できます。
- 実際のプロジェクトでは、より複雑な設定が必要になる場合があります。