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 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
|
Contributing to PAPPL
=====================
PAPPL is developed and distributed as open source software under the Apache
License, Version 2.0. Contributions should be submitted as pull requests on
the Github site:
http://github.com/michaelrsweet/pappl/pulls
Contents
--------
- [Build System](#build-system)
- [Version Numbering](#version-numbering)
- [Coding Guidelines](#coding-guidelines)
- [Source Files](#source-files)
- [Header Files](#header-files)
- [Comments](#comments)
- [Indentation](#indentation)
- [Spacing](#spacing)
- [Return Values](#return-values)
- [Functions](#functions)
- [Variables](#variables)
- [Types](#types)
- [Structures](#structures)
- [Constants](#constants)
- [Shell Script Guidelines](#shell-script-guidelines)
- [Makefile Guidelines](#makefile-guidelines)
- [General Organization](#general-organization)
- [Makefile Documentation](#makefile-documentation)
- [Portable Makefile Construction](#portable-makefile-construction)
- [Standard Variables](#standard-variables)
- [Standard Targets](#standard-targets)
- [Object Files](#object-files)
- [Programs](#programs)
- [Static Libraries](#static-libraries)
- [Shared Libraries](#shared-libraries)
- [Dependencies](#dependencies)
- [Install/Uninstall Support](#installuninstall-support)
Build System
------------
The build system uses GNU autoconf to tailor the library to the local operating
system. Visual Studio and Xcode projects are also provided in the "vcnet" and
"xcode" directories for Windows and macOS, respectively. To improve
portability, makefiles *must not* make use of features unique to GNU make. See
the [Makefile Guidelines](#makefile-guidelines) section for a description of the
allowed make features and makefile guidelines.
Additional GNU build programs such as GNU automake and GNU libtool *must not* be
used. GNU automake produces non-portable makefiles which depend on GNU-specific
extensions, and GNU libtool is not portable or reliable enough for PAPPL.
Version Numbering
-----------------
PAPPL uses a three-part version number separated by periods to represent the
major, minor, and patch release numbers. Major release numbers indicate large
design changes or backwards-incompatible changes to the library. Minor release
numbers indicate new features and other smaller changes which are backwards-
compatible with previous releases. Patch numbers indicate bug fixes to the
previous feature or patch release.
> Note:
>
> When we talk about compatibility, we are talking about binary compatibility
> for public APIs and output format compatibility for program interfaces.
> Changes to configuration file formats or the default behavior of programs
> are not generally considered incompatible as the upgrade process can
> normally address such changes gracefully.
Production releases use the plain version numbers:
MAJOR.MINOR.PATCH
1.0.0
1.0.1
1.0.2
...
1.1.0
...
2.0.0
The first production release in a MAJOR.MINOR series (MAJOR.MINOR.0) is called
a feature release. Feature releases are the only releases that may contain new
features. Subsequent production releases in a MAJOR.MINOR series may only
contain bug fixes.
Beta-test releases are identified by appending the letter B to the major and
minor version numbers followed by the beta release number:
MAJOR.MINORbNUMBER
1.0b1
Release candidates are identified by appending the letters RC to the major and
minor version numbers followed by the release candidate number:
MAJOR.MINORrcNUMBER
1.0rc1
Coding Guidelines
-----------------
Contributed source code must follow the guidelines below. While the examples
are for C source files, source code for other languages should conform to the
same guidelines as allowed by the language.
PAPPL requires at least C99 support for all C code. Aside from adding the
`bool` type and `//` comments, C99 also clarifies the `NULL` behavior of certain
standard functions such as `free` and `realloc`.
### Source Files
All source files names must be 16 characters or less in length to ensure
compatibility with older UNIX filesystems. Source files containing functions
have an extension of ".c" for C files and ".m" for Objective C files. All
"include" files have an extension of ".h". Tabs are set to 8 characters or
columns.
The top of each source file contains a header giving the purpose or nature of
the source file and the copyright and licensing notice:
//
// Description of file contents.
//
// Copyright YYYY by AUTHOR.
//
// Licensed under Apache License v2.0. See the file "LICENSE" for more
// information.
//
### Header Files
Private API header files must be named with the suffix "-private", for example
the "pappl.h" header file defines all of the public APIs while the
"pappl-private.h" header file defines all of the private APIs. Typically a
private API header file will include the corresponding public API header file.
### Comments
All source code utilizes block comments within functions to describe the
operations being performed by a group of statements; avoid putting a comment
per line unless absolutely necessary, and then consider refactoring the code
so that it is not necessary. C source files use the C99 comment format
("// comment"):
// Clear the state array before we begin...
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
array[i] = PAPPL_STATE_IDLE;
// Wait for state changes on another thread...
do
{
for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
if (array[i] != PAPPL_STATE_IDLE)
break;
if (i == (sizeof(array) / sizeof(array[0])))
sleep(1);
} while (i == (sizeof(array) / sizeof(array[0])));
### Indentation
All code blocks enclosed by brackets begin with the opening brace on a new
line. The code then follows starting on a new line after the brace and is
indented 2 spaces. The closing brace is then placed on a new line following
the code at the original indentation:
{
int i; // Looping var
// Process foobar values from 0 to 999...
for (i = 0; i < 1000; i ++)
{
do_this(i);
do_that(i);
}
}
Single-line statements following "do", "else", "for", "if", and "while" are
indented 2 spaces as well. Blocks of code in a "switch" block are indented 4
spaces after each "case" and "default" case:
switch (array[i])
{
case PAPPL_STATE_IDLE :
do_this(i);
do_that(i);
break;
default :
do_nothing(i);
break;
}
### Spacing
A space follows each reserved word such as `if`, `while`, etc. Spaces are not
inserted between a function name and the arguments in parenthesis.
### Return Values
Parenthesis surround values returned from a function:
return (PAPPL_STATE_IDLE);
### Functions
Functions with a global scope have a lowercase prefix followed by capitalized
words, e.g., `papplDoThis`, `papplDoThat`, `papplDoSomethingElse`, etc. Private
global functions begin with a leading underscore, e.g., `_papplDoThis`,
`_papplDoThat`, etc.
Functions with a local scope are declared static with lowercase names and
underscores between words, e.g., `do_this`, `do_that`, `do_something_else`, etc.
Function names follow the following pattern:
- "papplFooCreate" to create a Foo object,
- "papplFooDelete" to destroy (free) a Foo object,
- "papplFooGetBar" to get data element Bar from object Foo,
- "papplFooIsBar" to test condition Bar for object Foo, and
- "papplFooSetBar" to set data element Bar in object Foo.
- "papplFooVerb" to take an action with object Foo.
Each function begins with a comment header describing what the function does,
the possible input limits (if any), the possible output values (if any), and
any special information needed:
//
// 'papplDoThis()' - Short description of function.
//
// Longer documentation for function with examples using a subset of
// markdown. This is a bulleted list:
//
// - One fish
// - Two fish
// - Red fish
// - Blue fish
//
// > *Note:* Special notes for developer should be markdown block quotes.
//
float // O - Inverse power value, 0.0 <= y <= 1.1
papplDoThis(float x) // I - Power value (0.0 <= x <= 1.1)
{
...
return (y);
}
Return/output values are indicated using an "O" prefix, input values are
indicated using the "I" prefix, and values that are both input and output use
the "IO" prefix for the corresponding in-line comment.
The [`codedoc` documentation generator][1] also understands the following
special text in the function description comment:
@deprecated@ - Marks the function as deprecated (not recommended
for new development and scheduled for removal)
@since version@ - Marks the function as new in the specified version.
@private@ - Marks the function as private (same as starting the
function name with an underscore)
[1]: https://www.msweet.org/codedoc
### Variables
Variables with a global scope are capitalized, e.g., `ThisVariable`,
`ThatVariable`, `ThisStateVariable`, etc. Globals *must not* be used in the
PAPPL library.
Variables with a local scope are lowercase with underscores between words,
e.g., `this_variable`, `that_variable`, etc. Any "local global" variables
shared by functions within a source file are declared static.
Each variable is declared on a separate line and is immediately followed by a
comment block describing the variable:
int ThisVariable; // The current state of this
static int that_variable; // The current state of that
### Types
All type names are lowercase with underscores between words and `_t` appended
to the end of the name, e.g., `pappl_this_type_t`, `pappl_that_type_t`, etc.
Type names start with the "pappl\_" prefix to avoid conflicts with system types.
Private type names start with an underscore, e.g., `_pappl_this_t`,
`_pappl_that_t`, etc.
Each type has a comment block immediately after the typedef:
typedef int pappl_this_type_t; // This type is for foobar options.
### Structures
All structure names are lowercase with underscores between words and `_s`
appended to the end of the name, e.g., `pappl_this_s`, `pappl_that_s`, etc.
Structure names start with the "pappl\_" prefix to avoid conflicts with system
types. Private structure names start with an underscore, e.g., `_pappl_this_s`,
`_pappl_that_s`, etc.
Each structure has a comment block immediately after the struct and each member
is documented similar to the variable naming policy above:
struct pappl_this_struct_s // This structure is for foobar options.
{
int this_member; // Current state for this
int that_member; // Current state for that
};
One common design pattern is to define a private structure with a public
typedef, for example:
// In public header
typedef struct _pappl_foo_s pappl_foo_t // Foo object
// In private header
struct _pappl_foo_s // Foo object
{
int this_member; // Current state for this
int that_member; // Current state for that
};
### Constants
All constant names are uppercase with underscores between words, e.g.,
`PAPPL_THIS_CONSTANT`, `PAPPL_THAT_CONSTANT`, etc. Constants begin with the
"PAPPL\_" prefix to avoid conflicts with system constants. Private constants
start with an underscore, e.g., `_PAPPL_THIS_CONSTANT`,
`_PAPPL_THAT_CONSTANT`, etc.
Typed enumerations should be used whenever possible to allow for type checking
by the compiler. The constants for typed enumerations must match the type name
in uppercase, for example a `pappl_foo_e` enumeration has constant names
starting with `PAPPL_FOO_`.
Comment blocks immediately follow each constant:
typedef enum pappl_tray_e // Tray enumerations
{
PAPPL_TRAY_THIS, // This tray
PAPPL_TRAY_THAT // That tray
} pappl_tray_t;
Shell Script Guidelines
-----------------------
All shell scripts in PAPPL must conform to the [POSIX shell][POSIX-SHELL]
command language and should restrict their dependence on non-POSIX utility
commands.
[POSIX-SHELL]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18
Makefile Guidelines
-------------------
The following is a guide to the [POSIX makefile-based][POSIX-MAKE] build system.
These standards have been developed over the years to allow the PAPPL to be
built on as many systems and environments as possible.
[POSIX-MAKE]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
### General Organization
The source code is organized functionally into a top-level makefile, include
file, and subdirectories each with their own makefile and dependencies files.
The ".in" files are template files for the autoconf software and are used to
generate a static version of the corresponding file.
### Makefile Documentation
Each makefile starts with the standard header containing the description
of the file, and PAPPL copyright and license notice:
#
# Makefile for ...
#
# Copyright YYYY by AUTHOR.
#
# Licensed under Apache License v2.0. See the file "LICENSE" for more
# information.
#
### Portable Makefile Construction
We use a common subset of make program syntax to ensure that the software can be
compiled "out of the box" on as many systems as possible. The following is a
list of assumptions we follow when constructing makefiles:
- Targets; we assume that the make program supports the notion of simple
targets of the form "name:" that perform tab-indented commands that follow
the target, e.g.:
target:
TAB target commands
- Dependencies; we assume that the make program supports recursive dependencies
on targets, e.g.:
target: foo bar
TAB target commands
foo: bla
TAB foo commands
bar:
TAB bar commands
bla:
TAB bla commands
- Variable Definition; we assume that the make program supports variable
definition on the command-line or in the makefile using the following form:
name=value
- Variable Substitution; we assume that the make program supports variable
substitution using the following forms:
- `$(name)`; substitutes the value of "name",
- `$(name:.old=.new)`; substitutes the value of "name" with the filename
extension ".old" changed to ".new",
- `$(MAKEFLAGS)`; substitutes the command-line options passed to the
program without the leading hyphen (-),
- `$$`; substitutes a single $ character,
- `$<`; substitutes the current source file or dependency, and
- `$@`; substitutes the current target name.
- Suffixes; we assume that the make program supports filename suffixes with
assumed dependencies, e.g.:
.SUFFIXES: .c .o
.c.o:
TAB $(CC) $(CFLAGS) -o $@ -c $<
- Include Files; we assume that the make program supports POSIX include lines,
e.g.:
include ../Makedefs
include Dependencies
- Comments; we assume that comments begin with a # character and proceed to the
end of the current line.
- Line Length; we assume that there is no practical limit to the length of
lines.
- Continuation of long lines; we assume that the `\` character may be placed at
the end of a line to concatenate two or more lines in a makefile to form a
single long line.
- Shell; we assume a POSIX-compatible shell is present on the build system.
### Standard Variables
The following variables are defined in the "Makedefs" file generated by the
autoconf software:
- `AR`; the static library archiver command,
- `ARFLAGS`; options for the static library archiver command,
- `BUILDROOT`; optional installation prefix (defaults to `DESTDIR`, `DSTROOT`,
or `RPM_BUILD_ROOT`, as defined in the environment),
- `CC`; the C compiler command,
- `CFLAGS`; options for the C compiler command,
- `CODE_SIGN`: the code signing utility,
- `CODESIGN_IDENTITY`: the code signing identity,
- `CPPFLAGS`; options for the C preprocessor,
- `CSFLAGS`; options for the code signing utility,
- `DSOFLAGS`; options for the shared library building command,
- `INSTALL`; the install command,
- `LIBPAPPL`; the name of the PAPPL library file,
- `LIBPAPPL_STATIC`; the name of the PAPPL static library file (if different
from `LIBPAPPL`),
- `LDFLAGS`; options for the linker,
- `LIBS`; libraries for all programs,
- `LN`; the ln command,
- `MKDIR`; the mkdir command,
- `OPTIM`; common compiler optimization options,
- `PAPPL_VERSION`; the full PAPPL version number,
- `PAPPL_VERSION_MAJOR`; the major number from the PAPPL version,
- `PAPPL_VERSION_MINOR`; the minor number from the PAPPL version,
- `RANLIB`; the static library indexing command,
- `RM`; the rm command,
- `RMDIR`; the rmdir command,
- `SHELL`; the sh (POSIX shell) command,
- `SYSTEM_STATUS`; the native system status UI plug-in (if any),
- `WARNINGS`; common compiler warning options,
- `bindir`; the user command installation directory,
- `datadir`; the data file installation directory,
- `datarootdir`; the root data file installation directory,
- `exec_prefix`; the executable installation prefix directory,
- `includedir`; the public header file installation directory,
- `libdir`; the library installation directory,
- `libexecdir`; the library executables installation directory,
- `localestatedir`; the local state directory,
- `mandir`; the man page installation directory,
- `oldincludedir`; a historical variable required for autoconf,
- `prefix`; the installation prefix directory,
- `sbindir`; the administrative command installation directory,
- `sharedstatedir`; the shared state directory,
- `srcdir`; the source directory,
- `sysconfdir`; the system configuration directory, and
- `top_srcdir`; the top-level source directory.
### Standard Targets
The following standard targets are defined in each makefile:
- `all`; creates all target programs, libraries, and documentation files,
- `clean`; removes all target programs libraries, documentation files, and
object files,
- `depend`; generates automatic dependencies for any C source files (also
see "DEPENDENCIES"),
- `distclean`; removes autoconf-generated files in addition to those removed by
the "clean" target,
- `install`; installs all distribution files in their corresponding locations
(also see "INSTALL/UNINSTALL SUPPORT"),
- `test`; performs all unit and combined tests, and
- `uninstall`; removes all distribution files from their corresponding locations
(also see "INSTALL/UNINSTALL SUPPORT").
### Object Files
Object files (the result of compiling a C source file) have the extension ".o".
### Programs
Program files are the result of linking object files and libraries together to
form an executable file. A typical program target looks like:
program: $(OBJS)
TAB echo Linking $@...
TAB $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
TAB $(CODE_SIGN) $(CSFLAGS) -i org.msweet.pappl.$@ $@
### Static Libraries
Static libraries have a prefix of "lib" and the extension ".a". A typical
static library target looks like:
libname.a: $(OBJECTS)
TAB echo Creating $@...
TAB $(RM) $@
TAB $(AR) $(ARFLAGS) $@ $(OBJECTS)
TAB $(RANLIB) $@
### Shared Libraries
Shared libraries have a prefix of "lib" and the extension ".dylib" or ".so"
depending on the operating system. A typical shared library is composed of
several targets that look like:
libname.so.1: $(OBJECTS)
TAB echo $(CC) $(DSOFLAGS) -o $@ ...
TAB $(CC) $(DSOFLAGS) -o $@ $(OBJECTS)
TAB $(RM) `basename $@ .1`
TAB $(LN) $@ `basename $@ .1`
libname.1.dylib: $(OBJECTS)
TAB echo $(CC) $(DSOFLAGS) -o $@ ...
TAB $(CC) $(DSOFLAGS) -o $@ \
TAB TAB -install_name $(libdir)/$@ \
TAB TAB -current_version 1.0.0 \
TAB TAB -compatibility_version 1 \
TAB TAB $(OBJECTS) $(LIBS)
TAB $(CODE_SIGN) $(CSFLAGS) -i org.msweet.pappl.`basename $@ .1.dylib` $@
TAB $(RM) `basename $@ .1.dylib`.dylib
TAB $(LN) $@ `basename $@ .1.dylib`.dylib
### Dependencies
Static dependencies are expressed in each makefile following the target, for
example:
foo: bar
Static dependencies are only used when it is not possible to automatically
generate them. Automatic dependencies are stored in a file named
"Dependencies" and included at the end of the makefile. The following "depend"
target rule is used to create the automatic dependencies:
depend:
TAB $(CC) -MM $(CFLAGS) $(OBJS:.o=.c) | \
TAB TAB sed -e '1,$$s/ \/usr\/include\/[^ ]*//g' \
TAB TAB -e '1,$$s/ \/usr\/local\/include\/[^ ]*//g' >Dependencies
### Install/Uninstall Support
All makefiles contains install and uninstall rules which install or remove the
corresponding software. These rules must use the $(BUILDROOT) variable as a
prefix to any installation directory so that PAPPL can be installed in a
temporary location for packaging by programs like `rpmbuild`.
The `$(RANLIB)` command must be run on any static libraries after installation
since the symbol table is invalidated when the library is copied on some
platforms.
|