CMake の VISIBILITY_INLINES_HIDDEN プロパティとは?

2024-04-02

CMake の VISIBILITY_INLINES_HIDDEN プロパティ

VISIBILITY_INLINES_HIDDEN は、CMake のターゲットプロパティの一つであり、インライン化された関数の可視性を制御します。このプロパティを設定することで、コンパイル時にインライン化された関数を外部モジュールから見えないようにすることができます。

設定方法

VISIBILITY_INLINES_HIDDEN プロパティは、ターゲットの set_target_properties() コマンドで設定できます。以下は、VISIBILITY_INLINES_HIDDEN プロパティを ON に設定する例です。

set_target_properties(my_target PROPERTIES
  VISIBILITY_INLINES_HIDDEN ON
)

効果

VISIBILITY_INLINES_HIDDEN プロパティが ON に設定されると、ターゲットに含まれるインライン化された関数は、以下のようになります。

  • 同じターゲット内の他のコンパイルユニットからは参照可能
  • 他のターゲットからは参照不可

使用例

VISIBILITY_INLINES_HIDDEN プロパティは、以下のような場合に使用できます。

  • 内部実装の詳細を隠蔽したい場合
  • コードサイズを削減したい場合

注意点

  • VISIBILITY_INLINES_HIDDEN プロパティは、C++ のコンパイラのみでサポートされます。
  • このプロパティを設定すると、デバッグが難しくなる場合があります。

補足

  • VISIBILITY_INLINES_HIDDEN プロパティは、VISIBILITY_PRIVATE プロパティと似ていますが、インライン化された関数のみを対象としています。
  • VISIBILITY_INLINES_HIDDEN プロパティは、GCC や Clang などの最近のコンパイラでのみ使用できます。

用語解説

  • インライン化:コンパイラが関数の呼び出し箇所を直接コードで置き換えること
  • 可視性:他のモジュールから関数が参照できるかどうか
  • 上記の説明は、基本的な内容のみを記載しています。詳細は、上記の参考資料を参照してください。
  • ご質問やご不明な点があれば、お気軽にご連絡ください。


CMake の VISIBILITY_INLINES_HIDDEN プロパティのサンプルコード

シンプルな例

# 共通ヘッダーファイル
# my_header.h

void foo();

# ターゲット1
# my_target1.cpp

#include "my_header.h"

void foo() {
  // ...
}

# ターゲット2
# my_target2.cpp

#include "my_header.h"

void bar() {
  // foo() は参照できない
}

# CMakeLists.txt

add_library(my_target1 SHARED my_target1.cpp)
add_library(my_target2 SHARED my_target2.cpp)

target_link_libraries(my_target2 my_target1)

set_target_properties(my_target1 PROPERTIES
  VISIBILITY_INLINES_HIDDEN ON
)

特定の関数のみを隠蔽する例

# 共通ヘッダーファイル
# my_header.h

void foo();
void bar();

# ターゲット1
# my_target1.cpp

#include "my_header.h"

void foo() {
  // ...
}

void bar() {
  // ...
}

# ターゲット2
# my_target2.cpp

#include "my_header.h"

void baz() {
  // foo() は参照できる
  foo();
  // bar() は参照できない
}

# CMakeLists.txt

add_library(my_target1 SHARED my_target1.cpp)
add_library(my_target2 SHARED my_target2.cpp)

target_link_libraries(my_target2 my_target1)

set_target_properties(my_target1 PROPERTIES
  VISIBILITY_INLINES_HIDDEN ON
)

set_target_properties(my_target1 PROPERTIES
  VISIBILITY_PUBLIC "foo"
)

この例では、my_target1 ターゲットに含まれる foo() 関数はインライン化され、外部モジュールからは参照可能になります。一方、bar() 関数はインライン化され、外部モジュールからは参照不可になります。

ネームスペースと組み合わせる例

# 共通ヘッダーファイル
# my_header.h

namespace my_ns {
void foo();
}

# ターゲット1
# my_target1.cpp

#include "my_header.h"

namespace my_ns {
void foo() {
  // ...
}
}

# ターゲット2
# my_target2.cpp

#include "my_header.h"

void bar() {
  // my_ns::foo() は参照できない
}

# CMakeLists.txt

add_library(my_target1 SHARED my_target1.cpp)
add_library(my_target2 SHARED my_target2.cpp)

target_link_libraries(my_target2 my_target1)

set_target_properties(my_target1 PROPERTIES
  VISIBILITY_INLINES_HIDDEN ON
)

set_target_properties(my_target1 PROPERTIES
  VISIBILITY_PUBLIC "my_ns::foo"
)

この例では、my_target1 ターゲットに含まれる my_ns::foo() 関数はインライン化され、外部モジュールからは参照可能になります。一方、my_ns ネームスペース内の他の関数はインライン化され、外部モジュールからは参照不可になります。

静的ライブラリと組み合わせる例

# 共通ヘッダーファイル
# my_header.h

void foo();

# 静的ライブラリ
# my_static_lib.cpp

#include "my_header.h"

void foo() {
  // ...
}

# ターゲット1
# my_target1.cpp

#include "my_header.h"

void bar() {
  // foo() は参照できる
  foo();
}

# CMakeLists.txt

add_library(my_static_lib


CMake の VISIBILITY_INLINES_HIDDEN プロパティの代替方法

  • すべてのコンパイラでサポートされているわけではない
  • デバッグが難しくなる場合がある
  • コードの読みやすさが低下する場合がある

これらの欠点を回避するために、以下の代替方法を使用することができます。

関数を static にする

static キーワードを使用して関数を宣言すると、その関数は現在のコンパイルユニット内でのみ有効になります。

static void foo() {
  // ...
}

この方法は、すべてのコンパイラでサポートされており、デバッグも容易です。ただし、コードの読みやすさが低下する場合があります。

マクロを使用して、インライン化された関数の可視性を制御することができます。

#ifndef FOO_HIDDEN
#define FOO_HIDDEN static
#endif

FOO_HIDDEN void foo() {
  // ...
}

この方法は、コードの読みやすさを維持しながら、可視性を制御することができます。ただし、マクロの使用方法を誤ると、予期せぬ問題が発生する可能性があります。

ネームスペースを使用して、関数の可視性を制御することができます。

namespace my_ns {
void foo() {
  // ...
}
}

この方法は、コードの読みやすさを維持しながら、可視性を制御することができます。ただし、ネームスペースの入れ子構造が複雑になると、コードの管理が難しくなる場合があります。

オブジェクトファイルを使用する

インライン化された関数を個別のオブジェクトファイルにコンパイルし、そのオブジェクトファイルをリンクすることができます。

add_library(my_lib OBJECT my_lib.cpp)

target_link_libraries(my_target my_lib)

この方法は、可視性を細かく制御することができます。ただし、コンパイルとリンクの手順が複雑になる場合があります。

どの方法を選択するべきかは、具体的な状況によって異なります。以下の点を考慮する必要があります。

  • 使用しているコンパイラ
  • デバッグの容易さ
  • コードの読みやすさ
  • 可視性の制御レベル

VISIBILITY_INLINES_HIDDEN プロパティは、インライン化された関数の可視性を制御する便利な方法ですが、いくつかの欠点もあります。これらの欠点を回避するために、上記の代替方法を使用することができます。




CMakeでXcodeプロジェクトを極める! "Properties: Source Files"と"XCODE_LAST_KNOWN_FILE_TYPE"の達人になるためのテクニック

この情報は、Xcode がファイルを開いたり、編集したり、ビルドしたりする際にどのように扱うかを決定するために使用されます。Properties: Source Files は、CMakeLists. txt ファイルで設定できます。 以下の例は、main



Visual Studioでシェーダーファイルをコンパイルする:CMakeのVS_SHADER_FLAGSオプション

CMake の "Properties: Source Files" に設定できる "VS_SHADER_FLAGS" は、Visual Studio でシェーダーファイルのコンパイル時に渡されるオプションを指定します。このオプションは、シェーダーの動作やコンパイル方法を制御するために使用されます。


CMake で C++/CLI プログラミング: .NET Framework バージョン設定のベストプラクティス

"VS_DOTNET_TARGET_FRAMEWORK_VERSION" プロパティは、CMake で C++/CLI プロジェクトをビルドする際に、ターゲットとなる . NET Framework のバージョンを指定するために使用されます。これは、Visual Studio ソリューション (.sln) ファイルとプロジェクト (.vcxproj) ファイルの生成に影響を与えます。


CMakeでVisual Studio IDEの設定を制御:VS_SOURCE_SETTINGS_tool徹底解説

主な機能:Visual Studio IDEでのターゲット表示: ターゲットの表示名、アイコン、説明を設定できます。 ターゲットをフォルダ構造にどのように配置するかを制御できます。ターゲットの表示名、アイコン、説明を設定できます。ターゲットをフォルダ構造にどのように配置するかを制御できます。


CMakeで.NETプロジェクトをビルドする際のVS_DOTNET_REFERENCES_COPY_LOCALプロパティの役割

VS_DOTNET_REFERENCES_COPY_LOCAL は、CMake で .NET プロジェクトをビルドする際に、参照されているアセンブリを出力ディレクトリにコピーするかどうかを制御するプロパティです。デフォルトでは ON に設定されており、参照されているアセンブリは出力ディレクトリにコピーされます。



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

CMAKE_Fortran_MODDIR_FLAGは、Fortranモジュールの出力ディレクトリを指定するために使用するCMake変数です。この変数は、Fortranコンパイラにモジュールファイルを保存する場所を指示するために使用されます。


C言語コンパイラとCMakeの連携を強化! CMAKE_C_KNOWN_FEATURES で開発効率アップ

CMAKE_C_KNOWN_FEATURESは、CMakeのグローバルスコーププロパティであり、C言語コンパイラで利用可能なC言語機能のリストを格納します。このプロパティは、ターゲットのコンパイル時に特定の機能を有効化/無効化するために使用できます。


AUTOGEN_TARGET_DEPENDS以外の選択肢:CMakeで生成されたファイルに依存関係を設定する他の方法

概要ターゲット: AUTOGEN_TARGET_DEPENDS は、AUTOMOC または AUTOUIC プロパティが有効になっているターゲットにのみ影響します。依存関係: このプロパティは、生成されるファイルに必要なその他のファイルやターゲットを指定するために使用されます。


CMAKE_TLS_VERIFY:環境変数、GUI、C++コードなど、多彩な設定方法

CMAKE_TLS_VERIFY は、CMake の Variables における重要な設定項目です。これは、file(DOWNLOAD) や file(UPLOAD) コマンド、および ExternalProject や FetchContent モジュールによる内部的な file(DOWNLOAD) 呼び出しにおいて、TLS 検証 を有効にするかどうかを制御します。


CMakeでテスト実行中に特定の警告メッセージでテストを失敗させる方法

概要目的: 特定の警告メッセージが出力された場合に、テストを失敗させる使用場面: テスト実行中に特定の警告メッセージが出力されることが想定される場合設定方法: CMakeLists. txtファイルでset()コマンドを使用動作: テスト実行中に標準出力または標準エラー出力に指定された警告メッセージが出力された場合、テストが失敗する