「CMake パッケージガイドライン」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
31行目: 31行目:
 
{{ic|-O3}} を使用したからといって、ソフトウェアのパフォーマンスが向上することを保証するものではなく、時にはプログラムの動作が遅くなることもあります。また、状況によってはソフトウェアを壊してしまうこともあります。Arch Linux の開発者がターゲット最適化レベルとして {{ic|-O2}} を選択したのには理由があり、私たちはそれに従うべきでしょう。あなたが何をしているかを正確に分かっている場合、またはアップストリームが {{ic|-O3}} が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。
 
{{ic|-O3}} を使用したからといって、ソフトウェアのパフォーマンスが向上することを保証するものではなく、時にはプログラムの動作が遅くなることもあります。また、状況によってはソフトウェアを壊してしまうこともあります。Arch Linux の開発者がターゲット最適化レベルとして {{ic|-O2}} を選択したのには理由があり、私たちはそれに従うべきでしょう。あなたが何をしているかを正確に分かっている場合、またはアップストリームが {{ic|-O3}} が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。
   
  +
==== 自動最適化フラグオーバーライドの修正 ====
==== Fixing the automatic optimization flag override ====
 
   
  +
100%保証された方法で修正することは、CMake の柔軟性により、簡単な問題ではありません。すべてのケースに適用できる標準的な解決策は存在しないことに注意してください。ここでは、考えられる解決策と、守るべきポイントについて説明します。
Fixing this in a 100% guaranteed way is not a simple question due to CMake flexibility. Please note that there is no standard solution that can be applied to all cases. This section will discuss possible solutions and some points that should be observed.
 
   
  +
CMake のデフォルトのビルドタイプは {{ic|None}} であり、デフォルトでは {{ic|CFLAGS}} と {{ic|CXXFLAGS}} にフラグを付加しないため、 {{ic|CMAKE_BUILD_TYPE}} オプションを使用しないだけでもデフォルトが {{ic|None}} となり動作することがあります。しかし、多くのソフトウェアプロジェクトでは、ビルドタイプを自動的に {{ic|Release}} に設定するため、このオプションを省略しても問題が解決する保証はないことに注意してください。コマンドラインで {{ic|CMAKE_BUILD_TYPE}} が設定されていない場合、CMake ファイルで (または他のタイプで) 設定します。
The default CMake build type is {{ic|None}} and it does not append any flags to {{ic|CFLAGS}} and {{ic|CXXFLAGS}} by default, so simply omitting the usage of the {{ic|CMAKE_BUILD_TYPE}} option can work as it will default to {{ic|None}}. But note that omitting this option is not guaranteed to fix the problem, as many software projects automatically set the build type to {{ic|Release}} (or other type) in the CMake files if {{ic|CMAKE_BUILD_TYPE}} is not set at command line.
 
   
Since the default {{ic|None}} build type does not append any flags to {{ic|CFLAGS}} and {{ic|CXXFLAGS}} by default, using the {{ic|1=-DCMAKE_BUILD_TYPE=None}} option can also work. Generally speaking, using the {{ic|1=-DCMAKE_BUILD_TYPE=None}} option is better than omitting the usage of {{ic|CMAKE_BUILD_TYPE}}. It will cover the case when upstream automatically sets the build type to {{ic|Release}} when {{ic|CMAKE_BUILD_TYPE}} is omitted, it will not append any flags by default and it is uncommon to see software setting undesired flags for the {{ic|None}} build type.
+
デフォルトの {{ic|None}} ビルドタイプは {{ic|CFLAGS}} {{ic|CXXFLAGS}} にフラグを付加しないので、 {{ic|1=-DCMAKE_BUILD_TYPE=None}} オプションも使用可能です。一般的には {{ic|1=-DCMAKE_BUILD_TYPE=None}} オプションを使う方が {{ic|CMAKE_BUILD_TYPE}} を省略するよりも良いと言われています。これは {{ic|CMAKE_BUILD_TYPE}} が省略されたときにアップストリームが自動的にビルドタイプを {{ic|Release}} に設定する場合をカバーするもので、デフォルトではフラグは付加されず、ビルドタイプ {{ic|None}} に好ましくないフラグを設定するソフトウェアはまず見当たりません。
   
  +
しかし、残念ながら {{ic|1=-DCMAKE_BUILD_TYPE=None}} を使えば解決するというような単純なものではありません。{{ic|-O3}} の問題を解決するために {{ic|None}} のビルドタイプを使用する場合、別の問題に陥る可能性があります。多くのソフトウェアプロジェクトでは、CMake ファイルで {{ic|Release}} ビルドタイプに必要なコンパイラフラグを定義するのが一般的です(例えば、{{ic|CMAKE_C_FLAGS_RELEASE}} と {{ic|CMAKE_CXX_FLAGS_RELEASE}} を設定するようなものです)。CMake 変数)。このようなソフトウェアは、これらの上流で定義されたフラグを使用せずにコンパイルすると、{{ic|None}} ビルドタイプを使用した場合、壊れたり動作がおかしくなったりする可能性があります。フラグが足りないかどうかを判断するには、CMakeファイルを見る必要がありますし、{{ic|1=make VERBOSE=1}} の出力を {{ic|None}} と {{ic|Release}} ビルドタイプで比較することができます。もし、{{ic|None}} ビルドタイプで上流で定義されたフラグが見落とされた場合はどうすればいいのでしょうか?なぜなら、{{ic|Release}} ビルドタイプを使用すると、望ましくない {{ic|-O3}} フラグを使用する可能性があり、{{ic|None}} ビルドタイプを使用すると、いくつかの必要な上流定義フラグを見逃す可能性があるからです。この状況を解決する標準的な方法はありませんので、ケースバイケースで分析する必要があります。もし上流が {{ic|Release}} ビルドタイプに対して {{ic|-O2}} を定義しているなら、 {{ic|1=-DCMAKE_BUILD_TYPE=Release}} を使用することができます。(後述)。それ以外の場合は、CMake ファイルにパッチを当てることで解決できるかもしれません。
But unfortunately, things are not that simple like only using {{ic|1=-DCMAKE_BUILD_TYPE=None}} to fix this. When using the {{ic|None}} build type to fix the {{ic|-O3}} issue, one may fall into another problem. It is a common practice for many software projects to define some required compiler flags for the {{ic|Release}} build type in the CMake files (for example, like setting the {{ic|CMAKE_C_FLAGS_RELEASE}} and {{ic|CMAKE_CXX_FLAGS_RELEASE}} CMake variables). Such software may break or misbehave when compiled without these upstream defined flags if you use the {{ic|None}} build type. In order to determine if you are missing some flags you will need to look at the CMake files, or you can compare the output of {{ic|1=make VERBOSE=1}} for the {{ic|None}} and {{ic|Release}} build types. What to do if the {{ic|None}} build type causes some upstream defined flags to be missed? In this case you may be at the middle of two problematic situations, because if you use the {{ic|Release}} build type you may be using the undesired {{ic|-O3}} flag, and if you use the {{ic|None}} build type you will miss some required upstream defined flags. There is no standard way of solving this situation and it should be analyzed on a case-by-case basis. If upstream defines {{ic|-O2}} for the {{ic|Release}} build type, you can use {{ic|1=-DCMAKE_BUILD_TYPE=Release}} (see bellow). Otherwise, patching the CMake files may be a solution.
 
   
  +
いくつかのソフトウェアプロジェクトでは CMake ファイルに {{ic|-O2}} を {{ic|Release}} ビルドタイプとしてハードコードしています。
Some few software projects hardcode {{ic|-O2}} for the {{ic|Release}} build type in their CMake files, and thus {{ic|1=-DCMAKE_BUILD_TYPE=Release}} can be safely set in this case if you are sure that {{ic|-O2}} is the optimization level being used.
 
   
 
{{Warning|
 
{{Warning|
  +
* ビルドタイプが {{ic|None}} の場合、一部のソフトウェアが壊れる可能性があります。ビルドタイプが {{ic|None}} の場合、ソフトウェアが壊れたり、機能が失われたりしないかテストしてください。
* Some software may break when using the {{ic|None}} build type. Test the software when using the {{ic|None}} build type to check if it will break or lose functionality.
 
  +
* ソフトウェアによっては、ビルドタイプが {{ic|Release}} でないと動作しないものがあります。ソフトウェアについては、実験とテストが必要です。
* Some software may work only with the {{ic|Release}} build type. You will need to experiment and test the software.
 
 
}}
 
}}
   

2022年2月22日 (火) 22:16時点における版

この文書は cmake を使うソフトウェアの PKGBUILD を書くための標準とガイドラインをカバーしています。

はじめに

CMake web page より

CMake は、ソフトウェアをビルド、テスト、パッケージ化するために設計された、オープンソースでクロスプラットフォームのツールファミリーです。CMake は、プラットフォームやコンパイラに依存しないシンプルな設定ファイルを使ってソフトウェアのコンパイルプロセスを制御し、選択したコンパイラ環境で使用できるネイティブな makefile と workspaces を生成するために使用されます。

典型的な使用方法

典型的な使い方は、cmake コマンドを実行し、その後に building コマンドを実行することです。cmake コマンドは通常、いくつかのパラメータを設定し、必要な依存関係をチェックしてビルドファイルを作成し、ソフトウェアを makeninja といった他のツールでビルドできる状態にします。

CMakeの好ましくない動作について

ビルドファイルを生成するための内部特性により、CMake が好ましくない動作をすることがあります。そのため、CMake ベースのソフトウェアのために PKGBUILD を書くときにはいくつかのステップに注意する必要があります。

CMake はデフォルトのコンパイラ最適化フラグを自動的にオーバーライドすることができます

CMake を -DCMAKE_BUILD_TYPE=Release オプション付きで動かしている人をよく見かけます。上流のプロジェクトでは、ビルド手順にこのオプションをうっかり入れてしまうこともありますが、これは望ましくない振る舞いを生み出します。

それぞれのビルドタイプは CMake に自動的に CFLAGSCXXFLAGS にフラグのセットを追加させます。一般的な Release ビルドタイプを使うときは、自動的に -O3 [1] コンパイラ最適化フラグを追加し、これは現在 Arch Linux のデフォルトフラグである -O2 よりも優先されます。(設定ファイル makepkg configuration file で定義されています) これは Arch Linux が目標とする最適化レベルから逸脱しているので望ましくありません。

-O3 に関する注意事項

-O3 を使用したからといって、ソフトウェアのパフォーマンスが向上することを保証するものではなく、時にはプログラムの動作が遅くなることもあります。また、状況によってはソフトウェアを壊してしまうこともあります。Arch Linux の開発者がターゲット最適化レベルとして -O2 を選択したのには理由があり、私たちはそれに従うべきでしょう。あなたが何をしているかを正確に分かっている場合、またはアップストリームが -O3 が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。

自動最適化フラグオーバーライドの修正

100%保証された方法で修正することは、CMake の柔軟性により、簡単な問題ではありません。すべてのケースに適用できる標準的な解決策は存在しないことに注意してください。ここでは、考えられる解決策と、守るべきポイントについて説明します。

CMake のデフォルトのビルドタイプは None であり、デフォルトでは CFLAGSCXXFLAGS にフラグを付加しないため、 CMAKE_BUILD_TYPE オプションを使用しないだけでもデフォルトが None となり動作することがあります。しかし、多くのソフトウェアプロジェクトでは、ビルドタイプを自動的に Release に設定するため、このオプションを省略しても問題が解決する保証はないことに注意してください。コマンドラインで CMAKE_BUILD_TYPE が設定されていない場合、CMake ファイルで (または他のタイプで) 設定します。

デフォルトの None ビルドタイプは CFLAGSCXXFLAGS にフラグを付加しないので、 -DCMAKE_BUILD_TYPE=None オプションも使用可能です。一般的には -DCMAKE_BUILD_TYPE=None オプションを使う方が CMAKE_BUILD_TYPE を省略するよりも良いと言われています。これは CMAKE_BUILD_TYPE が省略されたときにアップストリームが自動的にビルドタイプを Release に設定する場合をカバーするもので、デフォルトではフラグは付加されず、ビルドタイプ None に好ましくないフラグを設定するソフトウェアはまず見当たりません。

しかし、残念ながら -DCMAKE_BUILD_TYPE=None を使えば解決するというような単純なものではありません。-O3 の問題を解決するために None のビルドタイプを使用する場合、別の問題に陥る可能性があります。多くのソフトウェアプロジェクトでは、CMake ファイルで Release ビルドタイプに必要なコンパイラフラグを定義するのが一般的です(例えば、CMAKE_C_FLAGS_RELEASECMAKE_CXX_FLAGS_RELEASE を設定するようなものです)。CMake 変数)。このようなソフトウェアは、これらの上流で定義されたフラグを使用せずにコンパイルすると、None ビルドタイプを使用した場合、壊れたり動作がおかしくなったりする可能性があります。フラグが足りないかどうかを判断するには、CMakeファイルを見る必要がありますし、make VERBOSE=1 の出力を NoneRelease ビルドタイプで比較することができます。もし、None ビルドタイプで上流で定義されたフラグが見落とされた場合はどうすればいいのでしょうか?なぜなら、Release ビルドタイプを使用すると、望ましくない -O3 フラグを使用する可能性があり、None ビルドタイプを使用すると、いくつかの必要な上流定義フラグを見逃す可能性があるからです。この状況を解決する標準的な方法はありませんので、ケースバイケースで分析する必要があります。もし上流が Release ビルドタイプに対して -O2 を定義しているなら、 -DCMAKE_BUILD_TYPE=Release を使用することができます。(後述)。それ以外の場合は、CMake ファイルにパッチを当てることで解決できるかもしれません。

いくつかのソフトウェアプロジェクトでは CMake ファイルに -O2Release ビルドタイプとしてハードコードしています。

警告:
  • ビルドタイプが None の場合、一部のソフトウェアが壊れる可能性があります。ビルドタイプが None の場合、ソフトウェアが壊れたり、機能が失われたりしないかテストしてください。
  • ソフトウェアによっては、ビルドタイプが Release でないと動作しないものがあります。ソフトウェアについては、実験とテストが必要です。

Verifying the fixes

You can verify if the fixes are being correctly used by CMake by enabling the verbose mode of the build tool. For example, when using make (which is the CMake default), this can be done by adding VERBOSE=1 to it (like make VERBOSE=1). This will enable make to output the compiler commands that are being executed. You can then run makepkg and examine the output to see if the compiler is using the -D_FORTIFY_SOURCE=2 and -O2 flags. If multiple optimization flags are being displayed in each command line, the last flag in the line will be the one used by the compiler (it means that -O2 needs to be the last optimization flag in order to be effective).

Prefix and library install directories

The standard Arch Linux /usr prefix can be specified by the -DCMAKE_INSTALL_PREFIX=/usr CMake option. This is usually needed because a lot of software defaults to install files into the /usr/local prefix.

Some upstream projects set their CMake files to install libraries into the /usr/lib64 directory. If this is the case, you can correctly set the library installation directory to /usr/lib by using the -DCMAKE_INSTALL_LIBDIR=lib CMake option.

Tips and tricks

Specifying directories

Since CMake version 3.13, there is a -B option that automatically creates the build directory. This avoids the creation of the build directory by a separated mkdir (or install) command. The -S option specifies the source directory (where to search for a CMakeLists.txt file) and avoids the need of cd'ing into the source tree before executing cmake. Combined together, these two options are a convenient way to specify the build and the source directories. For example, for building a program named foo:

PKGBUILD
build() {
    cmake -B build -S "foo-${pkgver}" [other_cmake_options]
    cmake --build build
}

Reducing possible unneeded output

The -Wno-dev CMake option will suppress the output of some warnings that are meant only for the upstream project developers who write the CMakeLists.txt files. Removing these warnings makes the CMake output smoother and reduces the burden on examining it. As a general rule, these warnings usually can be safely ignored by packagers.

Removing insecure RPATH references from binaries

Sometimes the resulting binaries can contain insecure references in RPATH. This can be verified by running Namcap on the built package and consists in a security issue that should be fixed. There is a good chance to fix this by using the CMAKE_SKIP_INSTALL_RPATH=YES or CMAKE_SKIP_RPATH=YES CMake options. You need to experiment with both and see what will work in the software in question (using both options is not needed).

Getting all available CMake options

For getting all "visible" CMake options that are available for a software project, execute cmake -LAH in the source tree (where the main CMakeLists.txt file is located).

If you want to save the output for later reference, you can redirect it to a file:

$ cmake -LAH >options.txt 2>&1

Template

Here is a general template for the build() function that serves as a starting point for CMake-based packages. Supposing the package is named foo, it is C and C++ based and that it does not define any required compiler flags for the Release build type in the CMake files.

ノート: The check function will only work if projects use enable_testing() and/or add_test() functionality in CMakeFiles.txt.
PKGBUILD
build() {
    cmake -B build -S "foo-${pkgver}" \
        -DCMAKE_BUILD_TYPE='None' \
        -DCMAKE_INSTALL_PREFIX='/usr' \
        -Wno-dev
    cmake --build build
}

check() {
    cd build
    ctest --output-on-failure
}

package() {
    DESTDIR="$pkgdir" cmake --install build
}

Do not forget to place cmake in makedepends.

Example packages

See also