「CMake パッケージガイドライン」の版間の差分
(一部翻訳) |
(→ヒントとヒントとテクニック: ビルド中の FetchContent のダウンロードを回避を翻訳して追加) |
||
(同じ利用者による、間の12版が非表示) | |||
21行目: | 21行目: | ||
ビルドファイルを生成するための内部特性により、CMake が好ましくない動作をすることがあります。そのため、CMake ベースのソフトウェアのために [[PKGBUILD]] を書くときにはいくつかのステップに注意する必要があります。 |
ビルドファイルを生成するための内部特性により、CMake が好ましくない動作をすることがあります。そのため、CMake ベースのソフトウェアのために [[PKGBUILD]] を書くときにはいくつかのステップに注意する必要があります。 |
||
− | === CMake はデフォルトのコンパイラ最適化フラグを自動的にオーバーライドすることが |
+ | === CMake はデフォルトのコンパイラ最適化フラグを自動的にオーバーライドすることがあります === |
CMake を {{ic|1=-DCMAKE_BUILD_TYPE=Release}} オプション付きで動かしている人をよく見かけます。上流のプロジェクトでは、ビルド手順にこのオプションをうっかり入れてしまうこともありますが、これは望ましくない振る舞いを生み出します。 |
CMake を {{ic|1=-DCMAKE_BUILD_TYPE=Release}} オプション付きで動かしている人をよく見かけます。上流のプロジェクトでは、ビルド手順にこのオプションをうっかり入れてしまうこともありますが、これは望ましくない振る舞いを生み出します。 |
||
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 が目標とする最適化レベルから逸脱しているので望ましくありません。 |
||
− | ==== |
+ | ==== {{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 ==== |
||
+ | 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. |
||
− | + | デフォルトの {{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. |
||
}} |
}} |
||
− | === |
+ | === 修正内容の確認 === |
+ | ビルドツールの冗長モードを有効にすることで、CMakeで修正内容が正しく使用されているかどうかを確認することができます。例えば、{{ic|make}} を使っている場合。(CMakeのデフォルトです) に {{ic|1=VERBOSE=1}} を追加することで実行できます ({{ic|1=make VERBOSE=1}} のように。) これにより、実行中のコンパイラコマンドを {{ic|make}} が出力するようになります。これで [[makepkg]] を実行し、コンパイラが {{ic|1=-D_FORTIFY_SOURCE=2}} と {{ic|-O2}} フラグを使っているか出力を確認することができます。各コマンドラインで複数の最適化フラグが表示されている場合、その行の最後のフラグがコンパイラによって使用されます({{ic|-O2}} が有効になるためには、最後の最適化フラグが必要です。) |
||
− | 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 {{ic|make}} (which is the CMake default), this can be done by adding {{ic|1=VERBOSE=1}} to it (like {{ic|1=make VERBOSE=1}}). This will enable {{ic|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 {{ic|1=-D_FORTIFY_SOURCE=2}} and {{ic|-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 {{ic|-O2}} needs to be the last optimization flag in order to be effective). |
||
− | == Prefix |
+ | == Prefix とライブラリのインストール先 == |
− | + | Arch Linux 標準の {{ic|/usr}} Prefix は {{ic|1=-DCMAKE_INSTALL_PREFIX=/usr}} CMake のオプションで指定できます。多くのソフトウェアがデフォルトでファイルを {{ic|/usr/local}} という Prefix にインストールするため、これは通常必要です。 |
|
+ | 一部のアップストリームプロジェクトは、ライブラリを {{ic|/usr/lib64}} ディレクトリにインストールするように CMake ファイルを設定します。この場合、{{ic|1=-DCMAKE_INSTALL_LIBDIR=lib}} CMake オプションを使用して、ライブラリのインストールディレクトリを {{ic|/usr/lib}} に正しく設定できます。 |
||
− | Some upstream projects set their CMake files to install libraries into the {{ic|/usr/lib64}} directory. If this is the case, you can correctly set the library installation directory to {{ic|/usr/lib}} by using the {{ic|1=-DCMAKE_INSTALL_LIBDIR=lib}} CMake option. |
||
+ | == ヒントとヒントとテクニック == |
||
− | == Tips and tricks == |
||
− | === |
+ | === ディレクトリの指定 === |
+ | CMake バージョン 3.13 以降、ビルドディレクトリを自動的に作成する {{ic|-B}} オプションが用意されています。これにより、分離された {{ic|mkdir}} によるビルドディレクトリの作成が不要になりました。(または {{ic|install}}) コマンドを使用します。{{ic|-S}} オプションはソースディレクトリ ({{ic|CMakeLists.txt}} ファイルを検索する場所) を指定し、 {{ic|cmake}} を実行する前にソースツリーに {{ic|cd}} する必要をなくしました。この2つのオプションを組み合わせると、ビルドとソースのディレクトリを指定する便利な方法となります。例えば、''foo'' という名前のプログラムをビルドする場合。 |
||
− | Since CMake version 3.13, there is a {{ic|-B}} option that automatically creates the build directory. This avoids the creation of the build directory by a separated {{ic|mkdir}} (or {{ic|install}}) command. The {{ic|-S}} option specifies the source directory (where to search for a {{ic|CMakeLists.txt}} file) and avoids the need of {{ic|cd}}'ing into the source tree before executing {{ic|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'': |
||
{{hc|1=PKGBUILD|2= |
{{hc|1=PKGBUILD|2= |
||
71行目: | 71行目: | ||
}} |
}} |
||
+ | === 不要な出力の可能性を低減する=== |
||
− | === Reducing possible unneeded output === |
||
+ | {{ic|-Wno-dev}} を使用します。CMake オプションは、{{ic|CMakeLists.txt}} ファイルを書いた上流プロジェクトの開発者のみを対象とした警告の出力を抑止します。これらの警告を削除することで、CMake の出力がスムーズになり、それを調べる負担が軽減されます。一般的なルールとして、これらの警告は通常パッケージャが安全に無視できるものです。 |
||
− | The {{ic|-Wno-dev}} CMake option will suppress the output of some warnings that are meant only for the upstream project developers who write the {{ic|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. |
||
− | === |
+ | === バイナリから安全でない {{ic|RPATH}} 参照を削除する === |
+ | 作成されたバイナリが {{ic|RPATH}} に安全でない参照を含むことがあります。これはビルドされたパッケージに対して [[Namcap]] を実行することで確認でき、修正されるべきセキュリティ問題であることがわかります。この問題は、{{ic|1=CMAKE_SKIP_INSTALL_RPATH=YES}} を使用することで修正できる可能性が高いです。または {{ic|1=CMAKE_SKIP_RPATH=YES}} CMake のオプションです。両方を使って実験し、問題のソフトウェアで何がうまくいくかを見る必要があります(両方のオプションを使うことは必要ありません。) |
||
− | Sometimes the resulting binaries can contain insecure references in {{ic|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 {{ic|1=CMAKE_SKIP_INSTALL_RPATH=YES}} '''or''' {{ic|1=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). |
||
− | === |
+ | === 利用可能な全てのCMakeオプションの取得 === |
+ | ソフトウェアプロジェクトで利用可能なすべての「見える」CMakeオプションを取得するには、ソースツリーで {{ic|cmake -LAH}} を実行します(メインの {{ic|CMakeLists.txt}} ファイルがあるところです)。 |
||
− | For getting all "visible" CMake options that are available for a software project, execute {{ic|cmake -LAH}} in the source tree (where the main {{ic|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 |
$ cmake -LAH >options.txt 2>&1 |
||
+ | === ビルド中の FetchContent のダウンロードを回避 === |
||
− | == Template == |
||
+ | CMake は、ビルド時に追加のリソースまたはサブプロジェクトを取得できるようにする [https://cmake.org/cmake/help/latest/module/FetchContent.html FetchContent] モジュールを提供します。ただし、理想的には、すべてのソースは {{ic|sources}} 配列で指定されているため、ビルド前に [[makepkg]] によってフェッチされる必要があります。これは、オプション [https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_SOURCE_DIR_%3CuppercaseName%3E FETCHCONTENT_SOURCE_DIR_<uppercaseName>] を使用して実行できます。これにより、ファイルへのパスを指定できます。それ以外の場合は取得されます。さらに、[https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_FULLY_DISCONNECTED FETCHCONTENT_FULLY_DISCONNECTED=ON] を使用すると、{{ic|FetchContent}} 宣言を見逃しても、ビルド中にすべてのダウンロードをスキップすることができます。 |
||
− | Here is a general template for the {{ic|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 {{ic|Release}} build type in the CMake files. |
||
+ | ==== 例 ==== |
||
− | {{Note|The check function will only work if projects use {{ic|enable_testing()}} and/or {{ic|add_test()}} functionality in {{ic|CMakeFiles.txt}}.}} |
||
+ | |||
+ | プロジェクトがリソース {{ic|foo}} を取得すると仮定します。 |
||
+ | |||
+ | {{hc|CMakeLists.txt|<nowiki> |
||
+ | FetchContent_Declare( |
||
+ | foo |
||
+ | URL https://example.com/foo.tar.gz |
||
+ | URL_HASH SHA256=cf051bf611a94884ba5e4c2d03932d14e83875c5b77f0fdf55c404cad0e4a6e6 |
||
+ | ) |
||
+ | FetchContent_MakeAvailable(foo) |
||
+ | </nowiki>}} |
||
+ | |||
+ | 次に、ビルド中にダウンロードする代わりに、このリソースを {{ic|sources}} 配列に追加し、ビルド ファイルの生成時に宣言できます。 |
||
+ | |||
+ | {{hc|PKGBUILD|<nowiki> |
||
+ | sources=( |
||
+ | ... |
||
+ | "https://example.com/foo.tar.gz" |
||
+ | ) |
||
+ | |||
+ | sha256sums=( |
||
+ | ... |
||
+ | "cf051bf611a94884ba5e4c2d03932d14e83875c5b77f0fdf55c404cad0e4a6e6" |
||
+ | ) |
||
+ | </nowiki>}} |
||
+ | |||
+ | $ cmake -B build -S "$pkgname-$pkgver" -DFETCHCONTENT_FULLY_DISCONNECTED=ON -DFETCHCONTENT_SOURCE_DIR_FOO="$srcdir/foo" |
||
+ | |||
+ | == テンプレート == |
||
+ | |||
+ | ここでは、CMake ベースのパッケージの出発点となる {{ic|build()}} 関数の一般的なテンプレートについて説明します。パッケージの名前は ''foo'' で、C および C++ ベースであり、CMake ファイルの中で {{ic|Release}} ビルドタイプに必要なコンパイラフラグを定義していないと仮定します。 |
||
+ | |||
+ | {{Note|このチェック機能は {{ic|enable_testing()}} と {{ic|add_test()}} が {{ic|CMakeFiles.txt}}}} で使われている場合のみ働きます。 |
||
{{hc|1=PKGBUILD|2= |
{{hc|1=PKGBUILD|2= |
||
112行目: | 145行目: | ||
}} |
}} |
||
− | + | {{Pkg|cmake}} を [[PKGBUILD#makedepends|makedepends]] に配置することを忘れないでください。 |
|
− | == |
+ | == パッケージの例 == |
* {{Pkg|i2pd}} |
* {{Pkg|i2pd}} |
||
* {{Pkg|libmysofa}} |
* {{Pkg|libmysofa}} |
||
− | == |
+ | == 参照 == |
− | * [https://cmake.org/documentation/ CMake |
+ | * [https://cmake.org/documentation/ CMake ドキュメント] |
− | * [https://cmake.org/cmake/help/latest/ |
+ | * [https://cmake.org/cmake/help/latest/ 最新バージョンのドキュメントリファレンス] |
− | * [[Wikipedia:CMake| |
+ | * [[Wikipedia:ja:CMake|CMake Wikipedia]] |
* {{man|1|cmake}} |
* {{man|1|cmake}} |
2023年10月30日 (月) 03:47時点における最新版
32ビット – CLR – クロス – Eclipse – Electron – Free Pascal – GNOME – Go – Haskell – Java – KDE – カーネル – Lisp – MinGW – Node.js – ノンフリー – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – ウェブ – Wine
この文書は cmake を使うソフトウェアの PKGBUILD を書くための標準とガイドラインをカバーしています。
はじめに
CMake は、ソフトウェアをビルド、テスト、パッケージ化するために設計された、オープンソースでクロスプラットフォームのツールファミリーです。CMake は、プラットフォームやコンパイラに依存しないシンプルな設定ファイルを使ってソフトウェアのコンパイルプロセスを制御し、選択したコンパイラ環境で使用できるネイティブな makefile と workspaces を生成するために使用されます。
典型的な使用方法
典型的な使い方は、cmake
コマンドを実行し、その後に building コマンドを実行することです。cmake
コマンドは通常、いくつかのパラメータを設定し、必要な依存関係をチェックしてビルドファイルを作成し、ソフトウェアを make
や ninja
といった他のツールでビルドできる状態にします。
CMakeの好ましくない動作について
ビルドファイルを生成するための内部特性により、CMake が好ましくない動作をすることがあります。そのため、CMake ベースのソフトウェアのために PKGBUILD を書くときにはいくつかのステップに注意する必要があります。
CMake はデフォルトのコンパイラ最適化フラグを自動的にオーバーライドすることがあります
CMake を -DCMAKE_BUILD_TYPE=Release
オプション付きで動かしている人をよく見かけます。上流のプロジェクトでは、ビルド手順にこのオプションをうっかり入れてしまうこともありますが、これは望ましくない振る舞いを生み出します。
それぞれのビルドタイプは CMake に自動的に CFLAGS
と CXXFLAGS
にフラグのセットを追加させます。一般的な Release
ビルドタイプを使うときは、自動的に -O3
[1] コンパイラ最適化フラグを追加し、これは現在 Arch Linux のデフォルトフラグである -O2
よりも優先されます。(設定ファイル makepkg configuration file で定義されています) これは Arch Linux が目標とする最適化レベルから逸脱しているので望ましくありません。
-O3
に関する注意事項
-O3
を使用したからといって、ソフトウェアのパフォーマンスが向上することを保証するものではなく、時にはプログラムの動作が遅くなることもあります。また、状況によってはソフトウェアを壊してしまうこともあります。Arch Linux の開発者がターゲット最適化レベルとして -O2
を選択したのには理由があり、私たちはそれに従うべきでしょう。あなたが何をしているかを正確に分かっている場合、またはアップストリームが -O3
が必要であると明示的・暗示的に言っている場合以外は、私たちのパッケージで使用するのは避けるべきです。
自動最適化フラグオーバーライドの修正
100%保証された方法で修正することは、CMake の柔軟性により、簡単な問題ではありません。すべてのケースに適用できる標準的な解決策は存在しないことに注意してください。ここでは、考えられる解決策と、守るべきポイントについて説明します。
CMake のデフォルトのビルドタイプは None
であり、デフォルトでは CFLAGS
と CXXFLAGS
にフラグを付加しないため、 CMAKE_BUILD_TYPE
オプションを使用しないだけでもデフォルトが None
となり動作することがあります。しかし、多くのソフトウェアプロジェクトでは、ビルドタイプを自動的に Release
に設定するため、このオプションを省略しても問題が解決する保証はないことに注意してください。コマンドラインで CMAKE_BUILD_TYPE
が設定されていない場合、CMake ファイルで (または他のタイプで) 設定します。
デフォルトの None
ビルドタイプは CFLAGS
と CXXFLAGS
にフラグを付加しないので、 -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_RELEASE
と CMAKE_CXX_FLAGS_RELEASE
を設定するようなものです) CMake 変数)このようなソフトウェアは、これらの上流で定義されたフラグを使用せずにコンパイルすると、None
ビルドタイプを使用した場合、壊れたり動作がおかしくなったりする可能性があります。フラグが足りないかどうかを判断するには、CMakeファイルを見る必要がありますし make VERBOSE=1
の出力を None
と Release
ビルドタイプで比較することができます。もし、None
ビルドタイプで上流で定義されたフラグが見落とされた場合はどうすればいいのでしょうか?なぜなら、Release
ビルドタイプを使用すると、望ましくない -O3
フラグを使用する可能性があり、None
ビルドタイプを使用すると、いくつかの必要な上流定義フラグを見逃す可能性があるからです。この状況を解決する標準的な方法はありませんので、ケースバイケースで分析する必要があります。もし上流が Release
ビルドタイプに対して -O2
を定義しているなら、 -DCMAKE_BUILD_TYPE=Release
を使用することができます。(後述) それ以外の場合は、CMake ファイルにパッチを当てることで解決できるかもしれません。
いくつかのソフトウェアプロジェクトでは CMake ファイルに -O2
を Release
ビルドタイプとしてハードコードしています。
修正内容の確認
ビルドツールの冗長モードを有効にすることで、CMakeで修正内容が正しく使用されているかどうかを確認することができます。例えば、make
を使っている場合。(CMakeのデフォルトです) に VERBOSE=1
を追加することで実行できます (make VERBOSE=1
のように。) これにより、実行中のコンパイラコマンドを make
が出力するようになります。これで makepkg を実行し、コンパイラが -D_FORTIFY_SOURCE=2
と -O2
フラグを使っているか出力を確認することができます。各コマンドラインで複数の最適化フラグが表示されている場合、その行の最後のフラグがコンパイラによって使用されます(-O2
が有効になるためには、最後の最適化フラグが必要です。)
Prefix とライブラリのインストール先
Arch Linux 標準の /usr
Prefix は -DCMAKE_INSTALL_PREFIX=/usr
CMake のオプションで指定できます。多くのソフトウェアがデフォルトでファイルを /usr/local
という Prefix にインストールするため、これは通常必要です。
一部のアップストリームプロジェクトは、ライブラリを /usr/lib64
ディレクトリにインストールするように CMake ファイルを設定します。この場合、-DCMAKE_INSTALL_LIBDIR=lib
CMake オプションを使用して、ライブラリのインストールディレクトリを /usr/lib
に正しく設定できます。
ヒントとヒントとテクニック
ディレクトリの指定
CMake バージョン 3.13 以降、ビルドディレクトリを自動的に作成する -B
オプションが用意されています。これにより、分離された mkdir
によるビルドディレクトリの作成が不要になりました。(または install
) コマンドを使用します。-S
オプションはソースディレクトリ (CMakeLists.txt
ファイルを検索する場所) を指定し、 cmake
を実行する前にソースツリーに cd
する必要をなくしました。この2つのオプションを組み合わせると、ビルドとソースのディレクトリを指定する便利な方法となります。例えば、foo という名前のプログラムをビルドする場合。
PKGBUILD
build() { cmake -B build -S "foo-${pkgver}" [other_cmake_options] cmake --build build }
不要な出力の可能性を低減する
-Wno-dev
を使用します。CMake オプションは、CMakeLists.txt
ファイルを書いた上流プロジェクトの開発者のみを対象とした警告の出力を抑止します。これらの警告を削除することで、CMake の出力がスムーズになり、それを調べる負担が軽減されます。一般的なルールとして、これらの警告は通常パッケージャが安全に無視できるものです。
バイナリから安全でない RPATH
参照を削除する
作成されたバイナリが RPATH
に安全でない参照を含むことがあります。これはビルドされたパッケージに対して Namcap を実行することで確認でき、修正されるべきセキュリティ問題であることがわかります。この問題は、CMAKE_SKIP_INSTALL_RPATH=YES
を使用することで修正できる可能性が高いです。または CMAKE_SKIP_RPATH=YES
CMake のオプションです。両方を使って実験し、問題のソフトウェアで何がうまくいくかを見る必要があります(両方のオプションを使うことは必要ありません。)
利用可能な全てのCMakeオプションの取得
ソフトウェアプロジェクトで利用可能なすべての「見える」CMakeオプションを取得するには、ソースツリーで cmake -LAH
を実行します(メインの CMakeLists.txt
ファイルがあるところです)。
もし、後で参照するために出力を保存したい場合は、ファイルにリダイレクトすることができます。
$ cmake -LAH >options.txt 2>&1
ビルド中の FetchContent のダウンロードを回避
CMake は、ビルド時に追加のリソースまたはサブプロジェクトを取得できるようにする FetchContent モジュールを提供します。ただし、理想的には、すべてのソースは sources
配列で指定されているため、ビルド前に makepkg によってフェッチされる必要があります。これは、オプション FETCHCONTENT_SOURCE_DIR_<uppercaseName> を使用して実行できます。これにより、ファイルへのパスを指定できます。それ以外の場合は取得されます。さらに、FETCHCONTENT_FULLY_DISCONNECTED=ON を使用すると、FetchContent
宣言を見逃しても、ビルド中にすべてのダウンロードをスキップすることができます。
例
プロジェクトがリソース foo
を取得すると仮定します。
CMakeLists.txt
FetchContent_Declare( foo URL https://example.com/foo.tar.gz URL_HASH SHA256=cf051bf611a94884ba5e4c2d03932d14e83875c5b77f0fdf55c404cad0e4a6e6 ) FetchContent_MakeAvailable(foo)
次に、ビルド中にダウンロードする代わりに、このリソースを sources
配列に追加し、ビルド ファイルの生成時に宣言できます。
PKGBUILD
sources=( ... "https://example.com/foo.tar.gz" ) sha256sums=( ... "cf051bf611a94884ba5e4c2d03932d14e83875c5b77f0fdf55c404cad0e4a6e6" )
$ cmake -B build -S "$pkgname-$pkgver" -DFETCHCONTENT_FULLY_DISCONNECTED=ON -DFETCHCONTENT_SOURCE_DIR_FOO="$srcdir/foo"
テンプレート
ここでは、CMake ベースのパッケージの出発点となる build()
関数の一般的なテンプレートについて説明します。パッケージの名前は foo で、C および C++ ベースであり、CMake ファイルの中で Release
ビルドタイプに必要なコンパイラフラグを定義していないと仮定します。
で使われている場合のみ働きます。
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 }
cmake を makedepends に配置することを忘れないでください。