4Dまとめ作成ツールCMakeでエントリーから実際のプロジェクト実践まで!

1.CMakeとは何ですか

GNU Make、QT の qmake、Microsoft の MS nmake、BSD Make (pmake)、Makepp など、いくつかの Make ツールについて聞いたことがあるかもしれません。これらの Make ツールはさまざまな規範や標準に従っており、実行される Makefile の形式は大きく異なります。これは深刻な問題を引き起こします。ソフトウェアがクロスプラットフォームであることを望む場合、異なるプラットフォーム上でコンパイルできることが保証されなければなりません。また、上記の Make ツールを使用する場合は、規格ごとに Makefile を作成する必要があり、大変な作業になります。

CMake は、上記の問題に対処するために設計されたツールです。まず、開発者がプラットフォームに依存しない CMakeList.txt ファイルを作成してコンパイル プロセス全体をカスタマイズできるようにし、次にターゲット ユーザーのプラットフォームに応じて、必要なローカライズされた Makefile とプロジェクト ファイルをさらに生成します。 Unix の場合は Makefile、Windows の場合は Visual Studio プロジェクトなど。「一度書けばどこでも実行できる」を実現するために。明らかに、CMake は、上記の make よりも高度なコンパイルおよび構成ツールです。プロジェクト アーキテクチャ システムとして CMake を使用するよく知られたオープン ソース プロジェクトには、VTK、ITK、KDE、OpenCV、OSG などが含まれます [1]。

CMake は私がとても気に入っており、いつも使っているツールです。これは、クロスプラットフォームおよびクロスコンパイラーに役立つだけでなく、ストレージスペースを大幅に節約できることです。特に水銀と組み合わせて使用​​すると、そのフレンドリーな経験は、私たち勤勉なプログラマーに少しの慰めを与えるのに十分です。

次の内容は、公式 Web サイトのチュートリアルから翻訳されたものです: CMake

1.1CMake チュートリアル

基本的な開始点 (ステップ 1)

最も基本的な方法は、ソース コード ファイルを exe 実行可能プログラムにコンパイルすることです。単純なプロジェクトの場合は、2 行の CMakeLists.txt ファイルで十分です。これがチュートリアルの始まりになります。CMakeLists.txt ファイルは次のようになります。

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)

この例では、CMakeLists.txt にはすべて小文字が使用されていることに注意してください。実際、CMake コマンドでは大文字と小文字が区別されず、大文字、小文字、または混合を使用できます。tutorial.cxx ソース コードは数値の平方根を計算します。最初のバージョンは次のように非常にシンプルに見えます。

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

バージョン番号と設定されたヘッダー ファイルの追加

追加する最初の機能は、プロジェクトと実行可能プログラムにバージョン番号を追加することです。これをソース コードで直接実行することもできますが、CMakeLists ファイルを使用して実行すると、より柔軟性が高まります。バージョン番号を増やすには、次のように CMakeLists ファイルを変更します。

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
 
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
 
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")
 
# add the executable
add_executable(Tutorial tutorial.cxx) 

設定ファイルはバイナリ ツリーに書き込む必要があるため、このディレクトリをヘッダー ファイル検索ディレクトリに追加する必要があります。次に、ソース コード ディレクトリに次の内容のhttp://TutorialConfig.h.inファイルを作成しました。

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

CMake がこのヘッダーを設定すると、@Tutorial_VERSION_MAJOR@ と @Tutorial_VERSION_MINOR@ の値が変更されます。次に、tutorial.cxx を変更して構成ヘッダーを組み込み、バージョン番号を使用します。最終的なソースコードは次のようになります。

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n",
            argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
  double inputValue = atof(argv[1]);
  double outputValue = sqrt(inputValue);
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
}

最も重要な変更は、TutorialConfig.h ヘッダー ファイルが含まれ、バージョン番号がエクスポートされたことです。

ライブラリの追加 (ステップ 2)

次に、プロジェクトにライブラリを追加します。このライブラリには、独自の平方根実装が含まれます。このようにして、アプリケーションはコンパイラによって提供されるライブラリの代わりにこのライブラリを使用できます。このチュートリアルでは、ライブラリを MathFunctions というサブフォルダーに配置します。

次のような 1 行の CMakeLists ファイルを使用します。

add_library(MathFunctions mysqrt.cxx)

元のファイル mysqrt.cxx には、コンパイラの sqrt と同様の機能を提供する mysqrt という関数があります。新しいライブラリを使用するには、トップレベルの CMakeLists ファイルに add_subdirectory への呼び出しを追加する必要があります。また、MathFunctions/mysqrt.h を検索できるように、ヘッダー ファイル検索ディレクトリを追加します。最後の変更は、新しいライブラリを実行可能ファイルに追加することです。最上位の CMakeLists ファイルは次のようになります。

include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory (MathFunctions) 
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions) 

ここで、MathFunctions ライブラリをオプションにする方法を考えてみましょう。このチュートリアルでこれを行う理由はありませんが、より大きなライブラリを使用する場合、またはサードパーティのライブラリに依存する場合は、そうすることをお勧めします。最初のステップは、トップレベルの CMakeLists ファイルにオプションを追加することです。

# should we use our own math functions?
option (USE_MYMATH 
        "Use tutorial provided math implementation" ON) 

このオプションは CMake GUI に表示され、デフォルト値は ON です。ユーザーが選択すると、この値は CACHE に保存されるため、CMAKE のたびに値を変更する必要はありません。次のステップでは、条件付きで MathFunctions ライブラリを構築してリンクします。これを行うには、トップレベルの CMakeLists ファイルを次のように変更します。

# add the MathFunctions library?
#
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})

ここで、USE_MYMATH は、MathFunction をコンパイルして使用するかどうかを決定するために使用されます。ここで変数 EXTRA_LIBS が使用されていることに注意してください。これは、大規模なプロジェクトをきれいに保つ方法です。ソース コード内の対応する変更は比較的単純です。

// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
 
int main (int argc, char *argv[])
{
  if (argc < 2)
    {
    fprintf(stdout,"%s Version %d.%d\n", argv[0],
            Tutorial_VERSION_MAJOR,
            Tutorial_VERSION_MINOR);
    fprintf(stdout,"Usage: %s number\n",argv[0]);
    return 1;
    }
 
  double inputValue = atof(argv[1]);
 
#ifdef USE_MYMATH
  double outputValue = mysqrt(inputValue);
#else
  double outputValue = sqrt(inputValue);
#endif
 
  fprintf(stdout,"The square root of %g is %g\n",
          inputValue, outputValue);
  return 0;
} 

ソース コードでは USE_MYMATH マクロも使用します。これは、構成ファイルhttp://TutorialConfig.h.inを通じて CMAKE によってソース コードに提供されます。

#cmakedefine USE_MYMATH

インストールとテスト (ステップ 3)

次に、インストール ルールとテスト サポートをプロジェクトに追加します。インストールのルールは非常にシンプルです。MathFunctions ライブラリの場合、次のステートメントを追加するだけで、ライブラリとヘッダー ファイルをインストールできます。

install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

アプリケーションの場合、実行可能プログラムと構成されたヘッダー ファイルをインストールするために、最上位の CMakeLists ファイルでアプリケーションを構成するだけで済みます。

# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"        
         DESTINATION include)

それだけです。これで、このチュートリアルをコンパイルしてから、make install と入力 (または IDE で INSTALL ターゲットをコンパイル) できるようになり、ヘッダー ファイル、ライブラリ、実行可能プログラムなどが正しくインストールされます。CMake 変数 CMAKE_INSTALL_PREFIX は、これらのファイルがどのルート ディレクトリにインストールされるかを決定するために使用されます。テストの追加も非常に簡単なプロセスです。最上位の CMakeLists ファイルの最後に、プログラムが正しく動作していることを確認するための一連の基本テストを追加できます。

# does the application run
add_test (TutorialRuns Tutorial 25)
 
# does it sqrt of 25
add_test (TutorialComp25 Tutorial 25)
 
set_tests_properties (TutorialComp25 
  PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")
 
# does it handle negative numbers
add_test (TutorialNegative Tutorial -25)
set_tests_properties (TutorialNegative
  PROPERTIES PASS_REGULAR_EXPRESSION "-25 is 0")
 
# does it handle small numbers
add_test (TutorialSmall Tutorial 0.0001)
set_tests_properties (TutorialSmall
  PROPERTIES PASS_REGULAR_EXPRESSION "0.0001 is 0.01")
 
# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
  PROPERTIES 
  PASS_REGULAR_EXPRESSION "Usage:.*number")

最初のテストは、アプリケーションがセグメンテーション違反やその他のクラッシュなしで実行されることを確認するだけであり、0 を返します。これは CTest の最も基本的な形式です。次のテストはすべて PASS_REGULAR_EXPRESSION テスト属性を使用して、出力に特定の文字列が含まれているかどうかを確認します。さまざまな入力値に対して多数のテストを追加する必要がある場合は、次のようなマクロの作成を検討することをお勧めします。

#define a macro to simplify adding tests, then use it
macro (do_test arg result)
  add_test (TutorialComp${arg} Tutorial ${arg})
  set_tests_properties (TutorialComp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
 
# do a bunch of result based tests
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")

do_test を呼び出すと、別のテストがプロジェクトに追加されます。

システムイントロスペクションの追加 (ステップ 4)

次に、一部のターゲット プラットフォームがサポートしていない可能性のあるコードを追加することを検討してみましょう。この例では、ターゲット プラットフォームに log 関数と exp 関数があるかどうかに応じてコードを追加します。もちろん、ほとんどのプラットフォームにはこれらの機能がありますが、このチュートリアルでは、これら 2 つの機能があまり一般的にサポートされていないことを前提としています。プラットフォームにログがある場合は、mysqrt でそれを使用して平方根を計算します。まず、トップレベルの CMakeLists ファイルの CheckFunctionExists.cmake を使用して、これらの関数の存在をテストします。

# does this system provide the log and exp functions?
include (CheckFunctionExists.cmake)
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)

次に、http://TutorialConfig.h.inを変更して、 CMake がこれらの関数のマクロを見つけるかどうかを定義します。

// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

重要な点は、構成ファイルのコマンドを実行する前にテストとログを完了する必要があるということです。profile コマンドは、CMake の構成ファイルをすぐに使用します。最後に、mysqrt 関数では、2 つの実装メソッドを提供します。

// if we have both log and exp then use them
#if defined (HAVE_LOG) && defined (HAVE_EXP)
  result = exp(log(x)*0.5);
#else // otherwise use an iterative approach
  . . .

生成されたファイルとジェネレーターの追加 (ステップ 5)

このセクションでは、生成されたソース ファイルをアプリケーションのビルド プロセスに含める方法を説明します。この例では、事前計算された平方根のテーブルを作成し、このテーブルをアプリケーションにコンパイルします。これを実現するには、まずそのようなテーブルを生成するプログラムが必要です。MathFunctions サブディレクトリにある MakeTable.cxx という新しいソース ファイルがまさにそれを行います。

// A simple program that builds a sqrt table 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main (int argc, char *argv[])
{
  int i;
  double result;
 
  // make sure we have enough arguments
  if (argc < 2)
    {
    return 1;
    }
  
  // open the output file
  FILE *fout = fopen(argv[1],"w");
  if (!fout)
    {
    return 1;
    }
  
  // create a source file with a table of square roots
  fprintf(fout,"double sqrtTable[] = {\n");
  for (i = 0; i < 10; ++i)
    {
    result = sqrt(static_cast<double>(i));
    fprintf(fout,"%g,\n",result);
    }
 
  // close the table with a zero
  fprintf(fout,"0};\n");
  fclose(fout);
  return 0;
}

このテーブルは有効な C++ コードによって生成され、出力ファイルの名前がパラメーターに置き換えられることに注意してください。次のステップでは、適切なコマンドを MathFunctions CMakeLists ファイルに追加して、ビルド プロセスの一部として MakeTable 実行可能ファイルをビルドします。これを行うには、次のようないくつかのコマンドが必要です。

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
 
# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  )
 
# add the binary tree directory to the search path for 
# include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h  )

まず、他の実行可能ファイルと同様に、MakeTable が実行可能ファイルとして追加されます。次に、MakeTable を実行して Table.h を生成する方法を詳しく説明するカスタム コマンドを追加しました。次に、mysqrt.cxx が生成されたファイル Table.h に依存していることを CMake に知らせる必要があります。これは、生成された Table.h を MathFunctions ライブラリに追加することで実現されます。また、mysqrt.cxx で Table.h を見つけられるように、現在のビルド ディレクトリを検索パスに追加する必要があります。

このプロジェクトをビルドすると、最初に実行可能プログラム MakeTable がビルドされます。次に、MakeTable を実行して Table.h を生成します。最後に、mysqrt.cxx をコンパイルして MathFunctions ライブラリを生成します。

この時点で、すべての機能を最上位の CMakeLists ファイルに追加しました。ファイルは次のようになります。

cmake_minimum_required (VERSION 2.6)
project (Tutorial)
 
# The version number.
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
 
# does this system provide the log and exp functions?
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
 
check_function_exists (log HAVE_LOG)
check_function_exists (exp HAVE_EXP)
 
# should we use our own math functions
option(USE_MYMATH 
  "Use tutorial provided math implementation" ON)
 
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )
 
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories ("${PROJECT_BINARY_DIR}")
 
# add the MathFunctions library?
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)
 
# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})
 
# add the install targets
install (TARGETS Tutorial DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"        
         DESTINATION include)
 
# does the application run
add_test (TutorialRuns Tutorial 25)
 
# does the usage message work?
add_test (TutorialUsage Tutorial)
set_tests_properties (TutorialUsage
  PROPERTIES 
  PASS_REGULAR_EXPRESSION "Usage:.*number"
  )
 
 
#define a macro to simplify adding tests
macro (do_test arg result)
  add_test (TutorialComp${arg} Tutorial ${arg})
  set_tests_properties (TutorialComp${arg}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result}
    )
endmacro (do_test)
 
# do a bunch of result based tests
do_test (4 "4 is 2")
do_test (9 "9 is 3")
do_test (5 "5 is 2.236")
do_test (7 "7 is 2.645")
do_test (25 "25 is 5")
do_test (-25 "-25 is 0")
do_test (0.0001 "0.0001 is 0.01")

TutorialConfig.h は次のようになります。

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
#cmakedefine USE_MYMATH
 
// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

MathFunctions の最終的な CMakeLists ファイルは次のようになります。

# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
# add the command to generate the source code
add_custom_command (
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  )
# add the binary tree directory to the search path 
# for include files
include_directories( ${CMAKE_CURRENT_BINARY_DIR} )
 
# add the main library
add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h)
 
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

インストーラーの構築 (ステップ 6)

最後に、プロジェクトを他の人に配布して使用できるようにしたいとします。私たちは、さまざまなプラットフォーム用のバイナリとソース コードを同時に提供したいと考えています。これは、ソースからビルドしたバイナリをインストールするステップ 3 のインストールとは少し異なります。この例では、バイナリ インストールと cygwin、debian、RPM などのパッケージ管理機能をサポートするインストール パッケージを構築します。この目的のために、CPack を使用してプラットフォーム固有のインストール パッケージを作成します。具体的には、トップレベルの CMakeLists.txt ファイルの最後に数行を追加する必要があります。

# build a CPack driven installer package
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE  
     "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
set (CPACK_PACKAGE_VERSION_PATCH "${Tutorial_VERSION_PATCH}")
include (CPack)

それだけです。まず、InstallRequiredSystemLibraries を組み込みました。このモジュールには、現在のプラットフォームで必要なすべてのランタイム ライブラリが含まれます。次に、ライセンスとプロジェクトのバージョン情報を保存するためにいくつかの Cpack 変数を設定します。バージョン情報には、前のチュートリアルで使用した変数が使用されます。最後に、パッケージのセットアップに使用しているシステムのこれらの変数やその他の機能を使用するために、CPack モジュールを組み込みました。

次のステップでは、通常の方法でプロジェクトをビルドし、CPack 上で実行します。バイナリ パッケージをビルドするには、以下を実行する必要があります。

cpack --config CPackConfig.cmake

閉じたコード パッケージを作成する場合は、次のように入力する必要があります。

cpack --config CPackSourceConfig.cmake

ダッシュボードのサポートの追加 (ステップ 7)

テスト結果をダッシュ​​ボードにアップロードするのは非常に簡単です。前のステップでいくつかのテストを定義しました。これらのルーチンを実行してダッシュボードに送信するだけです。ダッシュボードのサポートを含めるには、最上位の CMakeLists ファイルに CTest モジュールを含める必要があります。

# enable dashboard scripting
include (CTest)

また、Dashobard でプロジェクトの名前を指定するための CTestConfig.cmake ファイルも作成しました。

set (CTEST_PROJECT_NAME "Tutorial")

CTest はこのファイルを読み取って実行します。単純なダッシュボードを作成するには、プロジェクトで CMake を実行し、ビルド パスのディレクトリを変更して、ctest -D Experimental を実行します。ダッシュボードの結果は、Kitware のパブリック ダッシュボードにアップロードされます。

CMake を使用して Makefile を生成し、Linux プラットフォームでコンパイルするプロセスは次のとおりです。

  1. CMake 構成ファイル CMakeLists.txt を書き込みます。
  2. コマンドの実行cmake PATHccmake PATHMakefile 1 1 の生成の違いはccmakecmake前者は対話型インターフェイスを提供することです。その中には、PATHCMakeLists.txt が配置されているディレクトリがあります。
  3. makeコマンドを使用してコンパイルします。

この記事では例から始めて、CMake の一般的な使用法をステップごとに説明します。この記事のサンプル コードはすべてここにあります。これを読んでもまだ圧倒されていると感じる場合は、記事の最後にある他のリソースを引き続き学習してください。

1.2 CMake ガイド チュートリアル (公式アドレス)

CMake チュートリアルでは、CMake が役立つ一般的なビルド システムの問題をカバーする段階的な手順が提供されます。サンプル プロジェクトでさまざまなテーマがどのように連携するかを確認すると役立ちます。チュートリアル ドキュメントとサンプルのソース コードは、CMake ソース ツリーのディレクトリにありHelp/guide/tutorialます各ステップには、開始点として使用できるコードを含む独自のサブディレクトリがあります。チュートリアルの例は段階的に行われるため、各ステップでは前のステップの完全なソリューションが提供されます。

(ステップ1) 基本的な出発点

最も基本的なプロジェクトは、ソース コード ファイルから実行可能ファイルをビルドします。単純なプロジェクトの場合、CMakeLists.txt必要なファイルは 3 行だけです。これがこのチュートリアルの開始点です。次のように、Step1 ディレクトリに CMakeLists.txt ファイルを作成します。

cmake_minimum_required(VERSION 3.10)  
# set the project name project(Tutorial)  
# add the executable add_executable(Tutorial tutorial.cxx)

この例では、CMakeLists.txtファイル内で小文字のコマンドが使用されていることに注意してください。CMake は、大文字、小文字、および大文字と小文字の混合コマンドをサポートします。Step1 ディレクトリにあるソース コードは、tutorial.cxx数値の平方根を計算するために使用できます。

バージョン番号を追加し、ヘッダー ファイルを構成します

追加する最初の機能は、実行可能ファイルとプロジェクトにバージョン番号を付けることです。ソース コード内でこれを行うこともできますが、 を使用しますCMakeLists.txt

まず、CMakeLists.txtファイルを変更してバージョン番号を設定します。

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(Tutorial VERSION 1.0)

###早期版本的写法
###		project(Tutorial)
###		set (Tutorial_VERSION_MAJOR 1)
###		set (Tutorial_VERSION_MINOR 0)

次に、ソース コードにバージョン番号を渡すようにヘッダー ファイルを構成します。

configure_file(TutorialConfig.h.in TutorialConfig.h)

###早期版本的写法
###configure_file ("${PROJECT_SOURCE_DIR}/TutorialConfig.h.in" "${PROJECT_BINARY_DIR}/TutorialConfig.h")

設定されたファイルはバイナリ ツリーに書き込まれるため、インクルード ファイルを検索するパスのリストにこのディレクトリを追加する必要があります。ファイルの最後にCMakeLists.txt次の行を追加します。

#必须在add_excutable之后
target_include_directories(Tutorial PUBLIC  "${PROJECT_BINARY_DIR}")
###早期版本的写法:
###可以位于任意位置,一般放在add_excutable之前
###include_directories("${PROJECT_BINARY_DIR}")

TutorialConfig.h.inお気に入りのエディタを使用して、次の内容を含むソース ディレクトリを作成します。

// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

CMake がこのヘッダーを構成すると、@Tutorial_VERSION_MAJOR@ と @Tutorial_VERSION_MINOR@ の値が置き換えられます。次に、tutorial.cxx を変更して、構成ヘッダー ファイル TutorialConfig.h を含めます。最後に、次のようにtutorial.cxxを更新してバージョン番号を出力します。

 if (argc < 2) {
    // report version
    std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
              << Tutorial_VERSION_MINOR << std::endl;
    std::cout << "Usage: " << argv[0] << " number" << std::endl;
    return 1;
  }

次のように完了しますCMakeLists.txt

cmake_minimum_required(VERSION 3.10)

#set project name and version
project(Tutorial VERSION 1.0)

configure_file(TutorialConfig.h.in TutorialConfig.h)

#add the executable
add_executable(Tutorial tutorial.cxx)

target_include_directories(Tutorial PUBLIC  "${PROJECT_BINARY_DIR}"  )

C++ 標準を指定する

tutorial.cxx次に、 atof を に置き換えてstd::stodいくつかの C++11 機能をプロジェクトに追加します。また、 を削除します#include <cstdlib>

const double inputValue = std::stod(argv[1]);

正しいフラグを使用する必要があることを CMake コードで明示的に記述する必要があります。CMake で特定の C++ 標準のサポートを有効にする最も簡単な方法は、CMAKE_CXX_STANDARD変数を使用することです。このチュートリアルでは、CMakeLists.txtファイル内の変数をCMAKE_CXX_STANDARD11 に設定し、CMAKE_CXX_STANDARD_REQUIREDTrue に設定します。

cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

ビルドしてテストする

cmake または cmake-gui を実行してプロジェクトを構成し、選択したビルド ツールを使用してビルドします。たとえば、コマンド ラインから CMake ソース ツリーのディレクトリに移動しHelp /guide/tutorial、次のコマンドを実行できます。

mkdir Step1_build
cd Step1_build
cmake ../Step1
cmake --build .

チュートリアルをビルドしたディレクトリ (おそらく make ディレクトリ、または Debug または Release ビルド構成サブディレクトリ) に移動し、次のコマンドを実行します。

Tutorial 4294967296
Tutorial 10
Tutorial

(ステップ2) ライブラリを追加する

次に、プロジェクトにライブラリを追加します。このライブラリは、数値の平方根を計算するための独自の実装です。実行可能ファイルは、コンパイラが提供する標準の平方根関数の代わりにこのライブラリを使用できます。

このチュートリアルでは、ライブラリをMathFunctionsという名前のサブディレクトリに置きます。このディレクトリには、ヘッダー ファイルMathFunctions.hとソース ファイルがすでに含まれていますmysqrt.cxxソース ファイルには と呼ばれる関数があり、mysqrtコンパイラの関数とsqrt同様の機能を提供します。

ディレクトリ内のCMakeLists.txtファイルに次の行を追加します。MathFunctions

add_library(MathFunctions mysqrt.cxx)

新しいライブラリを使用するには、CMakeLists.txt最上位ファイルへの呼び出しを追加してadd_subdirectoryライブラリを構築します。新しいライブラリを実行可能ファイルに追加し、ヘッダー ファイルが見つかるMathFunctionsようにインクルード ディレクトリとして追加します。mqsqrt.h最上位ファイルCMakeLists.txtの最後の数行は次のようになります。

# add the MathFunctions library
add_subdirectory(MathFunctions)

# add the executable
add_executable(Tutorial tutorial.cxx)

#必须位于add_excutable之后
target_link_libraries(Tutorial PUBLIC MathFunctions)

###早期版本的写法
###target_link_libraries(Tutorial MathFunctions)

#add the binary tree to the search path for include files so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}" "${PROJECT_SOURCE_DIR}/MathFunctions")

次に、MathFunctions ライブラリをオプションにしましょう。これはこのチュートリアルでは実際には必要ありませんが、大規模なプロジェクトでは非常に一般的です。最初のステップは、CMakeLists.txt最上位ファイルにオプションを追加することです。

option(USE_MYMATH "Use tutorial provided math implementation" ON)
# configure a header file to pass some of the CMake settings to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)

このオプションは CMake GUI に表示され、ccmake (デフォルト値は ON) はユーザーが変更できます。この設定はキャッシュに保存されるため、ユーザーはビルド ディレクトリで CMake を実行するたびに値を設定する必要はありません。

次の変更は、MathFunctions ライブラリの構築とリンクをブール型オプションにすることです。これを行うには、CMakeLists.txtトップレベル ファイルの末尾を次のように変更します。

if(USE_MYMATH)
  add_subdirectory(MathFunctions)
  list(APPEND EXTRA_LIBS MathFunctions)
  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

# add the executable
add_executable(Tutorial tutorial.cxx)

#必须位于add_executable之后
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})

# add the binary tree to the search path for include files so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}" ${EXTRA_INCLUDES})

###早期版本的写法
##if(USE_MYMATH)
###include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
###add_subdirectory (MathFunctions)
###set(EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
###endif(USE_MYMATH)
###include_directories("${PROJECT_BINARY_DIR}")
###add_executable(Tutorial tutorial.cxx)
###target_link_libraries(Tutorial ${EXTRA_LIBS})

後で実行可能ファイルにリンクするために、変数を使用してEXTRA_LIBSオプションのライブラリを収集することに注意してください。変数はEXTRA_INCLUDESオプションのヘッダーでも同様に使用されます。これは、多くのオプション コンポーネントを扱う場合の古典的なアプローチであり、次のステップで最新のアプローチについて説明します。

ソース コードに対する対応する変更は非常に簡単です。まず、必要に応じてヘッダー ファイルを次の場所にtutorial.cxx含めます。MathFunctions.h

#ifdef USE_MYMATH
#  include "MathFunctions.h"
#endif

次に、同じファイル内で、どの平方根関数が使用されるかを制御する USE_MYMATH を作成します。

#ifdef USE_MYMATH
  const double outputValue = mysqrt(inputValue);
#else
  const double outputValue = sqrt(inputValue);
#endif

ソース コードではこれが必要になるためUSE_MYMATH、次の行でソース コードに追加できますTutorialConfig.h.in

#cmakedefine USE_MYMATH

演習:USE_MYMATHオプションの後に TutorialConfig.h.in を構成することがなぜそれほど重要なのでしょうか? この 2 つを逆にするとどうなるでしょうか? cmake または cmake-gui を実行してプロジェクトを構成し、選択したビルド ツールを使用してビルドします。次に、ビルドされたチュートリアルの実行可能ファイルを実行します。値はccmake または CMake GUI を使用して更新されますUSE_MYMATHチュートリアルを再構築して再度実行します。sqrt と mysqrt のどちらの関数の方が良い結果が得られますか?

完全なCMakeLists.txtファイルは次のとおりです。

cmake_minimum_required(VERSION 3.5)                                                                                  
# set the project name and version
project(Tutorial VERSION 1.0)
 
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_STANDARD_REQUIRED True)
 
option(USE_MYMATH "Use tutorial provided math implementation" ON) 
 
# configure a header file to pass some of the CMake settings to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
 
if(USE_MYMATH)
    add_subdirectory(MathFunctions)
    list(APPEND EXTRA_LIBS MathFunctions)
    list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
 
# add the executable
add_executable(Tutorial tutorial.cxx)

#必须位于add_executable之后
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})  

# add the binary tree to the search path for include files so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC  "${PROJECT_BINARY_DIR}" ${EXTRA_INCLUDES}) 

(ステップ3) ライブラリの利用条件を追加する

要件を使用すると、ライブラリまたは実行可能ファイルのリンクとインクルード行をより細かく制御できると同時に、CMake 内のターゲットの推移的なプロパティをより細かく制御できます。要件の使用を利用するための主なコマンドは次のとおりです。

  • ターゲットコンパイル定義
  • ターゲット ビルド オプション
  • target_include_directories
  • ターゲットライブラリ

ステップ 2 のコードをリファクタリングして、使用要件を記述する最新の CMake アプローチを活用しましょう。まず、MathFunctions にリンクするものには現在のソース ディレクトリを含める必要がありますが、MathFunctions 自体には含める必要がないことを述べます。したがって、これはINTERFACE使用要件になる可能性があります。

INTERFACE消費者が望むものは、生産者が望まないものであることを忘れないでください。次の行を のMathFunctions/CMakeLists.txt最後に追加します。

target_include_directories(MathFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR)

MathFunction の使用要件を指定したので、トップレベルから変数の使用を安全にCMakeLists.txt削除できます。EXTRA_INCLUDES

if(USE_MYMATH)
  add_subdirectory(MathFunctions)
  list(APPEND EXTRA_LIBS MathFunctions)
endif()
... ...
... ...

target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")

(ステップ 4) インストールとテスト

これで、プロジェクトへのインストール ルールの追加とサポートのテストを開始できます。

インストール ルールは非常に単純です。MathFunctions の場合はライブラリとヘッダーをインストールし、アプリケーションの場合は実行可能ファイルと構成されたヘッダーをインストールします。

したがって、MathFunctions/CMakeLists.txt次の行の最後に追加します。

install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

次に、トップレベルの cmakelt.txt の最後に追加します。

install(TARGETS Tutorial DESTINATION bin)
install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)

このチュートリアルの基本的なローカル インストールを作成するのに必要なのはこれだけです。cmake または cmake-gui を実行してプロジェクトを構成し、選択したビルド ツールを使用してビルドします。コマンド ラインからインストールするcmake --install場合は (3.15 以降に導入され、CMake の以前のバージョンでは make install を使用する必要があります)、INSTALLIDE からターゲットをビルドします。これにより、適切なヘッダー、ライブラリ、および実行可能ファイルがインストールされます。

CMake 変数は、CMAKE_INSTALL_PREFIXファイルのインストール ルート ディレクトリを決定するために使用されます。使用する場合cmake --install--prefixパラメータを介してカスタム インストール ディレクトリを指定できます。複数構成ツールの場合は、--configパラメーターを使用して構成を指定します。

インストールされたチュートリアルが動作することを確認します。

テストサポート

次に、アプリケーションをテストします。CMakeLists.txt最上位ファイルの最後でテストを有効にし、アプリケーションが正しく動作していることを確認するための基本的なテストを追加します

enable_testing()

# does the application run
add_test(NAME Runs COMMAND Tutorial 25)

# does it sqrt of 25
add_test (NAME Comp25 COMMAND Tutorial 25)
set_tests_properties (Comp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")

# does the usage message work?
add_test(NAME Usage COMMAND Tutorial)
set_tests_properties(Usage  PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")

# define a function to simplify adding tests
function(do_test target arg result)
  add_test(NAME Comp${arg} COMMAND ${target} ${arg})
  set_tests_properties(Comp${arg}  PROPERTIES PASS_REGULAR_EXPRESSION ${result} )
endfunction(do_test)

# do a bunch of result based tests
do_test(Tutorial 4 "4 is 2")
do_test(Tutorial 9 "9 is 3")
do_test(Tutorial 5 "5 is 2.236")
do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is [-nan|nan|0]")
do_test(Tutorial 0.0001 "0.0001 is 0.01")

###早期版本的写法
###include(CTest)
###add_test (TutorialRuns Tutorial 25)
###
###add_test (TutorialComp25 Tutorial 25)
###set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION "25 is 5")
###
##add_test (TutorialUsage Tutorial)
###set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number")
###
####define a macro to simplify adding tests, then use it
###macro (do_test arg result)
##add_test (TutorialComp${arg} Tutorial ${arg})
###set_tests_properties (TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result})
###endmacro (do_test)
###
###do_test(4 "4 is 2")
###do_test(9 "9 is 3")
###do_test(5 "5 is 2.236")
###do_test(7 "7 is 2.645")
###do_test(25 "25 is 5")
###do_test(-25 "-25 is [-nan|nan|0]")
###do_test(0.0001 "0.0001 is 0.01")

最初のテストでは、アプリケーションがセグメンテーション違反やその他のクラッシュなしで実行されることを確認するだけで、ゼロを返します。これは CTest テストの基本形式です。

次のテストでは、PASS_REGULAR_EXPRESSIONtest 属性を使用して、テストの出力に特定の文字列が含まれていることを確認します。この場合、間違った数の引数が指定されたときに使用法メッセージが出力されることを確認してください。

最後に、 という名前の関数がありますdo_test。この関数はアプリケーションを実行し、計算された平方根が指定された入力に対して正しいかどうかを検証します。を呼び出すたびにdo_test、渡されたパラメータ、名前、入力、および予期される結果に基づいて、別のテストがプロジェクトに追加されます。

アプリを再構築し、バイナリ ディレクトリに移動して と を実行しctest -Nますctest -VV複数構成ジェネレーター (Visual Studio など) の場合は、構成タイプを指定する必要があります。たとえば、「デバッグ」モードでテストを実行するには、ビルド ディレクトリ (「デバッグ」サブディレクトリではありません!) から使用しますctest -C Debug -VVあるいは、RUN_TESTSIDE からターゲットをビルドします。

(ステップ 5) システムセルフテストを追加する

ターゲット プラットフォームにはない機能に依存するコードをプロジェクトに追加することを検討してみましょう。logこの例では、ターゲット プラットフォームにと の機能があるかどうかに応じてコードを追加しますexpもちろん、ほぼすべてのプラットフォームにこれらの機能がありますが、このチュートリアルの目的では、それらは一般的ではないと想定されています。

プラットフォームにlog合計がある場合は、それを使用して関数の平方根expを計算します。mysqrtまず、トップレベルCMakeLists.txtCheckSymbolExistsモジュールを使用して、これらの関数の可用性をテストします。TutorialConfig.h.inの新しい定義を使用するので、そのファイルを設定する前に必ず設定してください

include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)

###早期版本的写法
###include (CheckFunctionExists)
###check_function_exists (log HAVE_LOG)
###check_function_exists (exp HAVE_EXP)

次に、これらの定義を に追加して、以下から使用TutorialConfig.h.inできるようにしますmysqrt.cxx中

// does the platform provide exp and log functions?
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP

cmath を含めるように変更されましたmysqrt.cxx次に、mysqrt関数の同じファイル内で、次のコード (システムで利用可能な場合) に基づく代替実装を提供できますlog(の前をexp忘れないでください)。return result;#endif

#if defined(HAVE_LOG) && defined(HAVE_EXP)
  double result = exp(log(x) * 0.5);
  std::cout << "Computing sqrt of " << x << " to be " << result
            << " using log and exp" << std::endl;
#else
  double result = x;

cmake または cmake-gui を実行してプロジェクトを構成し、選択したビルド ツールを使用してビルドして、チュートリアルの実行可能ファイルを実行します。

logとも使用できるはずだexpと思っていましたが、使用していないことに気づくでしょう。mysqrt.cxxに含めるのを忘れたことにすぐに気づく必要がありますTutorialConfig.h

このファイルがどこにあるかを知るMathFunctions/CMakeLists.txtために更新する必要もあります。mysqrt.cxx

target_include_directories(MathFunctions INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${CMAKE_BINARY_DIR})

この更新後、プロジェクトを再度ビルドして、ビルドされたチュートリアルの実行可能ファイルを実行します。logおよび がまだ使用されていない場合はexp、ビルド ディレクトリから生成された TutorialConfig.h ファイルを開きます。もしかしたら現在のシステムでは利用できないのでしょうか?

現時点ではどちらの関数がより良い結果をもたらす可能性がありますsqrtmysqrt?

コンパイル定義の指定

合計値をTutorialConfig.h保存するよりも良い場所はありますか? 使ってみましょうHAVE_LOGHAVE_EXPtarget_compile_definitions

まず、TutorialConfig.h.inそこから。includemysqrt.cxxまたはTutorialConfig.hother MathFunctions/CMakeLists.txtinclude はもう必要ありません。

次に、HAVE_LOGサムHAVE_EXP的チェックを に移動しMathFunctions/CMakeLists.txt、これらの値をPRIVATEコンパイル定義として指定できます。

include(CheckSymbolExists)
set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)

if(HAVE_LOG AND HAVE_EXP)
  target_compile_definitions(MathFunctions
                             PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()

これらの更新後、プロジェクトを再構築してください。組み込みのチュートリアル実行可能ファイルを実行し、結果がこの手順の前半と同じであることを確認します。

(ステップ 6) カスタム コマンドと生成されたファイルを追加する

このチュートリアルでは、プラットフォームlogexp関数の使用をやめ、代わりにmysqrt関数で使用できる事前計算された値のテーブルを生成したいと考えていると仮定します。このセクションでは、ビルド プロセス中にテーブルを作成し、そのテーブルをアプリケーションにコンパイルします。

MathFunctions/CMakeLists.txtまず、のsum 関数logのチェックを外しますexp次に、 mysqrt.cxx からHAVE_LOG合計のチェックを削除しますHAVE_EXP同時に、 を削除することもできます#include <cmath>

サブディレクトリには、テーブルを生成するためにという名前の新しいソース ファイルMathFunctionsが提供されます。MakeTable.cxx

ファイルを確認すると、出力ファイル名がパラメーターとして渡され、テーブルが有効な C++ コードとして生成されたことがわかります。

次のステップでは、適切なコマンドをMathFunctions/CMakeLists.txtファイルに追加して MakeTable 実行可能ファイルをビルドし、ビルド中にそれを実行します。これを実現するには、いくつかのコマンドが必要です。

まず、他の実行可能ファイルを追加するのと同じようにMathFunctions/CMakeLists.txt、 の先頭に実行可能ファイルを追加します。MakeTable

add_executable(MakeTable MakeTable.cxx)

次に、 MakeTable を実行して生成する方法を指定するカスタム コマンドを追加しますTable.h

add_custom_command(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
  DEPENDS MakeTable
  )

mysqrt.cxx次に、生成されたファイルに依存することをCMake に知らせる必要がありますTable.hこれは、生成された をライブラリ MathFunctions のソース リストにTable.h追加することによって行われます。

add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )

また、現在のバイナリ ディレクトリをインクルード ディレクトリのリストに追加して、mysqrt.cxx見つけて含められるようにする必要がありますTable.h

target_include_directories(MathFunctions
          INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
          PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
          )

それでは、生成されたテーブルを使用してみましょう。まず、mysqrt.cxxを含めるように変更しますTable.hmysqrt次に、このテーブルを使用するように関数を書き換えます。

double mysqrt(double x)
{
  if (x <= 0) {
    return 0;
  }

  // use the table to help find an initial value
  double result = x;
  if (x >= 1 && x < 10) {
    std::cout << "Use the table to help find an initial value " << std::endl;
    result = sqrtTable[static_cast<int>(x)];
  }

  // do ten iterations
  for (int i = 0; i < 10; ++i) {
    if (result <= 0) {
      result = 0.1;
    }
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
  }

  return result;
}

cmake または cmake-gui を実行してプロジェクトを構成し、選択したビルド ツールを使用してビルドします。このプロジェクトをビルドするときは、最初にMakeTable実行可能ファイルがビルドされます。MakeTable次に、 build が実行されますTable.h最後に、含まれているものをコンパイルしてMathFunctions ライブラリTable.hを生成します。mysqrt.cxxチュートリアルの実行可能ファイルを実行し、テーブルが使用されていることを確認します。

(ステップ 7) インストーラーをビルドする

次に、プロジェクトを他の人に配布して、他の人が使用できるようにしたいとします。私たちはバイナリ コードとソース コードの両方をさまざまなプラットフォームで提供したいと考えています。これは、「インストールとテスト」(ステップ 4) でソースからビルドしたバイナリをインストールしたインストールとは少し異なります。この例では、バイナリ インストールとパッケージ管理機能をサポートするインストーラー パッケージを構築します。これを行うには、CPack を使用してプラットフォーム固有のインストーラーを作成します。具体的には、トップレベルの CMakeLists.txt ファイルの最後に数行を追加する必要があります。

include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
include(CPack)

それだけです。最初に を含めますInstallRequiredSystemLibrariesこのモジュールには、プロジェクトの現在のプラットフォームに必要なランタイム ライブラリが含まれます。次に、このプロジェクトのライセンスとバージョン情報を保存する場所にいくつかの Cpack 変数を設定します。バージョン情報はチュートリアルの前半で設定されており、license.txtこのステップの最上位ソース ディレクトリに含まれています。

最後に、これらの変数と現在のシステムのその他のプロパティを使用してインストーラーをセットアップする CPack モジュールを含めます。

次のステップでは、通常の方法でプロジェクトをビルドし、それに対して CPack を実行します。バイナリ ディストリビューションを構築するには、バイナリ ディレクトリから次のコマンドを実行します。

cpack

ジェネレーターを指定するには、-G オプションを使用します。複数構成のビルドの場合は、-C を使用して構成を指定します。例えば:

cpack -G ZIP -C Debug

ソース配布を作成するには、次のように入力します。

cpack --config CPackSourceConfig.cmake

あるいは、make packageIDE でPackageターゲットを実行するか右クリックしますBuild Project

バイナリ ディレクトリにあるインストーラを実行します。次に、インストールされた実行可能ファイルを実行し、動作することを確認します。

(ステップ 8) ダッシュボードのサポートを追加する

テスト結果をダッシュ​​ボードに送信するサポートを追加するのは非常に簡単です。テスト サポートでは、プロジェクト用に多数のテストを定義しました。あとは、これらのテストを実行してダッシュボードに送信するだけです。ダッシュボードのサポートを含めるために、CMakeLists.txtCTest モジュールをトップレベルに含めます。

使用

# enable dashboard scripting
include(CTest)

交換

# enable testing 
enable_testing()

CTest モジュールは自動的に呼び出されるのでenable_testing()、CMake ファイルから削除できます。

CTestConfig.cmakeまた、プロジェクトの名前とダッシュボードの送信先を指定できるファイルを最上位ディレクトリに作成する必要があります。

set(CTEST_PROJECT_NAME "CMakeTutorial")
set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")

set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
set(CTEST_DROP_SITE_CDASH TRUE)

CTest は実行時にこのファイルを読み取ります。単純なダッシュボードを作成するには、cmake または cmake-gui を実行してプロジェクトを構成しますが、ビルドはできません。代わりに、ディレクトリをバイナリ ツリーに変更してから、次のコマンドを実行します。

ctest [-VV] -D Experimental

マルチ構成ジェネレーター (Visual Studio など) の場合は、構成タイプを指定する必要があることに注意してください。

ctest [-VV] -C Debug -D Experimental

あるいは、ExperimentalIDE 内からターゲットをビルドします。

ctestプロジェクトは構築およびテストされ、結果は Kitware パブリック ダッシュボード ダッシュボードに送信されます。ダッシュボードの結果は、Kitware のパブリック ダッシュボードにアップロードされます。

(ステップ 9) 静的ライブラリと動的ライブラリの混合

BUILD_SHARED_LIBSこのセクションでは、変数を使用してadd_libraryデフォルトの動作を制御し、明示的な型を使用せずにライブラリの構築方法を制御できるようにする方法を示しますSTATIC,SHARED,MODULE或OBJECT( )。

BUILD_SHARED_LIBSこれを行うには、最上位に を追加する必要がありますCMakeLists.txtこのコマンドを使用するのoptionは、ユーザーが値をオンにするかオフにするかを選択できるためです。

次に、このロジックを実行する呼び出しコードを必要とするのではなく、MathFunctions を mysqrt または sqrt でラップされた実際のライブラリになるようにリファクタリングします。これは、USE_MYMATHMathFuction の構築ではなく、このライブラリの動作が制御されることも意味します。

最初のステップは、CMakeLists.txt最上位の開始セクションを次のように更新することです。

cmake_minimum_required(VERSION 3.10)

# set the project name and version
project(Tutorial VERSION 1.0)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)

# configure a header file to pass the version number only
configure_file(TutorialConfig.h.in TutorialConfig.h)

# add the MathFunctions library
add_subdirectory(MathFunctions)

# add the executable
add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC MathFunctions)

MathFunctions を常に使用できるようになったので、ライブラリのロジックを更新する必要があります。したがって、 では、有効になったときに条件付きでビルドするMathFunctions/CMakeLists.txtものを作成する必要があります。ここで、これはチュートリアルであるため、SqrtLibrary が静的に構築されることを明示的に要求します。SqrtLibraryUSE_MYMATH

最終結果はMathFunctions/CMakeLists.txt次のようになります。

# add the library that runs
add_library(MathFunctions MathFunctions.cxx)

# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
                           INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
                           )

# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
if(USE_MYMATH)

  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")

  # first we add the executable that generates the table
  add_executable(MakeTable MakeTable.cxx)

  # add the command to generate the source code
  add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
    COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
    DEPENDS MakeTable
    )

  # library that just does sqrt
  add_library(SqrtLibrary STATIC
              mysqrt.cxx
              ${CMAKE_CURRENT_BINARY_DIR}/Table.h
              )

  # state that we depend on our binary dir to find Table.h
  target_include_directories(SqrtLibrary PRIVATE
                             ${CMAKE_CURRENT_BINARY_DIR}
                             )

  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()

# define the symbol stating we are using the declspec(dllexport) when
# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")

# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)

次に、使用する名前空間を更新MathFunctions/mysqrt.cxxますmathfunctionsdetail

#include <iostream>

#include "MathFunctions.h"

// include the generated table
#include "Table.h"

namespace mathfunctions
{
namespace detail 
{
// a hack square root calculation using simple operations
double mysqrt(double x)
{
  if (x <= 0) 
    return 0;

  // use the table to help find an initial value
  double result = x;
  if (x >= 1 && x < 10) 
  {
    std::cout << "Use the table to help find an initial value " << std::endl;
    result = sqrtTable[static_cast<int>(x)];
  }

  // do ten iterations
  for (int i = 0; i < 10; ++i)
  {
    if (result <= 0) 
      result = 0.1;
    double delta = x - (result * result);
    result = result + 0.5 * delta / result;
    std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
  }

  return result;
}
}
}

tutorial.cxxまた、機能しなくなるようにいくつかの変更を加える必要がありますUSE_MYMATH

  1. 常に含めるMathFunctions.h
  2. いつも使うmathfunctions::sqrt
  3. 含まないcmath

最後に、MathFunctions/MathFunctions.hdll エクスポート定義を使用するように更新します。

#if defined(_WIN32)
#  if defined(EXPORTING_MYMATH)
#    define DECLSPEC __declspec(dllexport)
#  else
#    define DECLSPEC __declspec(dllimport)
#  endif
#else // non windows
#  define DECLSPEC
#endif

namespace mathfunctions {
double DECLSPEC sqrt(double x);
}

この時点で、すべてをビルドした場合は、位置に依存しないコードを含まない静的ライブラリと位置に依存しないコードを含むライブラリを組み合わせたため、リンクの失敗に気づくでしょう。解決策は、ビルド タイプに関係なく、SqrtLibrary のPOSITION_INDEPENDENT_CODEtarget プロパティを明示的に True に設定することです。

# state that SqrtLibrary need PIC when the default is shared libraries
  set_target_properties(SqrtLibrary PROPERTIES
                        POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
                        )

  target_link_libraries(MathFunctions PRIVATE SqrtLibrary)

演習: MathFunctions.hdll エクスポート定義を使用するように変更しました。CMake ドキュメントを使用すると、これを簡単にするヘルパー モジュールを見つけることができますか?

(ステップ 10) ジェネレータ式を追加する

ジェネレーター式はビルド システムの生成中に評価され、各ビルド構成に固有の情報が生成されます。

ジェネレーター式は、多くのターゲット プロパティ (など)LINK_LIBRARIES,INCLUDE_DIRECTORIES,COMPLIE_DEFINITIONSのコンテキストで許可されます。target_link_libraries(),target_include_directories() ,target_compile_definitions()これらは、などのコマンドを使用してこれらのプロパティを設定するときにも使用できます。

ジェネレーター式を使用すると、条件付きリンク、コンパイル時に使用される条件定義、条件付きインクルード ディレクトリなどを有効にすることができます。条件は、ビルド構成、ターゲット プロパティ、プラットフォーム情報、またはその他のクエリ可能な情報に基づくことができます。

ジェネレーター式には、論理式、情報式、出力式など、さまざまなタイプがあります。

論理式は、条件付き出力を作成するために使用されます。基本的な式は 0 と 1 の式です。$<0:...>結果は空の文字列となり、代わりに<1:...>コンテンツ「...」が生成されます。入れ子にすることもできます。

ジェネレーター式の一般的な使用法は、言語レベルや警告などのコンパイラー フラグを条件付きで追加することです。良いパターンは、INTERFACE情報をターゲットと関連付けて情報を拡散させることです。を使用する代わりに、INTERFACEターゲットを構築し、必要なC++標準レベルを指定することから始めましょう11CMAKE_CXX_STANDARD

したがって、次のコード:

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

は次のように置き換えられます。

add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)

次に、必要なコンパイラ警告フラグをプロジェクトに追加します。警告フラグはコンパイラによって異なるため、COMPILE_LANG_AND_ID次のようにジェネレータ式を使用して、言語とコンパイラ ID のセットに応じてどのフラグを適用するかを制御します。

set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
 "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
 "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)

これを見ると、警告サインがBUILD_INTERFACE条件内にカプセル化されていることがわかります。これは、インストールされたプロジェクトの利用者が警告フラグを継承しないようにするために行われます。

演習:MathFunctions/CMakeLists.txtすべてのターゲットがペア呼び出しを持つように変更しますtutorial_compiler_flags target_link_libraries()

(ステップ 11) 出力構成を追加する

このチュートリアルの「(ステップ 4) インストールとテスト」では、プロジェクトのライブラリとヘッダー ファイルをインストールする機能を CMake に追加しました。「(ステップ 7) インストーラーの構築」中に、これをパッケージ化して他の人に配布できるようにする機能を追加しました。

次のステップでは、他の CMake プロジェクトがビルド ディレクトリ、ローカル インストール、またはパッケージ化されたファイルからプロジェクトを使用できるように、必要な情報を追加します。

最初のステップは、install(TARGETS)を指定するだけでなくDESTINATIONを指定するようにコマンドを更新することですEXPORTEXPORTこのキーワードは、インストール コマンドにリストされているすべてのターゲットをインストール ツリーからインポートするためのコードを含む CMake ファイルを生成し、インストールします。それでは、次のように更新MathFunctions/CMakeLists.txt内のinstallコマンドを使用して MathFunctions ライブラリを明示的に更新しましょう。EXPORT

install(TARGETS MathFunctions tutorial_compiler_flags
        DESTINATION lib
        EXPORT MathFunctionsTargets)
install(FILES MathFunctions.h DESTINATION include)

MathFunction をエクスポートしたので、生成されたMathFunctionsTargets.cmakeファイルを明示的にインストールする必要もあります。CMakeLists.txtこれを行うには、トップレベルの最後に以下を追加します。

install(EXPORT MathFunctionsTargets
  FILE MathFunctionsTargets.cmake
  DESTINATION lib/cmake/MathFunctions
)

この時点で、CMake を実行してみる必要があります。すべてが正しく設定されている場合は、CMake が次のようなエラーを生成することがわかります。

Target "MathFunctions" INTERFACE_INCLUDE_DIRECTORIES property contains
path:

  "/Users/robert/Documents/CMakeClass/Tutorial/Step11/MathFunctions"

which is prefixed in the source directory.

CMake が言おうとしているのは、エクスポート情報を生成する過程で、現在のマシンに本質的に関連付けられており、他のマシンには影響を与えないパスをエクスポートするということです。解決策は、MathFunctions を更新して、ビルド ディレクトリおよびインストール/パッケージから使用するときにtarget_include_directories別の場所が必要であることを認識させることです。INTERFACEこれは、MathFunctions の呼び出しをtarget_include_directories次のように変換することを意味します。

target_include_directories(MathFunctions
                           INTERFACE
                            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
                            $<INSTALL_INTERFACE:include>
                           )

更新後、CMake を再実行して、警告が出力されなくなったことを確認できます。

MathFunctionsConfig.cmakeこの時点で、CMake に必要なターゲット情報は正しくパッケージ化されましたが、 CMakefind_packageコマンドがプロジェクトを見つけられるようにビルドする必要があります。そこで、Config.cmake.inプロジェクトの最上位プロジェクトの最上位ディレクトリに、次の内容の新しいファイルを追加します。

@PACKAGE_INIT@
include ( "${CMAKE_CURRENT_LIST_DIR}/MathFunctionsTargets.cmake" )

次に、ファイルを適切に構成してインストールするには、CMakeLists.txtトップレベルの最後に次の行を追加します。

install(EXPORT MathFunctionsTargets
  FILE MathFunctionsTargets.cmake
  DESTINATION lib/cmake/MathFunctions
)

include(CMakePackageConfigHelpers)
# generate the config file that is includes the exports
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake"
  INSTALL_DESTINATION "lib/cmake/example"
  NO_SET_AND_CHECK_MACRO
  NO_CHECK_REQUIRED_COMPONENTS_MACRO
  )
# generate the version file for the config file
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake"
  VERSION "${Tutorial_VERSION_MAJOR}.${Tutorial_VERSION_MINOR}"
  COMPATIBILITY AnyNewerVersion
)

# install the configuration file
install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake
  DESTINATION lib/cmake/MathFunctions
  )

この時点で、プロジェクトの再配置可能な CMake 構成が生成されました。これは、プロジェクトのインストールまたはパッケージ化後に使用できます。CMakeLists.txtビルド ディレクトリのプロジェクトも使用したい場合は、トップ レベルの最後に以下を追加するだけです。

export(EXPORT MathFunctionsTargets
  FILE "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsTargets.cmake"
)

Targets.cmakeこのエクスポート呼び出しにより、ビルド ディレクトリに設定されたものをMathFunctionsConfig.cmakeインストールせずに他のプロジェクトで使用できるようにするものが生成されます。

CMake プロジェクトをインポートする (コンシューマ)

この例では、プロジェクトがConfig.cmakeメイクファイル用の他の CMake パッケージを見つける方法を示します。

Config.cmakeまた、プロジェクトの外部依存関係がビルド時にどのように宣言されるかについても示します。

パッケージのデバッグとリリース (複数のパッケージ)

デフォルトでは、CMake のモデルでは、ビルド ディレクトリには Debug、Release、MinSizeRel、または RelWithDebInfo の構成が 1 つだけ含まれます。

ただし、CPack は複数のビルド ディレクトリを同時にバンドルして、同じプロジェクトの複数の構成を含む 1 つのパッケージをビルドするように設定できます。

まず、 というディレクトリを構築する必要がありますmulti_config。このディレクトリには、一緒にパッケージ化するすべてのビルドが含まれます。

次にmulti_config、の下にdebugandreleaseディレクトリを作成します。最終的には次のようなレイアウトになるはずです。

─ multi_config
    ├── debug
    └── release

ここで、デバッグ ビルドとリリース ビルドを設定する必要があります。これには、おおよそ次のものが必要です。

cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/
cmake --build .
cd ../release
cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/
cmake --build .
cd ..

デバッグ ビルドとリリース ビルドが完了したので、カスタム ファイルを使用してMultiCPackConfig.cmake2 つのビルドを 1 つのリリース ビルドにパッケージ化できます。

cpack --config ../../MultiPackage/MultiCPackConfig.cmake

2、Cmakeエントリーケース

2.1 単一のソースファイル

このセクションに対応するソース コードは、ディレクトリ Demo1 にあります。単純なプロジェクトの場合、数行のコードを記述するだけで済みます。たとえば、現在プロジェクトにソース ファイルhttp://main.ccが 1 つだけあり、このプログラムの目的が数値の指数乗を計算するとします。

#include <stdio.h>
#include <stdlib.h>

/**
 * power - Calculate the power of number.
 * @param base: Base value.
 * @param exponent: Exponent value.
 *
 * @return base raised to the power exponent.
 */
double power(double base, int exponent)
{
    int result = base;
    int i;
    
    for(i = 1; i < exponent; ++i){
        result = result * base;
    }

    return result;
}

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

CMakeLists.txt を書く

まず、CMakeLists.txt ファイルを作成し、http://main.ccソース ファイルと同じディレクトリに保存します。

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo1)

# 指定生成目标
add_executable(Demo main.cc)

CMakeLists.txt の構文は比較的単純で、コマンド、コメント、スペースで構成されており、コマンドでは大文字と小文字が区別されません。記号#の後のものはすべてコメントとみなされます。コマンドはコマンド名、括弧、パラメータで構成され、パラメータ間はスペースで区切られます。

上記の CMakeLists.txt ファイルでは、いくつかのコマンドが順番に表示されています。

  1. cmake_minimum_required: この構成ファイルを実行するために必要な CMake の最小バージョンを指定します。
  2. project: パラメータは でmain、コマンドはプロジェクトの名前が main であることを示します。
  3. add_executable: main.cc という名前のソース ファイルを Demo という名前の実行可能ファイルにコンパイルします。

プロジェクトをコンパイルする

その後、現在のディレクトリで実行してcmake .Makefile を取得し、makeコマンドを使用して Demo1 実行可能ファイルをコンパイルします。

[ehome@xman Demo1]$ cmake .
-- The C compiler identification is GNU 4.8.2
-- The CXX compiler identification is GNU 4.8.2
-- Check for working C compiler: /usr/sbin/cc
-- Check for working C compiler: /usr/sbin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/sbin/c++
-- Check for working CXX compiler: /usr/sbin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ehome/Documents/programming/C/power/Demo1
[ehome@xman Demo1]$ make
Scanning dependencies of target Demo
[100%] Building C object CMakeFiles/Demo.dir/main.cc.o
Linking C executable Demo
[100%] Built target Demo
[ehome@xman Demo1]$ ./Demo 5 4
5 ^ 4 is 625
[ehome@xman Demo1]$ ./Demo 7 3
7 ^ 3 is 343
[ehome@xman Demo1]$ ./Demo 2 10
2 ^ 10 is 1024

2.2 複数のソースファイル

同じディレクトリ内の複数のソース ファイル: このセクションに対応するソース コードが配置されているディレクトリ: Demo2。

上の例にはソース ファイルが 1 つだけあります。ここで、power関数をMathFunctions.cという名前のソース ファイルに個別に記述すると、プロジェクトは次のようになります。

/Demo2
    |
    +--- main.cc
    |
    +--- MathFunctions.cc
    |
    +--- MathFunctions.h

この時点で、CMakeLists.txt は次の形式に変更できます。

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 指定生成目标
add_executable(Demo main.cc MathFunctions.cc)

唯一の変更は、コマンドにソース ファイルをadd_executable追加することです。MathFunctions.ccもちろん、このように書くことに問題はありませんが、ソースファイルの数が多い場合、すべてのソースファイルの名前を追加するのは面倒な作業になります。より便利な方法はaux_source_directory、指定されたディレクトリ内のすべてのソース ファイルを検索し、結果を指定された変数名に保存するコマンドを使用することです。その構文は次のとおりです。

aux_source_directory(<dir> <variable>)

したがって、CMakeLists.txt を次のように変更できます。

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo2)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})

このようにして、CMake は現在のディレクトリ内のすべてのソース ファイルのファイル名を変数 に割り当てDIR_SRCSDIR_SRCS変数内のソース ファイルを Demo という名前の実行可能ファイルにコンパイルする必要があることを示します。

2.3 複数のディレクトリ、複数のソースファイル

このセクションに対応するソース コードのディレクトリ: Demo3。

次に、MathFunctions.h およびhttp://MathFunctions.ccファイルをさらにmath ディレクトリに移動します。

./Demo3
    |
    +--- main.cc
    |
    +--- math/
          |
          +--- MathFunctions.cc
          |
          +--- MathFunctions.h

この場合、CMakeLists.txt ファイルをプロジェクトのルート ディレクトリ Demo3 と math ディレクトリにそれぞれ書き込む必要があります。便宜上、まず math ディレクトリ内のファイルを静的ライブラリにコンパイルし、それを main 関数から呼び出すことができます。

ルート ディレクトリ内の CMakeLists.txt:

# 项目信息
project (Demo3)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 添加 math 子目录
add_subdirectory(math)

# 指定生成目标 
add_executable(Demo main.cc)

# 添加链接库
target_link_libraries(Demo MathFunctions)

このファイルに次の内容を追加します。 行 3 では、コマンドを使用して、add_subdirectoryこのプロジェクトにサブディレクトリ math が含まれていることを示します。これにより、CMakeLists.txt ファイルと math ディレクトリ内のソース コードも処理されます。6 行目では、コマンドを使用して、target_link_libraries実行可能ファイル main が MathFunctions という名前のリンク ライブラリをリンクする必要があることを示します。

サブディレクトリ内の CMakeLists.txt:

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_LIB_SRCS 变量
aux_source_directory(. DIR_LIB_SRCS)

# 生成链接库
add_library (MathFunctions ${DIR_LIB_SRCS})

このファイル内のコマンドを使用して、add_librarysrc ディレクトリ内のソース ファイルを静的リンク ライブラリにコンパイルします。

2.4 カスタム コンパイル オプション

このセクションに対応するソース コード ディレクトリ: Demo4。

CMake ではプロジェクトにコンパイル オプションを追加できるため、ユーザーの環境やニーズに応じて最適なコンパイル スキームを選択できます。

たとえば、オプションのライブラリとして MathFunctions ライブラリを設定でき、オプションが の場合ON、ライブラリに定義されている数学関数が計算に使用されます。それ以外の場合は、標準ライブラリ内の数学関数ライブラリが呼び出されます。

CMakeLists ファイルを変更する

最初に行う必要があるステップは、このオプションを最上位の CMakeLists.txt ファイルに追加することです。

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)

# 项目信息
project (Demo4)

# 加入一个配置头文件,用于处理 CMake 对源码的设置
configure_file (
  "${PROJECT_SOURCE_DIR}/config.h.in"
  "${PROJECT_BINARY_DIR}/config.h"
  )

# 是否使用自己的 MathFunctions 库
option (USE_MYMATH
       "Use provided math implementation" ON)

# 是否加入 MathFunctions 库
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/math")
  add_subdirectory (math)  
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)

# 指定生成目标
add_executable(Demo ${DIR_SRCS})
target_link_libraries (Demo  ${EXTRA_LIBS})

の:

  1. 7 行目のconfigure_fileコマンドは、config.h.in から CMake によって生成される構成ヘッダー ファイル config.h を追加するために使用されます。このメカニズムを通じて、コードの生成を制御するためにいくつかのパラメーターと変数を事前定義できます。
  2. 13 行目のコマンドはオプションoptionを追加しUSE_MYMATH、デフォルトは ですON
  3. 17行目ではUSE_MYMATH変数の値に応じて自作のMathFunctionsライブラリを使用するかどうかを決定しています。

http://main.ccファイルを変更します。

次に、http://main.ccUSE_MYMATHファイルを変更して、事前定義された値に従って標準ライブラリと MathFunctions ライブラリのどちらを呼び出すかを決定できるようにします。

#include <stdio.h>
#include <stdlib.h>
#include "config.h"

#ifdef USE_MYMATH
  #include "math/MathFunctions.h"
#else
  #include <math.h>
#endif


int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    
#ifdef USE_MYMATH
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#else
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#endif
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

http://config.h.inファイルを書き込みます

USE_MYMATH上記のプログラムでは、2 行目で の値が事前定義されている config.h ファイルを参照していることに注意してください。ただし、このファイルを直接作成するのではなく、CMakeLists.txt からの構成のインポートを容易にするために、次の内容を含む config.h.in ファイルを作成します。

#cmakedefine USE_MYMATH

このようにして、CMake は CMakeLists 構成ファイルの設定に従って config.h ファイルを自動的に生成します。

プロジェクトをコンパイルする

次に、このプロジェクトをコンパイルします。この変数の値を対話的に選択するには、ccmakeコマンド2 2cmake -iを使用するか、会話型の対話型構成インターフェイスを提供する コマンドを使用できます。

画像

そこから、定義したばかりのオプションを見つけUSE_MYMATH、キーボードの矢印キーを押してさまざまなオプション ウィンドウ間を移動し、enterキーを押してオプションを変更します。変更後、cオプションを押して構成を完了し、gキーをMakefile を生成することを確認します。ccmake のその他の操作については、ウィンドウの下部に表示される指示プロンプトを参照してください。

それぞれ結果のUSE_MYMATH設定ONと取得を試みることができます。OFF

USE_MYMATH がオンになっています

操作結果:

[ehome@xman Demo4]$ ./Demo
Now we use our own MathFunctions library. 
 7 ^ 3 = 343.000000
 10 ^ 5 = 100000.000000
 2 ^ 10 = 1024.000000

この時点での config.h の内容は次のとおりです。

#define USE_MYMATH

USE_MYMATH はオフです

操作結果:

[ehome@xman Demo4]$ ./Demo
Now we use the standard library. 
 7 ^ 3 = 343.000000
 10 ^ 5 = 100000.000000
 2 ^ 10 = 1024.000000

この時点での config.h の内容は次のとおりです。

/* #undef USE_MYMATH */

2.5 インストールとテスト

このセクションに対応するソース コード ディレクトリ: Demo5。

CMake では、インストール ルールを指定したり、テストを追加したりすることもできます。これら 2 つの関数は、 Makefile を生成した後、それぞれmake installと を使用して実行できますmake test以前の GNU Makefile では、 2 つの疑似ターゲットとそれに対応するルールを記述する必要がありましたが、CMake では、この種の作業もいくつかのコマンドを呼び出すだけで済みinstallますtest

カスタム インストール ルール

まず、次の 2 行を math/CMakeLists.txt ファイルに追加します。

# 指定 MathFunctions 库的安装路径
install (TARGETS MathFunctions DESTINATION bin)
install (FILES MathFunctions.h DESTINATION include)

MathFunctions ライブラリのインストール パスを示します。次に、ルート ディレクトリにある CMakeLists ファイルも変更し、最後に次の行を追加します。

# 指定安装路径
install (TARGETS Demo DESTINATION bin)
install (FILES "${PROJECT_BINARY_DIR}/config.h"
         DESTINATION include)

上記のカスタマイズにより、生成された Demo ファイルと MathFunctions 関数ライブラリ libMathFunctions.o ファイルが にコピーされ/usr/local/bin、MathFunctions.h と生成された config.h ファイルが にコピーされます/usr/local/include33ちなみに、これは/usr/local/デフォルトでインストールされるルート ディレクトリです。CMAKE_INSTALL_PREFIX変数の値を変更することで、これらのファイルをコピーするルート ディレクトリを指定できます。

[ehome@xman Demo5]$ sudo make install
[ 50%] Built target MathFunctions
[100%] Built target Demo
Install the project...
-- Install configuration: ""
-- Installing: /usr/local/bin/Demo
-- Installing: /usr/local/include/config.h
-- Installing: /usr/local/bin/libMathFunctions.a
-- Up-to-date: /usr/local/include/MathFunctions.h
[ehome@xman Demo5]$ ls /usr/local/bin
Demo  libMathFunctions.a
[ehome@xman Demo5]$ ls /usr/local/include
config.h  MathFunctions.h

プロジェクトにテストを追加する

テストの追加も簡単です。CMake は、CTest と呼ばれるテスト ツールを提供します。必要なのは、プロジェクトのルート ディレクトリにある CMakeLists ファイル内の一連のコマンドを呼び出すことだけですadd_test

# 启用测试
enable_testing()

# 测试程序是否成功运行
add_test (test_run Demo 5 2)

# 测试帮助信息是否可以正常提示
add_test (test_usage Demo)
set_tests_properties (test_usage
  PROPERTIES PASS_REGULAR_EXPRESSION "Usage: .* base exponent")

# 测试 5 的平方
add_test (test_5_2 Demo 5 2)

set_tests_properties (test_5_2
 PROPERTIES PASS_REGULAR_EXPRESSION "is 25")

# 测试 10 的 5 次方
add_test (test_10_5 Demo 10 5)

set_tests_properties (test_10_5
 PROPERTIES PASS_REGULAR_EXPRESSION "is 100000")

# 测试 2 的 10 次方
add_test (test_2_10 Demo 2 10)

set_tests_properties (test_2_10
 PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")

上記のコードには 4 つのテストが含まれています。最初のテストは、test_runプログラムが正常に実行され、値 0 が返されるかどうかをテストするために使用されます。残りの 3 つのテストは、5 の 2 乗、10 の 5 乗、および 2 の 10 乗がすべて正しい結果を取得できるかどうかをテストするために使用されます。wherePASS_REGULAR_EXPRESSIONは、出力に後続の文字列が含まれるかどうかをテストするために使用されます。

テストの結果を見てみましょう。

[ehome@xman Demo5]$ make test
Running tests...
Test project /home/ehome/Documents/programming/C/power/Demo5
    Start 1: test_run
1/4 Test #1: test_run .........................   Passed    0.00 sec
    Start 2: test_5_2
2/4 Test #2: test_5_2 .........................   Passed    0.00 sec
    Start 3: test_10_5
3/4 Test #3: test_10_5 ........................   Passed    0.00 sec
    Start 4: test_2_10
4/4 Test #4: test_2_10 ........................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 4

Total Test time (real) =   0.01 sec

より多くの入力データをテストしたい場合、上記のようにテスト ケースを 1 つずつ記述するのは非常に面倒です。これはマクロを記述することで実現できます。

# 定义一个宏,用来简化测试工作
macro (do_test arg1 arg2 result)
  add_test (test_${arg1}_${arg2} Demo ${arg1} ${arg2})
  set_tests_properties (test_${arg1}_${arg2}
    PROPERTIES PASS_REGULAR_EXPRESSION ${result})
endmacro (do_test)
 
# 使用该宏进行一系列的数据测试
do_test (5 2 "is 25")
do_test (10 5 "is 100000")
do_test (2 10 "is 1024")

CTest の詳しい使用方法については、man 1 ctestCTest のドキュメントを参照してください。

gdbをサポート

DebugCMake で gdb 設定をサポートさせるのも非常に簡単です。 mode で開くオプションを指定するだけです-g

set(CMAKE_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

その後、gdb を直接使用して、生成されたプログラムをデバッグできます。

2.6 環境チェックの追加

このセクションに対応するソース コードのディレクトリ: Demo6。

プラットフォーム固有の機能を使用する場合など、システム環境の確認が必要になる場合があります。この例では、システムに pow 関数が付属しているかどうかを確認します。pow 関数がある場合はそれを使用し、そうでない場合は定義した power 関数を使用します。

CheckFunctionExists マクロを追加

まず、最上位の CMakeLists ファイルに CheckFunctionExists.cmake マクロを追加し、check_function_existsコマンドを呼び出して、powリンク フェーズ中にリンカーが関数を見つけられるかどうかをテストします。

# 检查系统是否支持 pow 函数
include (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
check_function_exists (pow HAVE_POW)

上記のコードをconfigure_fileコマンドの前に置きます。

関連するマクロ変数を事前定義する

次に、http://config.h.inファイルを変更して、関連するマクロ変数を事前定義します。

// does the platform provide pow function?
#cmakedefine HAVE_POW

コード内でのマクロと関数の使用

最後のステップは、コード内でマクロと関数を使用するようにhttp://main.ccを変更することです。

#ifdef HAVE_POW
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#else
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#endif

2.8 バージョン番号を追加する

このセクションに対応するソース コードのディレクトリ: Demo7。

ユーザーが各バージョンのメンテナンス状況を理解し、現在使用しているバージョンが古くないか、互換性がない可能性があるかどうかを常に把握できるように、プロジェクトにバージョン番号を追加して保守することを習慣にしてください。

まずトップレベルの CMakeLists ファイルを変更し、projectコマンドの後に次の 2 行を追加します。

set (Demo_VERSION_MAJOR 1)
set (Demo_VERSION_MINOR 0)

現在のプロジェクトのメジャー バージョン番号とマイナー バージョン番号をそれぞれ指定します。

後で、コード内のバージョン情報を取得するために、http://config.h.inファイルを変更し、2 つの事前定義変数を追加します。

// the configured options and settings for Tutorial
#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@
#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@

このようにして、バージョン情報をコード内に直接出力できます。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "config.h"
#include "math/MathFunctions.h"

int main(int argc, char *argv[])
{
    if (argc < 3){
        // print version info
        printf("%s Version %d.%d\n",
            argv[0],
            Demo_VERSION_MAJOR,
            Demo_VERSION_MINOR);
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    
#if defined (HAVE_POW)
    printf("Now we use the standard library. \n");
    double result = pow(base, exponent);
#else
    printf("Now we use our own Math library. \n");
    double result = power(base, exponent);
#endif
    
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

2.9 インストールパッケージの生成

このセクションに対応するソース コードは、ディレクトリ Demo8 にあります。

このセクションでは、バイナリ インストール パッケージやソース コード インストール パッケージなど、さまざまなプラットフォームでインストール パッケージを構成および生成する方法を学習します。このタスクを実行するには、CPack を使用する必要があります。これも CMake によって提供され、パッケージ化に特別に使用されるツールです。

まず、最上位の CMakeLists.txt ファイルの末尾に次の行を追加します。

# 构建一个 CPack 安装包
include (InstallRequiredSystemLibraries)
set (CPACK_RESOURCE_FILE_LICENSE
  "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")
set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")
include (CPack)

上記のコードは次のことを行います。

  1. InstallRequiredSystemLibraries モジュールをインポートして、後で CPack モジュールをインポートします。
  2. 著作権情報やバージョン情報など、CPack 関連の変数をいくつか設定します。バージョン情報には、前のセクションで定義したバージョン番号が使用されます。
  3. Cpack モジュールをインポートします。

次のジョブは、通常どおりプロジェクトをビルドし、cpackコマンドを実行することです。

バイナリ インストール パッケージを生成します。

cpack -C CPackConfig.cmake

ソースコードインストールパッケージを生成する

cpack -C CPackSourceConfig.cmake

試してみることができます。プロジェクトをビルドした後、次のcpack -C CPackConfig.cmakeコマンドを実行します。

[ehome@xman Demo8]$ cpack -C CPackSourceConfig.cmake
CPack: Create package using STGZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.sh generated.
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.tar.gz generated.
CPack: Create package using TZ
CPack: Install projects
CPack: - Run preinstall target for: Demo8
CPack: - Install project: Demo8
CPack: Create package
CPack: - package: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux.tar.Z generated.

この時点で、異なる形式の 3 つのバイナリ パッケージ ファイルがこのディレクトリに作成されます。

[ehome@xman Demo8]$ ls Demo8-*
Demo8-1.0.1-Linux.sh  Demo8-1.0.1-Linux.tar.gz  Demo8-1.0.1-Linux.tar.Z

これら 3 つのバイナリ パッケージ ファイルに含まれる内容はまったく同じです。そのうちの 1 つを実行できます。CPack によって自動的に生成された対話型のインストール インターフェイスが表示されます。

[ehome@xman Demo8]$ sh Demo8-1.0.1-Linux.sh 
Demo8 Installer Version: 1.0.1, Copyright (c) Humanity
This is a self-extracting archive.
The archive will be extracted to: /home/ehome/Documents/programming/C/power/Demo8

If you want to stop extracting, please press <ctrl-C>.
The MIT License (MIT)

Copyright (c) 2013 Joseph Pan(http://hahack.com)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Do you accept the license? [yN]: 
y
By default the Demo8 will be installed in:
  "/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux"
Do you want to include the subdirectory Demo8-1.0.1-Linux?
Saying no will install in: "/home/ehome/Documents/programming/C/power/Demo8" [Yn]: 
y

Using target directory: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux
Extracting, please wait...

Unpacking finished successfully

完了後、インストールが Demo8-1.0.1-Linux サブディレクトリにあることを示すプロンプトが表示されるので、そこに移動してプログラムを実行できます。

[ehome@xman Demo8]$ ./Demo8-1.0.1-Linux/bin/Demo 5 2
Now we use our own Math library. 
5 ^ 2 is 25

CPack の詳しい使用方法については、man 1 cpackCPack のドキュメントを参照してください。

プロジェクトを他のプラットフォームから CMake に移行します。

CMake は、さまざまなプラットフォームでの実行に適したエンジニアリング環境を簡単に構築できます。また、現在のエンジニアリング環境が CMake ではなく、特定のプラットフォームに基づいている場合、CMake に移行できますか? 答えは可能です。一般的に使用されるいくつかのプラットフォームについて、対応する移行ソリューションを以下に示します。

オートツール

  • am2cmake は autotools プロジェクトを CMake に変換できます。このツールの成功例は KDE です。
  • 代替の Automake2CMake は、automake を使用して KDevelop プロジェクトを変換できます。
  • autoconf テストの変換

qmake

  • qmake コンバーターは、QT を使用して qmake プロジェクトを変換できます。

ビジュアルスタジオ

  • .vcprojvcproj2cmake.rb は、Visual Studio プロジェクト ファイル (サフィックス名はまたは.vcxproj)に従って CMakeLists.txt ファイルを生成できます。
  • vcproj2cmake.ps1 vcproj2cmake の PowerShell バージョン。
  • folders4cmake は、Visual Studio プロジェクト ファイルに従って、対応する「source_group」情報を生成します。これは、CMake スクリプトで簡単に使用できます。Visual Studio 9/10 プロジェクト ファイルをサポートします。

CMakeLists.txt が自動的に推定される

  • gencmake は、既存のファイルから CMakeLists.txt ファイルを派生します。
  • CMakeListGenerator は、一連のファイルとディレクトリの分析を適用して、完全な CMakeLists.txt ファイルを作成します。Win32 プラットフォームのみがサポートされています。

著作権に関する声明: この記事は、Zhihu ブロガー「Linux カーネルで遊ぶ」によって書かれたオリジナルの記事です。CC 4.0 BY-SA 著作権契約に従っています。転載する場合は、元のソースのリンクとこの声明を添付してください。以下の条件に従って
、そうするためにソフトウェアが提供される人:


上記の著作権表示およびこの許可通知は、ソフトウェアのすべてのコピーまたは主要部分に含まれるものとします。

ソフトウェアは「現状のまま」提供され、明示的か黙示的かを問わず、商品性、特定目的への
適合性、および非侵害の保証を含むがこれらに限定されない、いかなる種類の保証も行われません。
いかなる場合においても、作者または
著作権所有者は、契約行為、不法行為、またはその他の行為であるかどうかにかかわらず、ソフトウェアまたはソフトウェアの使用またはその他の取引に起因
または関連して生じる、いかなる請求、損害、またはその他の責任に対しても責任を負わないものとします。
ソフトウェア。

ライセンスを受け入れますか? [yN]:
y
デフォルトでは、Demo8 は次の場所にインストールされます:
“/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux”
サブディレクトリ Demo8-1.0.1 を含めますか? -Linux?
「いいえ」と答えると、次の場所にインストールされます: “/home/ehome/Documents/programming/C/power/Demo8” [Yn]:
y

使用するターゲット ディレクトリ: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux
解凍中です。お待​​ちください…

開梱も無事に終わりました


完成后提示安装到了 Demo8-1.0.1-Linux 子目录中,我们可以进去执行该程序:

```text
[ehome@xman Demo8]$ ./Demo8-1.0.1-Linux/bin/Demo 5 2
Now we use our own Math library. 
5 ^ 2 is 25

CPack の詳しい使用方法については、man 1 cpackCPack のドキュメントを参照してください。

プロジェクトを他のプラットフォームから CMake に移行します。

CMake は、さまざまなプラットフォームでの実行に適したエンジニアリング環境を簡単に構築できます。また、現在のエンジニアリング環境が CMake ではなく、特定のプラットフォームに基づいている場合、CMake に移行できますか? 答えは可能です。一般的に使用されるいくつかのプラットフォームについて、対応する移行ソリューションを以下に示します。

オートツール

  • am2cmake は autotools プロジェクトを CMake に変換できます。このツールの成功例は KDE です。
  • 代替の Automake2CMake は、automake を使用して KDevelop プロジェクトを変換できます。
  • autoconf テストの変換

qmake

  • qmake コンバーターは、QT を使用して qmake プロジェクトを変換できます。

ビジュアルスタジオ

  • .vcprojvcproj2cmake.rb は、Visual Studio プロジェクト ファイル (サフィックス名はまたは.vcxproj)に従って CMakeLists.txt ファイルを生成できます。
  • vcproj2cmake.ps1 vcproj2cmake の PowerShell バージョン。
  • folders4cmake は、Visual Studio プロジェクト ファイルに従って、対応する「source_group」情報を生成します。これは、CMake スクリプトで簡単に使用できます。Visual Studio 9/10 プロジェクト ファイルをサポートします。

CMakeLists.txt が自動的に推定される

  • gencmake は、既存のファイルから CMakeLists.txt ファイルを派生します。
  • CMakeListGenerator は、一連のファイルとディレクトリの分析を適用して、完全な CMakeLists.txt ファイルを作成します。Win32 プラットフォームのみがサポートされています。

著作権に関する声明: この記事は、Zhihu ブロガー「Linux カーネルで遊ぶ」によって書かれたオリジナルの記事です。CC 4.0 BY-SA 著作権契約に従っています。転載する場合は、元のソースのリンクとこの声明を添付してください。
元のリンク: https://zhuanlan.zhihu.com/p/638429917

おすすめ

転載: blog.csdn.net/m0_50662680/article/details/131484268