1 # Contributing to Boost.GIL
3 Boost.GIL is a member of [Boost](https://www.boost.org) libraries.
5 If you wish to contribute a new feature or a bug fix,
6 please follow the workflow explained in this document.
10 - [Prerequisites](#prerequisites)
11 - [Pull Requests](#pull-requests)
12 - [Getting started with Git workflow](#getting-started-with-git-workflow)
13 - [1. Clone Boost super-project](#1-clone-boost-super-project)
14 - [2. Checkout Boost.GIL development branch](#2-checkout-boostgil-development-branch)
15 - [3. Fork Boost.GIL repository on GitHub](#3-fork-boostgil-repository-on-github)
16 - [4. Submit a pull request](#4-submit-a-pull-request)
17 - [5. Update your pull request](#5-update-your-pull-request)
18 - [Development](#development)
19 - [Install dependencies](#install-dependencies)
20 - [Using Boost.Build](#using-boostbuild)
21 - [Using CMake](#using-cmake)
22 - [Using Faber](#using-faber)
23 - [Running clang-tidy](#running-clang-tidy)
24 - [Guidelines](#guidelines)
29 - Build and run-time dependencies for tests and examples:
32 - Headers and libraries of libjpeg, libpng, libtiff, libraw for the I/O extension.
33 - Experience with `git` command line basics.
34 - Familiarity with build toolset and development environment of your choice.
35 - Although this document tries to present all commands with necessary options,
36 it may be a good idea to skim through the
37 [Boost Getting Started](https://www.boost.org/more/getting_started/index.html)
38 chapters, especially if you are going to use
39 [Boost.Build](https://boostorg.github.io/build/) for the first time.
43 - **DO** submit all major changes to code via pull requests (PRs) rather than through
44 a direct commit. PRs will be CI-checked first, then reviewed and potentially merged
45 by the repo maintainers after a peer review that includes at least one maintainer.
46 Contributors with commit access may submit trivial patches or changes to the project
47 infrastructure configuration via direct commits (CAUTION!)
48 - **DO NOT** mix independent, unrelated changes in one PR.
49 Separate unrelated fixes into separate PRs, especially if they are in different components
50 (e.g. core headers versus extensions).
51 Separate real product/test code changes from larger code formatting/dead code removal changes,
52 unless the former are extensive enough to justify such refactoring, then also mention it.
53 - **DO** start PR subject with "WIP:" tag if you submit it as "work in progress".
54 A PR should preferably be submitted when it is considered ready for review and subsequent
55 merging by the contributor. Otherwise, clearly indicate it is not yet ready.
56 The "WIP:" tag will also help maintainers to label your PR with [status/work-in-progress].
57 - **DO** give PRs short-but-descriptive names (e.g. "Add test for algorithm XXX", not "Fix #1234").
58 - **DO** [refer] to any relevant issues, and include the [keywords] that automatically
59 close issues when the PR is merged.
60 - **DO** [mention] any users that should know about and/or review the change.
61 - **DO** ensure each commit successfully builds. The entire PR must pass all tests in
62 the Continuous Integration (CI) system before it'll be merged.
63 - **DO** address PR feedback in an additional commit(s) rather than amending the existing
64 commits, and only rebase/squash them when necessary. This makes it easier for reviewers
66 - **DO** assume that the [Squash and Merge] will be used to merge your commit unless you
67 request otherwise in the PR.
68 - **DO** NOT fix merge conflicts using a merge commit. Prefer git rebase.
69 - **DO** NOT submit changes to the original legacy tests, see
70 [test/legacy/README.md](test/legacy/README.md).
72 ### Merging Pull Requests (for maintainers with write access)
74 - **DO** use [Squash and Merge] by default for individual contributions unless requested
75 by the PR author. Do so, even if the PR contains only one commit. It creates a simpler
76 history than [Create a Merge Commit]. Reasons that PR authors may request the true
77 merge recording a merge commit may include (but are not limited to):
78 - The change is easier to understand as a series of focused commits.
79 Each commit in the series must be buildable so as not to break git bisect.
80 - Contributor is using an e-mail address other than the primary GitHub address
81 and wants that preserved in the history.
82 Contributor must be willing to squash the commits manually before acceptance.
84 ## Getting started with Git workflow
86 First, you need learn some minimal basics of the
87 [modular Boost](https://svn.boost.org/trac/boost/wiki/ModularBoost)
88 super-project workflow.
90 The following steps are based on the official Boost
91 [Getting Started](https://github.com/boostorg/boost/wiki/Getting-Started).
93 **NOTE:** For brevity, commands below use notation for POSIX-like operating
94 systems and you may need to tweak them for Windows systems.
96 ### 1. Clone Boost super-project
98 The preparation involves the following steps:
100 1. Clone the Boost super-project
103 git clone --recurse-submodules --jobs 8 https://github.com/boostorg/boost.git
106 2. Switch the Boost super-project to desired branch, `master` or `develop`
113 **TIP:** [Modular Boost Library Maintenance](https://svn.boost.org/trac10/wiki/StartModMaint)
114 guide, for more realistic test environment, recommends to develop and test
115 individual Boost library against other Boost libraries as defined by
116 the Boost super-project `master` branch:
122 git submodule update --init --recursive --jobs 8
125 3. Build the `b2` driver program for Boost.Build engine.
132 **TIP:** For more convenient path-less invocation, you can copy the `b2`
133 program to a location in your `PATH`.
135 4. Optionally, create full content of `/boost` virtual directory with
136 all Boost headers linked from the individual modular Boost libraries.
137 If you skip this step, executing `b2` to run tests will automatically
138 create the directory with all headers required by Boost.GIL and tests.
144 **TIP:** If something goes wrong, you end up with incomplete or accidentally
145 modified files in your clone of the super-project repository, or you simply
146 wish to start fresh, then you can clean and reset the whole repository and
151 git submodule foreach --recursive git clean -xfd
153 git submodule foreach --recursive git reset --hard
154 git submodule update --init --recursive --jobs 8
157 ### 2. Checkout Boost.GIL development branch
159 Regardless if you decide to develop again `master` (recommended) or `develop`
160 branch of the Boost super-project, you should *always* base your contributions
161 (i.e. topic branches) on Boost.GIL `develop` branch.
163 1. Go to the Boost.GIL library submodule.
169 2. Checkout the `develop` branch and bring it up to date
174 git pull origin develop
177 ### 3. Fork Boost.GIL repository on GitHub
179 Follow [Forking Projects](https://guides.github.com/activities/forking/) guide
180 to get personal copy of [boostorg/gil](https://github.com/boostorg/gil)
181 repository from where you will be able to submit new contributions as
182 [pull requests](https://help.github.com/articles/about-pull-requests/).
184 Add your fork as git remote to the Boost.GIL submodule:
188 git remote add <username> https://github.com/<username>/gil.git
191 or, if you cloned from your fork already, add the upstream as `origin` remote:
194 git remote add upstream https://github.com/boostorg/gil.git
196 git remote rename origin <username>
197 git remote add origin https://github.com/boostorg/gil.git
200 ### 4. Submit a pull request
202 All Boost.GIL contributions should be developed inside a topic branch created by
203 branching off the `develop` branch of [boostorg/gil](https://github.com/boostorg/gil).
205 **IMPORTANT:** Pull Requests *must* come from a branch based on `develop`,
206 and *never* on `master`.
208 **NOTE:** The branching workflow model
209 [Boost recommends](https://svn.boost.org/trac10/wiki/StartModWorkflow)
217 git checkout -b feature/foo
220 Now, you are set to to develop a new feature for Boost.GIL,
221 then [git add](https://git-scm.com/docs/git-add) and
222 [git commit](https://git-scm.com/docs/git-commit) your changes.
224 Once it's finished, you can submit it as pull request for review:
228 git checkout feature/foo
229 git push <username> feature/foo
232 Finally, sign in to your GitHub account and
233 [create a pull request](https://help.github.com/articles/creating-a-pull-request/).
235 Your pull request will be automatically built and tests will run on Travis CI
236 and AppVeyor (see [README](README.md) for builds status). Please, keep an eye
237 on those CI builds and correct any problems detected in your contribution
238 by updating your pull request.
240 ### 5. Update your pull request
242 Depending on actual purpose of the update, you can follow a different
243 strategy to update your pull request:
245 - Use `git commit --amend`, `git rebase` and `git push --force` when your
246 pull request is still *work-in-progress* and not ready for review yet.
247 - Use `git commit`, `git merge` and `git push` to update your pull request
248 during review, in response to requests from reviewers.
250 **NOTE:** Once review of your work has started, you should not rebase your work.
251 You should create new commits and update your topic branch. This helps with
252 traceability in the pull request and prevents the accidental history breakage.
253 Those who review your work may be fetching it into their fork for local review.
255 #### Synchronise pull request branch
257 Keep your topic branch up to date and synchronized with the upstream `develop` branch:
262 git pull origin develop
263 git checkout feature/foo
266 If review of your work has not started, *prefer* to merge:
270 git push <username> feature/foo
273 If your PR is still *work-in-progress*, you may rebase if you like:
277 git push --force <username> feature/foo
280 #### Amend last commit of pull request
282 If your pull request is a *work-in-progress* and has not been reviewed yet,
283 you may amend your commit or rebase onto the `develop` branch:
287 git checkout feature/foo
290 git push --force <username> feature/foo
293 #### Add new commits to pull request
295 In order to update your pull request, for example in response to a change
296 request from reviewer, just add new commits:
300 git checkout feature/foo
302 git commit -m "Fix build Travis CI failures"
303 git push <username> feature/foo
308 Boost.GIL is a [header-only library](https://en.wikipedia.org/wiki/Header-only)
309 which does not require sources compilation. Only test runners and
310 [example](example/README.md) programs have to be compiled.
312 By default, Boost.GIL uses Boost.Build to build all the executables.
314 We also provide configuration for two alternative build systems:
316 - [CMake](https://cmake.org)
317 - [Faber](http://stefan.seefeld.name/faber/)
319 **NOTE:** The CMake and Faber are optional and the corresponding build
320 configurations for Boost.GIL do not offer equivalents for all Boost.Build features. Most important difference to recognise is that Boost.Build will
321 automatically build any other Boost libraries required by Boost.GIL as dependencies.
323 ### Install dependencies
325 Boost.GIL tests and examples use the GIL I/O extension which depends on
326 third-party libraries for read and write support of specific image formats:
329 sudo apt-get install libjpeg-dev libpng-dev libtiff5-dev libraw-dev
332 ### Using Boost.Build
334 The [b2 invocation](https://boostorg.github.io/build/manual/develop/index.html#bbv2.overview.invocation)
335 explains available options like `toolset`, `variant` and others.
337 Simply, just execute `b2` to run all tests built using default
338 `variant=debug` and default `toolset` determined for your
339 development environment.
341 **TIP:** Pass `b2` option `-d 2` to output complete action text and commands,
342 as they are executed. It is useful to inspect compilation flags.
344 If no target or directory is specified, everything in the current directory
345 is built. For example, all Boost.GIL tests can be built and run using:
352 Run core tests only specifying location of directory with tests:
356 ../../b2 -j8 test/core
359 Run all tests for selected extension (from Boost root directory, as alternative):
362 ./b2 -j8 libs/gil/test/io
363 ./b2 -j8 libs/gil/test/numeric
364 ./b2 -j8 libs/gil/test/toolbox
367 Run I/O extension tests bundled in target called `simple`:
370 ./b2 libs/gil/test/io//simple
375 Maintainer: [@mloskot](https://github.com/mloskot)
377 **WARNING:** The CMake configuration is only provided for convenience
378 of contributors. It does not export or install any targets, deploy
379 config files or support subproject workflow.
381 **NOTE:** CMake configuration does not build any dependencies required by
382 Boost.GIL like Boost.Test and Boost.Filesystem libraries or any
383 third-party image format libraries used by the I/O extension.
385 The provided CMake configuration allows a couple of ways to develop Boost.GIL:
387 1. Using Boost installed from binary packages in default system-wide location.
388 2. Using Boost installed from sources in arbitrary location (CMake may need
389 `-DBOOST_ROOT=/path/to/boost/root`, see
390 [FindBoost](https://cmake.org/cmake/help/latest/module/FindBoost.html)
391 documentation for details).
392 3. Using [cloned Boost super-project](#cloned-boost-super-project), inside modular
393 `libs/gil`. This mode requires prior deployment of `boost` virtual directory
394 with headers and stage build of required libraries, for example:
398 ./b2 -j8 variant=debug --with-test --with-filesystem stage
399 ./b2 -j8 variant=release --with-test --with-filesystem stage
402 or, depending on specific requirements, more complete build:
405 ./b2 -j8 variant=debug,release address-model=32,64 --layout=versioned --with-test --with-filesystem stage
408 Using the installed Boost enables a lightweight mode for the library development,
409 inside a stand-alone clone Boost.GIL repository and without any need to clone the
410 whole Boost super-project.
412 **TIP:** For the lightweight setup, prefer latest release of Boost.
414 For available custom CMake options, open the top-level `CMakeLists.txt`
415 and search for `option`.
417 Here is an example of such lightweight workflow in Linux environment (Debian-based):
419 - Install required Boost libraries
423 sudo apt-get install libboost-dev libboost-test-dev libboost-filesystem-dev
426 - Clone Boost.GIL repository
429 git clone https://github.com/boostorg/gil.git
433 - Configure build with CMake
441 **TIP:** By default, tests and [examples](example/README.md) are compiled using
442 the minimum required C++11.
443 Specify `-DCMAKE_CXX_STANDARD=14|17|20` to use newer version.
444 For more CMake options available for GIL, check `option`-s defined
445 in the top-level `CMakeLists.txt`.
447 **TIP:** If CMake is failing to find Boost libraries, especially built
448 with `--layout=versioned`, you can try a few hacks:
449 - option `-DBoost_ARCHITECTURE=-x64` to help CMake find Boost 1.66 and above
450 add an architecture tag to the library file names in versioned build
451 The option added in CMake 3.13.0.
452 - option `-DBoost_COMPILER=-gcc5` or `-DBoost_COMPILER=-vc141` to help CMake earlier
453 than 3.13 match your compiler with toolset used in the Boost library file names
454 (i.e. `libboost_unit_test_framework-gcc5-mt-x64-1_69` and not `-gcc55-`).
455 Fixed in CMake 3.13.0.
456 - if CMake is still failing to find Boost, you may try `-DBoost_DEBUG=ON` to
457 get detailed diagnostics output from `FindBoost.cmake` module.
459 - List available CMake targets
462 cmake --build . --target help
465 - Build selected target with CMake
468 cmake --build . --target gil_test_pixel
471 - List available CTest targets
474 ctest --show-only | grep Test
477 - Run selected test with CTest
480 ctest -R gil.tests.core.pixel
483 #### CMake configuration for Visual Studio
485 We provide [example/cmake/CMakeSettings.json](https://github.com/boostorg/gil/blob/develop/example/cmake/CMakeSettings.json)
486 with reasonable default settings for the [CMake support in Visual Studio](https://go.microsoft.com//fwlink//?linkid=834763).
487 See [example/cmake/README.md](example/cmake/README.md) for more details.
489 #### CMake configuration for Visual Studio Code
491 We provide [example/cmake/cmake-variants.yaml](https://github.com/boostorg/gil/blob/develop/example/cmake/cmake-variants.yaml)
492 with reasonable default settings for the [CMake Tools](https://github.com/vector-of-bool/vscode-cmake-tools) extension.
493 See [example/cmake/README.md](example/cmake/README.md) for more details.
497 Maintainer: [@stefanseefeld](https://github.com/stefanseefeld)
501 ### Running clang-tidy
503 [clang-tidy](http://clang.llvm.org/extra/clang-tidy/) can be run on demand to
504 diagnose or diagnose and fix or refactor source code issues.
506 Since the CMake configuration is provided for building tests and [examples](example/README.md),
507 it is easy to run `clang-tidy` using either the integration built-in CMake 3.6+
508 as target property `CXX_CLANG_TIDY` or the compile command database which
509 can be easily generated.
513 This mode uses the CMake built-in integration and runs `clang-tidy` checks configured
514 in [.clang-tidy](https://github.com/boostorg/gil/blob/develop/.clang-tidy).
515 All custom compilation warning levels (e.g. `-Wall`) are disabled and
516 compiler defaults are used.
520 cmake -S . -B _build -DGIL_USE_CLANG_TIDY=ON
526 cmake --build _build --target test_headers_all_in_one
531 **WARNING:** This is advanced processing and depending on checks, it may fail to deliver
532 expected results, especially if run against all configured translation units at ones.
534 1. Generate `compile_commands.json` database
538 cmake -S . -B _build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
541 2. Edit `compile_commands.json` and remove entries of commands for all but the `.cpp`
542 files you wish to refactor. For example, keep `test_headers_all_in_one.cpp` only
543 to refactor all headers.
545 3. Run the parallel `clang-tidy` runner script to apply the desired checks (and fixes)
546 across the library source code:
549 run-clang-tidy.py -p=_build -header-filter='boost\/gil\/.*' -checks='-*,modernize-use-using' -fix > cl.log 2>&1
554 Boost.GIL is a more than a decade old mature library maintained by several
555 developers with help from a couple of dozens contributors.
556 It is important to maintain consistent design, look and feel.
557 Thus, below a few basic guidelines are listed.
559 First and foremost, make sure you are familiar with the official
560 [Boost Library Requirements and Guidelines](https://www.boost.org/development/requirements.html).
562 Second, strive for writing idiomatic C++11, clean and elegant code.
564 **NOTE:** *The Boost.GIL source code does not necessary represent clean and elegant
565 code to look up to. The library has recently entered the transition to C++11.
566 Major refactoring overhaul is ongoing.*
568 Maintain structure your source code files according to the following guidelines:
570 - Name files in meaningful way.
571 - Put copyright and license information in every file
572 - If your changes [meet a certain threshold of originality](https://www.boost.org/users/license.html),
573 add yourself to the copyright notice. Do not put any additional authorship or
574 file comments (eg. no `\file` for Doxygen), revision information, etc.
575 - In header, put `#include` guard based on header path and file name
578 #ifndef BOOST_GIL_<DIR1>_<DIR2>_<FILE>_HPP
579 #define BOOST_GIL_<DIR1>_<DIR2>_<FILE>_HPP
584 - Make sure each [header is self-contained](https://github.com/boostorg/gil/wiki/Include-Directives-Order), i.e. that they include all headers they need.
585 - All public headers should be placed in `boost/gil/` or `boost/gil/<component>/`.
586 - All non-public headers should be placed `boost/gil/detail` or `boost/gil/<component>/detail`.
587 - All public definitions should reside in scope of `namespace boost { namespace gil {...}}`.
588 - All non-public definitions should reside in scope of `namespace boost { namespace gil { namespace detail {...}}}`.
589 - Write your code to fit within **100** columns of text.
590 - Use [EditorConfig](https://editorconfig.org) for your editor and enable [.editorconfig](https://github.com/boostorg/gil/blob/develop/.editorconfig) to:
591 - Indent with **4 spaces** and no tabs.
592 - Trim any trailing whitespaces.
593 - Do not increases the indentation level within namespace.
595 [status/work-in-progress]: https://github.com/boostorg/gil/labels/status%2Fwork-in-progress
596 [refer]: https://help.github.com/articles/autolinked-references-and-urls/
597 [keywords]: https://help.github.com/articles/closing-issues-using-keywords/
598 [mention]: https://help.github.com/articles/basic-writing-and-formatting-syntax/#mentioning-people-and-teams
599 [squash and merge]: https://help.github.com/articles/merging-a-pull-request/
600 [create a merge commit]: https://help.github.com/articles/merging-a-pull-request/