開発プラクティス

GDAL への変更

バグ修正などの小さな変更は, GitHub プルリクエストを作成して行うことができます.

大きな変更は gdal-dev リストサーバで議論されるべきであり, RFC (リクエストフォーコメント) ドキュメントの作成が必要な場合があります.

GDAL における大規模なコード追加に関するポリシーは, RFC 85: Policy regarding substantial code additions に記載されています.

ポータビリティ

GDAL は,32 ビットおよび 64 ビットのコンピューティング環境,リトルエンディアンおよびビッグエンディアンの CPU に広くポータブルであるように努めています.ポートディレクトリの CPL 関数は,プラットフォーム固有の操作を抽象化するサービスを提供します.

一般的に,メモリ割り当て,パス解析,ファイルシステム I/O(VSILFILE* / VSIVirtualFile* を使用),ODBC アクセスなどの操作において,OS 関数の代わりに CPL 関数を使用するべきです.

C/C++ 標準

GDAL/OGR で採用されている現在の C および C++ 標準は,C99 および C++17 です(RFC 98: Build requirements for GDAL 3.9 で最終更新).

変数名

多くの既存の GDAL/OGR コードは,適応型ハンガリア命名規則を使用しています.この規則の使用は必須ではありませんが,この規則を使用しているコードを維持する場合は,変更時に引き続きこれに従うことが望ましいです.最も重要なのは,それを不適切に使用しないようにすることです.それは非常に混乱を招く可能性があるためです.

ハンガリア命名法では,接頭辞は変数の型や意味について何かを伝えます.以下は,GDAL/OGR で使用されるいくつかの接頭辞です.

  • a: 配列

  • b: C/C++ bool. C99 採用以前の C コードでは,TRUE/FALSE 値のみを持つ int にも使用されます.

  • by: バイト (GByte / unsigned char).

  • df: 浮動小数点数 (倍精度)

  • e: 列挙

  • i: ゼロベースの配列またはループインデックスとして使用される整数.

  • f: 浮動小数点数 (単精度)

  • h: 不透明なハンドル (GDALDatasetH など).

  • n: 整数 (サイズ未指定)

  • o: C++ オブジェクト

  • os: CPLString または std::string

  • p: ポインタ

  • psz: ヌル終端文字列へのポインタ (例."char *pszName;")

  • sz: ヌル終端文字列 (例." char szName[100];")

  • k: コンパイル時定数

接頭辞は重ねることができます.以下は,意味のある変数のいくつかの例です.

  • *char !*papszTokens: 文字列の配列へのポインタ.

  • *int panBands: 数値の配列の最初の要素へのポインタ.

  • *double padfScanline: 倍精度浮動小数点数の配列の最初の要素へのポインタ.

  • *double pdfMeanRet: 単一の倍精度浮動小数点数へのポインタ.

  • *GDALRasterBand poBand: 単一のオブジェクトへのポインタ.

  • *GByte pabyHeader: バイトの配列へのポインタ.

変数名の標準的な規則は,変数名の各単語の先頭を大文字にすることです.

関数およびクラスの命名

  • 関数およびクラスは,シンボルの衝突を回避するために十分な名前空間 ("GDAL" または "OGR" 接頭辞,または C++ 名前空間の使用) を持つべきです.

ファイル名とコードのフォーマット

  • すべてのソースファイル (.h, .c, .cpp, .py など) には,著作権表示と GDAL X/MIT ライセンスのテキストが含まれているヘッダーが必要です.

  • 小文字のファイル名を使用します.

  • C++ ファイルには .cpp 拡張子を使用します (.cc ではありません).

  • C/C++ コードのフォーマットルールは, .clang-format で定義されています.Python コードのフォーマットは Black によって強制されます. pre-commit ユーティリティを使用して,これらを自動的に強制する必要があります. コミットフック を参照してください.

メモリ割り当て

大規模なメモリ割り当ては, VSIMalloc() ファミリの関数を使用して行うべきです.これにより, nullptr が返されます. RFC 19: Safer memory allocation in GDAL に従って, VSIMalloc2() を使用することができます.これにより, CPLMalloc(x * y) または VSIMalloc(x * y) を行う代わりに,潜在的なオーバーフローを検出し,それが発生した場合は NULL ポインタを返します.これは, x と y がラスタの寸法またはラスタブロックサイズに関連している GDAL ラスタドライバで有用です.同様に, VSIMalloc3(x, y, z) は, CPLMalloc(x * y * z) の代わりに使用できます.

std::bad_alloc をスローする可能性がある std::vector などの標準ライブラリデータ構造を使用する場合,大量のメモリを割り当てる可能性のあるブロックの周りに try/catch ブロックを使用する必要があります.

新しいドライバの追加

  • ドライバがサードパーティライブラリに依存している場合,ドライバのコンパイルはライブラリの存在に依存する必要があります.ドライバは,可能な限り既存のライブラリ依存関係を再利用するようにする必要があります. 例: SAX XML パーサリングのための Expat.

  • ベクトルドライバの場合,ドライバの Open() メソッド (しばしばデータソースの Open() メソッドに委任される) が十分に選択的であることを確認してください.つまり,ドライバに適していないデータファイルを受け入れないこと,および十分に堅牢であること (認識するコンテンツに対する小さな変化に対してクラッシュしないこと) を確認してください.異常なファイル名に対処できるかどうかを確認してください. GDAL ドライバの場合,オプションの Identify() メソッドについても同様のチェックを行ってください.

  • ドライバをカバーするテストセットを Python テストスイートに追加する必要があります.適切な場合,小さなサンプルデータファイルを autotest/gdrivers/data または autotest/ogr/data に追加することができます.``test_ogrsf`` ユーティリティと GDALTest クラスは,基本的なドライバ機能のテストを簡素化することができます.

  • ドライバのためのドキュメントページを作成する必要があります.ドキュメントは,最低限,ドライバで処理されるフォーマットについて簡単に説明し,接続文字列,作成オプション,構成オプションなどの特定の構文を説明する必要があります.ドキュメントは,より詳細なフォーマットの説明へのリンクを提供し,必要なサードパーティライブラリを言及する必要があります.

テストの書き方

新しいテストの書き方に関する推奨事項 を参照してください.

Git の使用

このセクションでは,GDAL 開発のための git 使用のいくつかのベストプラクティスをまとめています.

作業リポジトリの初期化

GitHub UI から OSGeo/gdal をフォークし,次に以下を実行します:

git clone https://github.com/OSGeo/gdal
cd gdal
git remote add my_user_name git@github.com:my_user_name/gdal.git

フィーチャーブランチでの作業

git checkout master
# potentially update your local master against upstream, as described above
git checkout -b my_new_feature_branch

# do work. For example:
git add my_new_file
git add my_modifid_message
git rm old_file
git commit -a

# you may need to resynchronize against master if you need some bugfix
# or new capability that has been added since you created your branch
git fetch origin
git rebase origin/master

# At end of your work, make sure history is reasonable by folding non
# significant commits into a consistent set
git rebase -i master
# use 'fixup' for example to merge several commits together,
# and 'reword' to modify commit messages

# or alternatively, in case there is a big number of commits and marking
# all them as 'fixup' is tedious
git fetch origin
git rebase origin/master
git reset --soft origin/master
git commit -a -m "Put here the synthetic commit message"

# push your branch
git push my_user_name my_new_feature_branch

GitHub UI からプルリクエストを発行します.

プルリクエストの議論や自動チェックで変更が必要な場合,ローカルでコミットしてプッシュします.適切な履歴を取得するためには,``git rebase -i master`` を使用してコミットを結合する必要があります.その場合,``git push -f my_user_name my_new_feature_branch`` でブランチを強制プッシュする必要があります.

ローカルの master をアップストリームの master に更新する

git checkout master
git fetch origin

# Be careful: this will lose all local changes you might have done now
git reset --hard origin/master

コミットメッセージ

コミットメッセージには,コンポーネント名 (例: ドライバ名),短い説明,および適切な場合には,問題への参照 ('fixes #' が実際に修正している場合) を示すべきです.

COMPONENT_NAME: fix bla bla (fixes #1234)

Details here...

コミットフック

GDAL は,コミット前にコードフォーマッタやリンタを実行するための pre-commit フックを提供しています.フックはリポジトリと共にクローンされ,`pre-commit <https://pre-commit.com>`_ を使用してインストールすることができます:

python3 -m pip install pre-commit
pre-commit install

インストールされると,フックは pre-commit run --all-files を使用して手動で実行できます.

Blame 無視ファイル

GDAL 3.7 開発中に行われた全体ツリーコードの再フォーマットにより,``git blame`` 情報が誤解を招く可能性があります.それを避けるために,以下のように git 設定を変更して,全体ツリーリフォーマットのリビジョンを無視する必要があります:

git config blame.ignoreRevsFile .git-blame-ignore-revs

master から安定ブランチにバグ修正をバックポートする

git checkout master
With git log, identify the sha1sum of the commit you want to backport
git checkout 2.2 # if you want to backport to 2.2
git pull origin 2.2
# git checkout -b branch_name  # if you intend to submit the backport as a pull request
git cherry-pick the_sha1_sum
git push ...

変更が必要な場合,それを行い,``git commit -a --amend`` を実行します

行ってはいけないこと

(OSGeo/gdal にプッシュ権限を持つ人向け) コミットを修正したり, https://github.com/OSGeo/gdal にコミットされたものの履歴を修正したりしてはいけません.

シンボリックリンクをコミットすることは,Windows での潜在的な問題を回避するために,.github ディレクトリ内でのみ許可されています.

ソースツリーレイアウト

  • alg: アルゴリズム: ラスタ化,ポリゴン化,ワーパーエンジンなど.

  • apps: C++ コマンドラインユーティリティ

  • autotest: リグレッションテストスイート (C++ および Python)

  • cmake: CMake モジュールとヘルパー関数

  • doc: GDAL ドキュメントおよびスクリプトのソースコード

  • docker: GDAL Docker イメージ の Dockerfile

  • gcore: ラスタコア機能. ベースクラス: GDALDataset, GDALRasterBand, GDALDriver, 概要ビルドなど.

  • frmts: GDAL/ラスタドライバ (主に,ogr/ogrsf_frmts/gpkg の GDAL GeoPackage ラスタサポートを除く)

  • fuzzer: GDAL OSS-Fuzz 統合 のソースコードとスクリプト

  • gnm: 地理ネットワークデータモデル のソースコード

  • ogr: OGR ベクトルコアクラス: OGRFieldDefn, OGRGeomFieldDefn, OGRFeatureDefn, OGRGeometry および派生クラス, OGR SQL など.

  • ogr/ogrsf_frmts: OGR/ベクトルドライバ

  • ogr/ogrsf_frmts/generic: OGR ベクトルコアクラス: OGRLayer, OGR SQL 汎用レイヤー

  • port: CPL (Common Portability Library)

  • perftests: GDAL のさまざまな側面の速度/パフォーマンスをチェックするための C++ および Python スクリプト.

  • scripts: 継続的インテグレーション,リリース生成,およびその他の補助タスクに使用されるさまざまなユーティリティスクリプト.いずれもエンドユーザー向けではありません.

  • swig/include: SWIG Python, Java, C# バインディングの定義

  • swig/python/gdal-utils/scripts: インストールされた/公開された GDAL Python ユーティリティのランチャースクリプト.実際の機能はありません

  • swig/python/gdal-utils/osgeo_utils: GDAL Python ユーティリティのコアコード.PyPI gdal および gdal-utils パッケージで利用可能です.

  • swig/python/gdal-utils/samples: インストールされていないスクリプトであり,一般的にはほとんどまたはほとんどドキュメント化されていません.将来公式として昇格される予定のスクリプトのステージングエリアとして機能するかもしれません.

  • swig/python/gdal-utils/auxiliary: GDAL Python ユーティリティで使用されるヘルパーメソッドとクラス.PyPI gdal および gdal-utils パッケージで利用可能です.

  • third_party: libgdal で使用されるサードパーティライブラリ. 他のものは以下で見つけることができます:

    • alg/internal_libqhull

    • apps/argparse

    • frmts/gtiff/libtiff

    • frmts/gtiff/libgeotiff

    • frmts/hdf4/hdf-eos

    • frmts/jpeg/libjpeg

    • frmts/jpeg/libjpeg12

    • frmts/grib/degrib/degrib

    • frmts/grib/degrib/g2clib

    • frmts/pcidsk/sdk

    • frmts/pcraster/libcsf

    • frmts/png/libpng

    • frmts/gif/giflib

    • frmts/zlib/

    • ogr/ogrsf_frmts/cad/libopencad

    • ogr/ogrsf_frmts/geojson/libjson

    • ogr/ogrsf_frmts/flatgeobuf/flatbuffers

    • ogr/ogrsf_frmts/pmtiles/pmtiles

    • ogr/ogrsf_frmts/sqlite/sqlite_rtree_bulk_load