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

提供: ArchWiki
ナビゲーションに移動 検索に移動
(一部翻訳)
27行目: 27行目:
 
それぞれのビルドタイプは CMake に自動的に {{ic|CFLAGS}} と {{ic|CXXFLAGS}} にフラグのセットを追加させます。一般的な {{ic|Release}} ビルドタイプを使うときは、自動的に {{ic|-O3}} [https://github.com/Kitware/CMake/blob/v3.17.0/Modules/Compiler/GNU.cmake#L58] コンパイラ最適化フラグを追加し、これは現在 Arch Linux のデフォルトフラグである {{ic|-O2}} よりも優先されます。(設定ファイル [[Makepkg#Configuration|makepkg configuration file]] で定義されています) これは Arch Linux が目標とする最適化レベルから逸脱しているので望ましくありません。
 
それぞれのビルドタイプは CMake に自動的に {{ic|CFLAGS}} と {{ic|CXXFLAGS}} にフラグのセットを追加させます。一般的な {{ic|Release}} ビルドタイプを使うときは、自動的に {{ic|-O3}} [https://github.com/Kitware/CMake/blob/v3.17.0/Modules/Compiler/GNU.cmake#L58] コンパイラ最適化フラグを追加し、これは現在 Arch Linux のデフォルトフラグである {{ic|-O2}} よりも優先されます。(設定ファイル [[Makepkg#Configuration|makepkg configuration file]] で定義されています) これは Arch Linux が目標とする最適化レベルから逸脱しているので望ましくありません。
   
==== Notes about {{ic|-O3}} ====
+
==== {{ic|-O3}} に関する注意事項 ====
   
  +
{{ic|-O3}} を使用したからといって、ソフトウェアのパフォーマンスが向上することを保証するものではなく、時にはプログラムの動作が遅くなることもあります。また、状況によってはソフトウェアを壊してしまうこともあります。Arch Linux の開発者がターゲット最適化レベルとして {{ic|-O2}} を選択したのには理由があり、私たちはそれに従うべきでしょう。あなたが何をしているかを正確に分かっている場合、またはアップストリームが {{ic|-O3}} が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。
Using {{ic|-O3}} does not guarantee that the software will perform better, and sometimes it can even slow down the program. It can also break software in some situations. There is a good reason why the Arch Linux developers choose {{ic|-O2}} as the target optimization level and we should stick with it. Unless you know exactly what you are doing, or if upstream explicitly tells or implies that {{ic|-O3}} is needed, we should avoid using it in our packages.
 
   
 
==== Fixing the automatic optimization flag override ====
 
==== Fixing the automatic optimization flag override ====

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

この文書は 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 が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。

Fixing the automatic optimization flag override

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.

The default CMake build type is None and it does not append any flags to CFLAGS and CXXFLAGS by default, so simply omitting the usage of the CMAKE_BUILD_TYPE option can work as it will default to None. But note that omitting this option is not guaranteed to fix the problem, as many software projects automatically set the build type to Release (or other type) in the CMake files if CMAKE_BUILD_TYPE is not set at command line.

Since the default None build type does not append any flags to CFLAGS and CXXFLAGS by default, using the -DCMAKE_BUILD_TYPE=None option can also work. Generally speaking, using the -DCMAKE_BUILD_TYPE=None option is better than omitting the usage of CMAKE_BUILD_TYPE. It will cover the case when upstream automatically sets the build type to Release when 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 None build type.

But unfortunately, things are not that simple like only using -DCMAKE_BUILD_TYPE=None to fix this. When using the None build type to fix the -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 Release build type in the CMake files (for example, like setting the CMAKE_C_FLAGS_RELEASE and CMAKE_CXX_FLAGS_RELEASE CMake variables). Such software may break or misbehave when compiled without these upstream defined flags if you use the 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 make VERBOSE=1 for the None and Release build types. What to do if the 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 Release build type you may be using the undesired -O3 flag, and if you use the 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 -O2 for the Release build type, you can use -DCMAKE_BUILD_TYPE=Release (see bellow). Otherwise, patching the CMake files may be a solution.

Some few software projects hardcode -O2 for the Release build type in their CMake files, and thus -DCMAKE_BUILD_TYPE=Release can be safely set in this case if you are sure that -O2 is the optimization level being used.

警告:
  • Some software may break when using the None build type. Test the software when using the None build type to check if it will break or lose functionality.
  • Some software may work only with the Release build type. You will need to experiment and test the software.

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