CMakeの add_imported_target と target_link_libraries コマンドを徹底解説

2024-04-27

CMake の "Properties: Targets" における "IMPORTED_NO_SYSTEM" プロパティ

IMPORTED_NO_SYSTEM プロパティは、CMake において インポートされたターゲットシステムライブラリ でないことを指定するために使用されます。これは、ターゲットがシステムにデフォルトでインストールされているライブラリではなく、プロジェクト固有のライブラリであることを示します。

影響

このプロパティを設定すると、以下の影響が発生します。

  • インクルードディレクトリの扱い: インポートされたターゲットの INTERFACE_INCLUDE_DIRECTORIES プロパティで指定されたディレクトリは、デフォルトでは システムインクルードディレクトリ として扱われます。しかし、IMPORTED_NO_SYSTEM プロパティを設定すると、これらのディレクトリはシステムインクルードディレクトリではなく、通常のインクルードディレクトリとして扱われます。これは、コンパイラがこれらのディレクトリを検索する順序に影響を与えます。
  • インストール: install(EXPORT) コマンドや export() コマンドを使用してインポートされたターゲットをインストールする場合、IMPORTED_NO_SYSTEM プロパティが設定されていると、そのターゲットのインクルードディレクトリは システムインクルードディレクトリ としてインストールされません。

以下の例は、IMPORTED_NO_SYSTEM プロパティを使用して、インポートされたターゲットのインクルードディレクトリがシステムインクルードディレクトリとして扱われないようにする方法を示しています。

# インポートされたターゲット "foo" を定義します。
add_imported_target(foo SHARED $<TARGET_LOCATION:foo>)

# foo のインクルードディレクトリを指定します。
target_properties(foo PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${foo_include_dir}")

# foo がシステムライブラリではないことを指定します。
set_target_properties(foo PROPERTIES IMPORTED_NO_SYSTEM TRUE)

補足

  • IMPORTED_NO_SYSTEM プロパティは、CMake 3.23 以降で使用できます。
  • システムライブラリかどうか分からない場合は、IMPORTED_NO_SYSTEM プロパティを設定しないことをお勧めします。


CMake のサンプルコード

シンプルなプロジェクト

この例では、main.cpp という名前のソースコードファイルと、CMakeLists.txt という名前の CMakeLists ファイルを使用して、シンプルな実行ファイルを作成します。

// main.cpp
#include <iostream>

int main() {
  std::cout << "Hello, world!" << std::endl;
  return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)

project(hello_world)

add_executable(hello_world main.cpp)

このコードを実行するには、以下のコマンドを実行します。

cmake .
make

ライブラリを使用するプロジェクト

この例では、foo.h という名前のヘッダーファイルと foo.cpp という名前のソースコードファイルを使用して、ライブラリを作成します。次に、main.cpp という名前のソースコードファイルを使用して、ライブラリを使用する実行ファイルを作成します。

// foo.h
#ifndef FOO_H
#define FOO_H

int foo(int x);

#endif
// foo.cpp
#include "foo.h"

int foo(int x) {
  return x * x;
}
// main.cpp
#include <iostream>
#include "foo.h"

int main() {
  int x = 5;
  int y = foo(x);
  std::cout << "foo(" << x << ") = " << y << std::endl;
  return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)

project(hello_world)

add_library(foo foo.cpp foo.h)
target_link_directories(hello_world PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

add_executable(hello_world main.cpp)
target_link_libraries(hello_world foo)

このコードを実行するには、以下のコマンドを実行します。

cmake .
make

サブディレクトリを含むプロジェクト

この例では、src ディレクトリに main.cpp という名前のソースコードファイルと CMakeLists.txt という名前の CMakeLists ファイルがあり、include ディレクトリに foo.h という名前のヘッダーファイルがあります。

// src/main.cpp
#include <iostream>
#include "foo.h"

int main() {
  int x = 5;
  int y = foo(x);
  std::cout << "foo(" << x << ") = " << y << std::endl;
  return 0;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)

project(hello_world)

add_subdirectory(src)
# src/CMakeLists.txt
add_executable(hello_world main.cpp)
target_include_directories(hello_world PRIVATE include)

このコードを実行するには、以下のコマンドを実行します。

cmake .
make

インストール

この例では、foo.h という名前のヘッダーファイルと foo.cpp という名前のソースコードファイルを使用して、ライブラリを作成します。次に、ライブラリを DESTDIR ディレクトリにインストールします。

// foo.h
#ifndef FOO_H
#define FOO_H

int foo(int x);

#endif
// foo.cpp
#include "foo.h"

int foo(int x) {
  return x * x;
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)

project(hello_world)

add_library(foo foo.cpp foo.h)

install(TARGETS foo DESTDIR ${DESTDIR})
install(DIRECTORY include DESTDIR ${DESTDIR}/include)

このコードを実行するには、以下のコマンドを実行します。

cmake -DCMAKE_INSTALL_PREFIX=/path/to/install .
make
make install

クロスコンパイル

この例では、main.cpp という名前のソースコードファイルを使用して、クロスコンパイル可能な実行ファイルを作成



CMakeでターゲットをインポートする方法

add_imported_target コマンドを使用する

この方法は、CMakeLists.txtファイル内で、外部プロジェクトからビルドされたターゲットをインポートするために使用されます。

add_imported_target(target_name STATIC | SHARED | EXECUTABLE
  [GLOBAL]
  source_directory
  [<source_files>]
  [IMPORTED_TARGETS target_name ...]
  [PROPERTIES ...])

上記のコマンドの引数は以下の通りです。

  • target_name: インポートするターゲットの名前
  • STATIC, SHARED, EXECUTABLE: ターゲットの種類
  • GLOBAL: オプション。このオプションを指定すると、インポートされたターゲットがグローバルスコープで利用可能になります。
  • source_directory: ターゲットのソースディレクトリ
  • <source_files>: オプション。ターゲットを構成するソースファイル
  • IMPORTED_TARGETS: オプション。依存関係となる他のインポート済みターゲット

以下の例は、foo という名前のライブラリをインポートする方法を示しています。

add_imported_target(foo SHARED ${CMAKE_CURRENT_BINARY_DIR}/foo/libfoo.so)

target_link_libraries コマンドを使用する

この方法は、プロジェクト内のターゲットに別のターゲットをリンクするために使用されます。

target_link_libraries(target_name target1 target2 ...)

上記のコマンドの引数は以下の通りです。

  • target1, target2: リンクするターゲット

以下の例は、main という名前の実行ファイルに foo というライブラリをリンクする方法を示しています。

target_link_libraries(main foo)

補足

  • インポートするターゲットがCMakeLists.txtファイルと同じディレクトリにある場合は、source_directory 引数を省略できます。
  • インポートするターゲットが静的ライブラリの場合は、IMPORTED_LINK_FLAGS プロパティを使用して、インポートするライブラリに必要なリンカフラグを指定できます。
  • インポートするターゲットが共有ライブラリまたは実行ファイルの場合は、IMPORTED_LINK_LIBRARIES プロパティを使用して、インポートするターゲットに必要なライブラリを指定できます。

上記以外にも、CMakeでターゲットをインポートする方法はいくつかあります。詳細については、CMakeのドキュメントを参照してください。




CMake: find_library()とtarget_link_directories()の連携

target_link_directories()コマンドは、CMakeプロジェクト内のターゲットに対して、リンカがライブラリを検索するディレクトリを指定するために使用されます。これは、ターゲットがリンクするライブラリが標準の検索パスに存在しない場合に特に重要です。



プログラミング初心者でもわかる!CMake の "set_directory_properties()" コマンドの使い方

set_directory_properties() コマンドは、CMakeプロジェクト内のディレクトリとサブディレクトリにプロパティを設定するために使用されます。これらのプロパティは、ビルドプロセス、インストール、その他の CMake 動作を制御するために使用できます。


CMake try_compile() を使って特定のライブラリがインストールされているかどうかを確認する方法

try_compile() は、CMake の強力なコマンドの一つで、コードを実際にコンパイルすることなく、コンパイルが成功するかどうかを確認することができます。これは、特定のコンパイラやオプションがシステム上で使用可能かどうかをテストしたり、コードの移植性を検証したりする際に非常に便利です。


C++標準ライブラリ、テンプレートエンジン、シェルスクリプト... string()コマンドの代替方法を徹底比較

CMakeのstring()コマンドは、文字列処理を行うための強力なツールです。C++のstd::stringのような機能に加え、CMake特有の便利な機能も備えています。主な機能文字列の連結、分割、置換、比較大文字・小文字変換部分文字列の抽出


CMake include() で効率的なビルドを実現

include() は CMake の重要なコマンドの一つで、他の CMake ファイルやモジュールを読み込むために使用されます。 これにより、コードを分割し、再利用性と保守性を向上させることができます。機能他の CMake ファイルを読み込んで、その中のコマンドを実行する



CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES とは?メモリ管理の誤りを検出する Xcode の機能

CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES は CMake の変数で、Xcode プロジェクトで生成されるスキームの「診断」セクションで「Malloc Guard Edges」機能を有効にするかどうかを制御します。


CMakeの CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION 変数:Windows 10 SDKのバージョンを指定する方法

CMake 変数 CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION は、Visual Studio 2015 以降で Windows 10 以上のターゲットをビルドする場合、使用する Windows SDK のバージョンを指定するために使用されます。


警告メッセージの原因は? CMakeポリシー「CMP0050」の動作と設定方法を完全理解

CMakeポリシー「CMP0050」は、プロジェクトのソースディレクトリを変更する際の動作を制御します。このポリシーは、CMake 3.13で導入され、デフォルトで有効になっています。影響を受けるユーザー以下のいずれかに該当する場合は、このポリシーの影響を受けます。


CMakeにおけるCMAKE_CROSSCOMPILING変数の詳細解説

CMAKE_CROSSCOMPILING変数は、CMakeがクロスコンパイル環境で実行されているかどうかを判断するために使用されます。これは、ターゲットプラットフォームとビルドプラットフォームが異なる場合に設定されます。設定方法CMAKE_CROSSCOMPILING変数は、以下の方法で設定できます。


CMake で Objective-C プロジェクトをビルドするメリットとデメリット

CMakeでObjective-Cプロジェクトをビルドするには、環境変数 を設定する必要があります。環境変数は、コンパイラやリンカーなどのツールが、Objective-Cソースコードをどのようにコンパイルし、リンクするかを指示するために使用されます。