Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / gil / CONTRIBUTING.md
1 # Contributing to Boost.GIL
2
3 Boost.GIL is a member of [Boost](https://www.boost.org) libraries.
4
5 If you wish to contribute a new feature or a bug fix,
6 please follow the workflow explained in this document.
7
8 ## Table of Content
9
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)
25
26 ## Prerequisites
27
28 - C++11 compiler
29 - Build and run-time dependencies for tests and examples:
30   - Boost.Filesystem
31   - Boost.Test
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.
40
41 ## Pull Requests
42
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
65   to track changes.
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).
71
72 ### Merging Pull Requests (for maintainers with write access)
73
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.
83
84 ## Getting started with Git workflow
85
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.
89
90 The following steps are based on the official Boost
91 [Getting Started](https://github.com/boostorg/boost/wiki/Getting-Started).
92
93 **NOTE:** For brevity, commands below use notation for POSIX-like operating
94 systems and you may need to tweak them for Windows systems.
95
96 ### 1. Clone Boost super-project
97
98 The preparation involves the following steps:
99
100 1. Clone the Boost super-project
101
102     ```shell
103     git clone --recurse-submodules --jobs 8 https://github.com/boostorg/boost.git
104     ```
105
106 2. Switch the Boost super-project to desired branch, `master` or `develop`
107
108     ```shell
109     cd boost
110     git checkout master
111     ```
112
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:
117
118     ```shell
119     cd boost
120     git checkout master
121     git pull
122     git submodule update --init --recursive --jobs 8
123     ```
124
125 3. Build the `b2` driver program for Boost.Build engine.
126
127     ```shell
128     ./bootstrap.sh
129     ./b2 --version
130     ```
131
132     **TIP:** For more convenient path-less invocation, you can copy the `b2`
133     program to a location in your `PATH`.
134
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.
139
140     ```shell
141     ./b2 -j8 headers
142     ```
143
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
147 its modules:
148
149 ```shell
150 git clean -xfd
151 git submodule foreach --recursive git clean -xfd
152 git reset --hard
153 git submodule foreach --recursive git reset --hard
154 git submodule update --init --recursive --jobs 8
155 ```
156
157 ### 2. Checkout Boost.GIL development branch
158
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.
162
163 1. Go to the Boost.GIL library submodule.
164
165     ```shell
166     cd libs/gil
167     ```
168
169 2. Checkout the `develop` branch and bring it up to date
170
171     ```shell
172     git checkout develop
173     git branch -vv
174     git pull origin develop
175     ```
176
177 ### 3. Fork Boost.GIL repository on GitHub
178
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/).
183
184 Add your fork as git remote to the Boost.GIL submodule:
185
186 ```shell
187 cd libs/gil
188 git remote add <username> https://github.com/<username>/gil.git
189 ```
190
191 or, if you cloned from your fork already, add the upstream as `origin` remote:
192
193 ```shell
194 git remote add upstream https://github.com/boostorg/gil.git
195 # or
196 git remote rename origin <username>
197 git remote add origin https://github.com/boostorg/gil.git
198 ```
199
200 ### 4. Submit a pull request
201
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).
204
205 **IMPORTANT:** Pull Requests *must* come from a branch based on `develop`,
206 and *never* on `master`.
207
208 **NOTE:** The branching workflow model
209 [Boost recommends](https://svn.boost.org/trac10/wiki/StartModWorkflow)
210 is called Git Flow.
211
212 For example:
213
214 ```shell
215 cd libs/gil
216 git checkout develop
217 git checkout -b feature/foo
218 ```
219
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.
223
224 Once it's finished, you can submit it as pull request for review:
225
226 ```shell
227 cd libs/gil
228 git checkout feature/foo
229 git push <username> feature/foo
230 ```
231
232 Finally, sign in to your GitHub account and
233 [create a pull request](https://help.github.com/articles/creating-a-pull-request/).
234
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.
239
240 ### 5. Update your pull request
241
242 Depending on actual purpose of the update, you can follow a different
243 strategy to update your pull request:
244
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.
249
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.
254
255 #### Synchronise pull request branch
256
257 Keep your topic branch up to date and synchronized with the upstream `develop` branch:
258
259 ```shell
260 cd libs/gil
261 git checkout develop
262 git pull origin develop
263 git checkout feature/foo
264 ```
265
266 If review of your work has not started, *prefer* to merge:
267
268 ```shell
269 git merge develop
270 git push <username> feature/foo
271 ```
272
273 If your PR is still *work-in-progress*, you may rebase if you like:
274
275 ```shell
276 git rebase develop
277 git push --force <username> feature/foo
278 ```
279
280 #### Amend last commit of pull request
281
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:
284
285 ```shell
286 cd libs/gil
287 git checkout feature/foo
288 git add -A
289 git commit --amend
290 git push --force <username> feature/foo
291 ```
292
293 #### Add new commits to pull request
294
295 In order to update your pull request, for example in response to a change
296 request from reviewer, just add new commits:
297
298 ```shell
299 cd libs/gil
300 git checkout feature/foo
301 git add -A
302 git commit -m "Fix build Travis CI failures"
303 git push <username> feature/foo
304 ```
305
306 ## Development
307
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.
311
312 By default, Boost.GIL uses Boost.Build to build all the executables.
313
314 We also provide configuration for two alternative build systems:
315
316 - [CMake](https://cmake.org)
317 - [Faber](http://stefan.seefeld.name/faber/)
318
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.
322
323 ### Install dependencies
324
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:
327
328 ```shell
329 sudo apt-get install libjpeg-dev libpng-dev libtiff5-dev libraw-dev
330 ```
331
332 ### Using Boost.Build
333
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.
336
337 Simply, just execute `b2` to run all tests built using default
338 `variant=debug` and default `toolset` determined for your
339 development environment.
340
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.
343
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:
346
347 ```shell
348 cd libs/gil
349 ../../b2
350 ```
351
352 Run core tests only specifying location of directory with tests:
353
354 ```shell
355 cd libs/gil
356 ../../b2 -j8 test/core
357 ```
358
359 Run all tests for selected extension (from Boost root directory, as alternative):
360
361 ```shell
362 ./b2 -j8 libs/gil/test/io
363 ./b2 -j8 libs/gil/test/numeric
364 ./b2 -j8 libs/gil/test/toolbox
365 ```
366
367 Run I/O extension tests bundled in target called `simple`:
368
369 ```shell
370 ./b2 libs/gil/test/io//simple
371 ```
372
373 ### Using CMake
374
375 Maintainer: [@mloskot](https://github.com/mloskot)
376
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.
380
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.
384
385 The provided CMake configuration allows a couple of ways to develop Boost.GIL:
386
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:
395
396   ```shell
397   ./b2 -j8 headers
398   ./b2 -j8 variant=debug --with-test --with-filesystem stage
399   ./b2 -j8 variant=release --with-test --with-filesystem stage
400   ```
401
402   or, depending on specific requirements, more complete build:
403
404   ```shell
405   ./b2 -j8 variant=debug,release address-model=32,64 --layout=versioned --with-test --with-filesystem stage
406   ```
407
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.
411
412 **TIP:** For the lightweight setup, prefer latest release of Boost.
413
414 For available custom CMake options, open the top-level `CMakeLists.txt`
415 and search for `option`.
416
417 Here is an example of such lightweight workflow in Linux environment (Debian-based):
418
419 - Install required Boost libraries
420
421     ```shell
422     sudo apt-get update
423     sudo apt-get install libboost-dev libboost-test-dev libboost-filesystem-dev
424     ```
425
426 - Clone Boost.GIL repository
427
428     ```shell
429     git clone https://github.com/boostorg/gil.git
430     cd gil
431     ```
432
433 - Configure build with CMake
434
435     ```shell
436     mkdir _build
437     cd _build/
438     cmake ..
439     ```
440
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`.
446
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.
458
459 - List available CMake targets
460
461     ```shell
462     cmake --build . --target help
463     ```
464
465 - Build selected target with CMake
466
467     ```shell
468     cmake --build . --target gil_test_pixel
469     ```
470
471 - List available CTest targets
472
473     ```shell
474     ctest --show-only | grep Test
475     ```
476
477 - Run selected test with CTest
478
479     ```shell
480     ctest -R gil.tests.core.pixel
481     ```
482
483 #### CMake configuration for Visual Studio
484
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.
488
489 #### CMake configuration for Visual Studio Code
490
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.
494
495 ### Using Faber
496
497 Maintainer: [@stefanseefeld](https://github.com/stefanseefeld)
498
499 *TODO:* _Describe_
500
501 ### Running clang-tidy
502
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.
505
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.
510
511 #### Linting
512
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.
517
518 ```shell
519 cd libs/gil
520 cmake -S . -B _build -DGIL_USE_CLANG_TIDY=ON
521
522 # all targets
523 cmake --build _build
524
525 # selected target
526 cmake --build _build --target test_headers_all_in_one
527 ```
528
529 #### Refactoring
530
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.
533
534 1. Generate `compile_commands.json` database
535
536     ```shell
537     cd libs/gil
538     cmake -S . -B _build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
539     ```
540
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.
544
545 3. Run the parallel `clang-tidy` runner script to apply the desired checks (and fixes)
546     across the library source code:
547
548     ```shell
549     run-clang-tidy.py -p=_build -header-filter='boost\/gil\/.*' -checks='-*,modernize-use-using' -fix > cl.log 2>&1
550     ```
551
552 ## Guidelines
553
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.
558
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).
561
562 Second, strive for writing idiomatic C++11, clean and elegant code.
563
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.*
567
568 Maintain structure your source code files according to the following guidelines:
569
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
576
577     ```cpp
578     #ifndef BOOST_GIL_<DIR1>_<DIR2>_<FILE>_HPP
579     #define BOOST_GIL_<DIR1>_<DIR2>_<FILE>_HPP
580     ...
581     #endif
582     ```
583
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.
594
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/