CMake: プロジェクトをクリーンアップ! ポリシー「CMP0081」で相対パスの使用を禁止


CMakeポリシー「CMP0081」は、LINK_DIRECTORIES ターゲットプロパティで相対パスを使用することを禁止するものです。このポリシーは、CMake 3.13で導入されました。

旧動作と新動作

CMake 3.12以前では、LINK_DIRECTORIES ターゲットプロパティに相対パスを含めることが許可されていました。しかし、この動作は、相対パスの基底パスが明確に定義されていないという問題がありました。

CMake 3.13以降では、この問題を解決するために、LINK_DIRECTORIES ターゲットプロパティに相対パスを含めると、CMakeは致命的エラー(FATAL_ERROR)を出力します。

影響を受けるもの

このポリシー変更の影響を受けるのは、LINK_DIRECTORIES ターゲットプロパティに相対パスを使用しているCMakeプロジェクトです。このようなプロジェクトは、CMake 3.13以降でビルドしようとすると、致命的エラーが発生します。

対処方法

このポリシー変更の影響を受けるプロジェクトを修正するには、以下のいずれかの方法を行う必要があります。

  • cmake_policy コマンドを使用して、このポリシーをOLDに設定する
  • LINK_DIRECTORIES ターゲットプロパティに絶対パスを使用する

cmake_policy コマンドを使用したポリシー設定

以下の例は、cmake_policy コマンドを使用して、CMP0081 ポリシーをOLDに設定する方法を示しています。

cmake_policy(SET CMP0081 OLD)

このコマンドを実行すると、CMakeはLINK_DIRECTORIES ターゲットプロパティに相対パスを含め ても警告を出力するだけで、致命的エラーは発生しなくなります。

  • 新しいプロジェクトを作成する場合は、常に絶対パスを使用してLINK_DIRECTORIES ターゲットプロパティを設定することをお勧めします。
  • cmake_policy コマンドを使用してポリシーをOLDに設定することは、非推奨です。将来的にこの動作が変更される可能性があるためです。


例1:相対パスを使用するLINK_DIRECTORIESターゲットプロパティ

cmake_minimum_required(VERSION 3.0)

project(myproject)

add_executable(myprogram myprogram.cpp)

target_link_directories(myprogram ../lib)

この例では、target_link_directories コマンドを使用して、myprogram ターゲットの LINK_DIRECTORIES ターゲットプロパティに相対パス (../lib) を設定しています。

CMake 3.12以前では、このコードは問題なくコンパイルされます。しかし、CMake 3.13以降では、このコードは致命的エラー(FATAL_ERROR)を出力します。

例2:絶対パスを使用するLINK_DIRECTORIESターゲットプロパティ

cmake_minimum_required(VERSION 3.0)

project(myproject)

add_executable(myprogram myprogram.cpp)

target_link_directories(myprogram /usr/local/lib)

このコードは、すべてのCMakeバージョで問題なくコンパイルされます。

例3:cmake_policyコマンドを使用してポリシーをOLDに設定

cmake_minimum_required(VERSION 3.0)

project(myproject)

cmake_policy(SET CMP0081 OLD)

add_executable(myprogram myprogram.cpp)

target_link_directories(myprogram ../lib)

この例では、cmake_policy コマンドを使用して、CMP0081 ポリシーをOLDに設定しています。

この設定により、target_link_directories ターゲットプロパティに相対パス (../lib) を設定しても、CMakeは警告を出力するだけで、致命的エラーは発生しなくなります。

  • 実際のプロジェクトでは、プロジェクトの要件に合わせて適切なコードを記述する必要があります。
  • 上記の例はあくまで説明目的であり、実際のプロジェクトで使用されるコードとは異なる場合があります。


このポリシー変更の影響を受けるプロジェクトを修正するには、以下の代替方法を使用することができます。

絶対パスを使用する

最も簡単な代替方法は、LINK_DIRECTORIES ターゲットプロパティに絶対パスを使用することです。絶対パスは、ファイルシステム上の場所を明確に定義するため、相対パスよりも望ましいとされています。

# 相対パスを使用する場合
target_link_directories(myprogram ../lib)

# 絶対パスを使用する場合
target_link_directories(myprogram /usr/local/lib)

CMAKE_MODULE_PATH 環境変数を設定する

別の代替方法は、CMAKE_MODULE_PATH 環境変数を設定して、カスタムモジュールディレクトリを指定することです。このモジュールディレクトリに、link_directories 関数を提供するカスタムモジュールを配置することができます。この関数は、LINK_DIRECTORIES ターゲットプロパティに相対パスを含めることができます。

# カスタムモジュールディレクトリを指定
set(CMAKE_MODULE_PATH "/my/custom/module/path")

# カスタムモジュールを使用する
load_module(my_custom_modules)
my_custom_modules_link_directories(myprogram ../lib)

サブディレクトリを使用する

プロジェクトをサブディレクトリ構造に整理し、各サブディレクトリで target_link_directories コマンドを使用して相対パスを設定することもできます。この方法では、相対パスを使用することができますが、プロジェクトの構造が複雑になる可能性があります。

# サブディレクトリ構造を使用する場合
project(myproject)

add_subdirectory(lib)
add_executable(myprogram myprogram.cpp)

# 各サブディレクトリで相対パスを設定
target_link_directories(myprogram ../lib)

CMakeLists.txtファイルを2つに分ける

# 古いCMakeポリシーを使用するCMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(myproject)

cmake_policy(SET CMP0081 OLD)

add_executable(myprogram myprogram.cpp)
target_link_directories(myprogram ../lib)

# 新しいCMakeポリシーを使用するCMakeLists.txt
cmake_minimum_required(VERSION 3.13)

add_executable(myprogram myprogram.cpp)

# ... (その他のビルド設定)

推奨事項

上記の代替方法のうち、絶対パスを使用する 方法が最もシンプルで推奨されます。

絶対パスを使用する方法は、プロジェクトの構造を明確にし、移植性を向上させることができます。

他の代替方法は、より複雑な状況で使用することができますが、プロジェクトの保守性を悪化させる可能性があるため、注意が必要です。