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: 動的にロードされるモジュールのリンク

以下の例では、foobar という名前の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であることを指定します。
  • 上記の例では、foobar という名前の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 オプションを使用する 方法は、ターゲットが他のターゲットとリンクされている場合に便利です。
  • コンパイラオプションを設定する 方法は、最も汎用性があり、ほとんどの状況で使用できます。
  • 実際のプロジェクトでは、より複雑な設定が必要になる場合があります。