1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
|
# CONTRIBUTING
Instructions and conventions for people wanting to work on librsync. Please
consider these guidelines even if you're doing your own fork.
## Requirements
There are a bunch of tools and libraries that are useful for development or
that librsync depends on. In addition to the standard cmake/gcc/make/etc C
development tools, the following packages are recommended;
* libpopt-dev - the cmdline argument parsing library used by rdiff. If this is
not available rdiff cannot be compiled, and only the librsync library will
be compiled.
* libb2-dev - blake2 hash library librsync can use if `USE_LIBB2` is set to
`ON` in cmake. If this is not avalable librsync will use its included copy
of blake2 (which may be older... or newer).
* doxygen - documentation generator used to generate html documentation. If
installed `make doc` can be run to generate all the docs.
* graphviz - graph generator used by doxygen for generating diagrams. If not
installed doxygen will not generate any diagrams.
* indent - code reformatter for tidying code. If installed all the code can be
tidied with `make tidy`.
* [tidyc](https://github.com/dbaarda/tidyc) - extension wrapper for indent
that includes better formatting of doxygen comments. If installed code and
comments can be tidied with `make tidyc`.
* clang-tidy - code lint checker for potential problems. If installed the code
can be checked with `make clang-tidy`.
* iwyu - `#include` checker and fixer. If installed includes can be checked
with `make iwyu`, and automatically fixed with `make iwyu-fix`. Note on some
platforms this package is [missing a
dependency](https://bugs.launchpad.net/ubuntu/+source/iwyu/+bug/1769334) and
also needs `libclang-common-9-dev` to be installed.
These can all be installed on Debian/Ubuntu systems by running;
```Shell
$ apt-get update
$ apt-get install libpopt-dev libb2-dev doxygen graphviz indent clang-tidy iwyu
$ git clone https://github.com/dbaarda/tidyc.git
$ cp tidyc/tidyc ~/bin
```
### Windows
Not all the recommended packages are easily available on windows.
[Cygwin](https://cygwin.com/) and [MSYS2](http://msys2.org/) provide a
development environment similar to Linux. Some packages can also be found on
[Chocolatey](https://chocolatey.org/). For native development using standard
MSVC tools, libpopt can be found on [vcpkg](https://vcpkg.io/) and installed
by running;
```Shell
$ vcpkg update
$ vcpkg --triplet x64-windows install libpopt
```
For cmake to find the installed libpopt you need to add `-D
CMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake` to the cmake
cmdline. This configures cmake to correctly search the vcpkg install locations
to find libraries.
### MacOS
MacOS is generally more similar to Linux than Windows, and several packages
are available on homebrew. The libpopt library can be installed by running;
```Shell
$ brew update
$ brew install popt
```
## Building
The minimal instructions to fetch, configure, compile, and test everything
using a in-place default Debug build with trace enabled using the internal
blake2 implementation is;
```Shell
$ git clone https://github.com/librsync/librsync.git
$ cd librsync
$ cmake .
$ make check
```
For cmake, `-B` can be used to select a separate build directory, and `-G` can
select a different make system. Also the following settings can be changed
with `-D <setting>=<value>` arguments when generating the project with cmake;
* CMAKE_BUILD_TYPE=(Debug|Release|MinSizeRel|RelWithDebInfo) - the build type
to use, which selects compiler options. The default is `Debug`.
* CMAKE_C_COMPILER=(cc|gcc|clang|...) - The compiler to use. The default is to
auto-detect the available compiler on the platform.
* BUILD_RDIFF=(ON|OFF) - Whether to build and test the rdiff executable.
Defaults to ON if libpopt is available.
* BUILD_SHARED_LIBS=(ON|OFF) - Whether to build dynamic libraries or use
static linking. Defaults to ON.
* ENABLE_TRACE=(ON|OFF) - Whether to enable trace output in the library and
for rdiff using `-v`. Trace output can help with debugging but its a little
faster with ENABLE_TRACE=OFF. Defaults to ON for Debug builds, and OFF for
others.
* USE_LIBB2=(ON|OFF) - Whether to use libb2 instead of the included blake2
implementation. Defaults to OFF.
So for a Release build in a separate directory using Ninja, clang, static
linking, and libb2 with trace enabled, do this instead;
```Shell
$ cmake -B build -G Ninja
-D CMAKE_C_COMPILER=clang \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D USE_LIBB2=ON \
-D ENABLE_TRACE=ON
$ cmake --build build --config Release --target check
```
You can also use ccmake or cmake-gui to interactively configure and generate
into a separate build directory with;
```Shell
$ ccmake -B build
```
## Coding
The prefered style for code is equivalent to using GNU indent with the
following arguments;
```Shell
$ indent -linux -nut -i4 -ppi2 -l80 -lc80 -fc1 -sob -T FILE -T Rollsum -T rs_result
```
The preferred style for non-docbook comments are as follows;
```C
/*=
| A short poem that
| shall never ever be
| reformated or reindented
*/
/* Single line comment indented to match code indenting. */
/* Blank line delimited paragraph multi-line comments.
Without leading stars, or blank line comment delimiters. */
int a; /* code line comments */
```
The preferred style for docbook comments is javadoc with autobrief as
follows;
```C
/** /file file.c
* Brief summary paragraph.
*
* With blank line paragraph delimiters and leading stars.
*
* /param foo parameter descriptions...
*
* /param bar ...in separate blank-line delimited paragraphs.
*
* Example:/code
* code blocks that will never be reformated.
* /endcode
*
* Without blank-line comment delimiters. */
int a; /**< brief attribute description */
int b; /**< multiline attribute description
*
* With blank line delimited paragraphs.*/
```
There is a `make tidy` target that will use GNU indent to reformat all code
and non-docbook comments, doing some pre/post processing with sed to handle
some corner cases indent doesn't handle well.
There is a `make tidyc` target that will reformat all code and comments with
[tidyc](https://github.com/dbaarda/tidyc). This will also correctly reformat
all docbook comments, equivalent to running tidyc with the following
arguments;
```Shell
$ tidyc -R -C -l80 -T FILE -T Rollsum -T rs_result
```
There is `make clang-tidy` and `make iwyu` targets for checking for coding
errors and incorrect `#include` statements. Note that the iwyu check gets
confused by and will emit warnings about `fileutil.c` which has extra
conditional includes necessary to find working functions on various platforms.
Other than `fileutil.c` both checks should be clean.
If iwyu finds problems, `make ifwu-fix` can be run to automatically fix them,
followed by `make tidyc` to reformat the result to our preferred style. Note
that this doesn't always produce an ideal result and may require manual
intervention.
Please try to update docs and tests in parallel with code changes.
## Testing
Using `make check` will compile and run all tests. Additional code correctness
checks can be run with `make clang-tidy` and `make iwyu`.
Note that `assert()` is used extensively within the code for verifying the
correctness of internal operations using a roughly design-by-contract
approach. These are only enabled for Debug builds, so testing with a Debug
build will give a better chance of identifying problems during development.
Once you are confident the code is correct, a Release build will turn these
off giving faster execution.
There are also GitHub Actions configured for the librsync project to
configure, build, test, and lint everything on a variety of different
platforms with a variety of different settings. These are run against any pull
request or commit, and are a good way to check things are not broken for other
platforms.
Test results for builds of public github branches are at
https://github.com/librsync/librsync/actions.
## Documenting
[NEWS.md](NEWS.md) contains a list of user-visible changes in the library
between release versions. This includes changes to the way it's packaged, bug
fixes, portability notes, changes to the API, and so on. Add and update items
under a "Changes in X.Y.Z" heading at the top of the file. Do this as you go
along, so that we don't need to work out what happened when it's time for a
release.
[TODO.md](TODO.md) contains a list of ideas and proposals for the future.
Ideally entries should be formated in a way that can be just moved into
[NEWS.md](NEWS.md) when they are done. Regularly check to see if there is
anything that needs removing or updating.
## Submitting
Fixes or improvements in pull requests are welcome. Please:
- [ ] Send small PRs that address one issues each.
- [ ] Update `NEWS.md` to say what you changed.
- [ ] Add a test as a self-contained C file in `tests/` that passes or fails,
and is hooked into `CMakeLists.txt`.
- [ ] Keep the code style consistent with what's already there, especially in
keeping symbols with an `rs_` prefix.
## Releasing
If you are making a new tarball release of librsync, follow this checklist:
* Make a "Release vx.x.x" pull request containing updates ready for the
release including;
* Review the changes included and decide if the release should be a major
(non-backwards compatible change), minor (backwards compatible change),
or micro (bugfix only change) version number change to get the new
"X.Y.Z" version number.
* NEWS.md - make sure the top "Changes in X.Y.Z" is correct, and the date
is correct. Make sure the changes since the last release are documented.
* TODO.md - check if anything needs to be removed or updated.
* `CMakeLists.txt` - version is correct.
* `librsync.spec` - make sure version and URL are right.
* Run `make all doc check` in a clean checkout of the release pull request
branch. Also check the GitHub Actions [check and lint
status](https://github.com/librsync/librsync/actions) of the last commit on
github. If it all looks good merge the release pull request on github.
* Draft a new release on github, typing in the release details including an
overview, included changes, and known issues. The overview should give an
indication of the magnitude of the changes and their impact, and the
relative urgency to upgrade. The included changes should come from the
NEWS.md for the release. It's probably easiest to copy and edit the previous
release.
* After creating the release, download the `Source code (tar.gz)` release
asset. Go to "Actions", find the workflow run for the "Check" corresponding
to the merge of the release pull request, and download the `install results
windows-latest Release` artifact renamed to `librsync-win64-X.Y.Z.zip`. Edit
the release, and upload the source code and windows artifacts. This ensures
that the release includes a stable tarball (See
https://github.com/librsync/librsync/issues/146 for details) and win64
install.
* Run `make doc` on a clean checkout of the new release tag and `cp -av html/*`
into a `rm -Rf *` emptied checkout of librsync.github.io and check it in.
This ensures it includes deletes of obsolete files as well as new and
updated files. Push this to update the online docs.
* Create and merge a "Prepare vX.Y.Z+1." pull request containing updates to
prepare for the changes in the next release including;
* Bump the minor version in `CMakeLists.txt`.
* Add a `NOT RELEASED YET` version entry in `NEWS.md`
* Bump the minor version and add a `%changelog` entry in `librsync.spec`.
|