| 1 | Notes on Coding Standards/Requirements for OpenAFS Source |
| 2 | --------------------------------------------------------- |
| 3 | |
| 4 | We have an official style. Please use it. If you have gnu indent 2.2.9 or |
| 5 | later you can reformat for this style with the following option: |
| 6 | |
| 7 | -npro -nbad -bap -nbc -bbo -br -ce -cdw -brs -ncdb -cp1 -ncs -di2 -ndj -nfc1 |
| 8 | -nfca -i4 -lp -npcs -nprs -psl -sc -nsob -ts8 |
| 9 | |
| 10 | Do not use $< for non-pattern rules in any cross-platform dir as it |
| 11 | requires a reasonable make that is not available on all systems. |
| 12 | |
| 13 | Do not have build rules that build multiple targets. Make doesn't seem able |
| 14 | to handle this, and it interferes with -j builds. (In particular, build the |
| 15 | rxgen targets individually and not using the flags for building all the files |
| 16 | in one shot.) |
| 17 | |
| 18 | Try to test builds using gmake -j # MAKE="gmake -j #", it seems like a good |
| 19 | way to find missing or order-dependent dependency rules. (Is there a better |
| 20 | way to do this?) |
| 21 | |
| 22 | -- Prototyping and Style -- |
| 23 | Prototypes for all source files in a given dir DDD should be placed |
| 24 | in the file DDD/DDD_prototypes.h. All externally used (either API |
| 25 | or used by other source files) routines and variables should be |
| 26 | prototyped in this file. |
| 27 | |
| 28 | The prototypes should be a full prototype, with argument and return |
| 29 | types. (Should not generate a warning with gcc -Wstrict-prototypes.) |
| 30 | |
| 31 | Format of the prototype files should look like: |
| 32 | |
| 33 | Standard Copyright Notice |
| 34 | |
| 35 | #ifndef AFS_SRC_DDD_PROTO_H |
| 36 | #define AFS_SRC_DDD_PROTO_H |
| 37 | |
| 38 | /* filename.c */ |
| 39 | prototypes |
| 40 | |
| 41 | /* filename.c */ |
| 42 | prototypes |
| 43 | |
| 44 | #endif /* AFS_SRC_DDD_PROTO_H */ |
| 45 | |
| 46 | In most of the existing prototypes, the define is DDD_PROTOTYPES_H, which is |
| 47 | probably ok as well. |
| 48 | |
| 49 | The declaration of the routines should be done in ANSI style. If at some |
| 50 | later date, it is determined that prototypes don't work on some platform |
| 51 | properly, we can use ansi2knr during the compile. |
| 52 | |
| 53 | rettype |
| 54 | routine(argtype arg) |
| 55 | { |
| 56 | |
| 57 | } |
| 58 | |
| 59 | All routines should have a return type specified, void if nothing returned, |
| 60 | and should have (void) if no arguments are taken. |
| 61 | |
| 62 | Header files should not contain macros or other definitions unless they |
| 63 | are used across multiple source files. |
| 64 | |
| 65 | All routines should be declared static if they are not used outside that |
| 66 | source file. |
| 67 | |
| 68 | Compiles on gcc-using machines should strive to handle using |
| 69 | -Wstrict-prototypes -Werror. (this may take a while) |
| 70 | |
| 71 | Routines shall be defined in source prior to use if possible, and |
| 72 | prototyped in block at top of file if static. |
| 73 | |
| 74 | API documentation in the code should be done using Qt-style Doxygen |
| 75 | comments. |
| 76 | |
| 77 | If you make a routine or variable static, be sure and remove it from |
| 78 | the AIX .exp files. |
| 79 | |
| 80 | Suggested compiler flags: |
| 81 | gcc: -Wall -Wstrict-prototypes |
| 82 | Solaris Workshop CC: -fd -v |
| 83 | (You might not want the -fd, it isn't really useful, just complains about the |
| 84 | K&R style functions, but -v gives useful info.) |
| 85 | |
| 86 | Multiple line comment blocks should begin with only /* on one line and end with |
| 87 | only */ on one line. |
| 88 | |
| 89 | Example: |
| 90 | |
| 91 | /* |
| 92 | * Multiple line comment blocks should be formatted |
| 93 | * like this example. |
| 94 | */ |
| 95 | |
| 96 | Do not use braces on one-line if and loop statements. |
| 97 | |
| 98 | Use: |
| 99 | |
| 100 | if (some_condition) |
| 101 | do_some_action(); |
| 102 | else |
| 103 | do_something_else(); |
| 104 | |
| 105 | while (some_condition) |
| 106 | do_something(); |
| 107 | |
| 108 | Instead of: |
| 109 | |
| 110 | if (some_condition) { |
| 111 | do_some_action(); |
| 112 | } |
| 113 | |
| 114 | while (some_condition) { |
| 115 | do_something(); |
| 116 | } |
| 117 | |
| 118 | |
| 119 | Dependencies required to build OpenAFS from source |
| 120 | -------------------------------------------------- |
| 121 | The following packages are required to build all of the OpenAFS code |
| 122 | from source on various operating systems: |
| 123 | |
| 124 | On Debian: |
| 125 | - autoconf, automake, bison, comerr-dev, cpio, flex, libkrb5-dev, |
| 126 | libncurses5-dev, libpam0g-dev, libxml2-utils, perl, pkg-config; |
| 127 | - libfuse-dev (for the FUSE-based user-mode client); |
| 128 | - dblatex, docbook-xsl, doxygen, xsltproc (for documentation); |
| 129 | - debhelper, hardening-wrapper, dkms (to build the Debian packages) |
| 130 | |
| 131 | On FreeBSD: |
| 132 | - autoconf, automake, libtool; |
| 133 | - fusefs-libs, pkgconf (for the FUSE-based user-mode client); |
| 134 | - perl, dblatex, docbook-xsl, libxslt, python, ruby, zip (for documentation) |
| 135 | |
| 136 | In addition, FreeBSD systems require kernel sources and a configured kernel |
| 137 | build directory (see section "FreeBSD Notes" in the README file). |
| 138 | |
| 139 | GIT Usage |
| 140 | ========= |
| 141 | |
| 142 | *WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING* |
| 143 | The Git tree may not always have code which can currently be built. |
| 144 | While every effort is made to keep the head of the tree buildable, |
| 145 | you may at any time find yourself between commits and hence have a tree |
| 146 | which does not build, or worse, causes more serious problems! |
| 147 | |
| 148 | Do not use the Git tree unless you know what you're doing. |
| 149 | |
| 150 | Git checkouts do not include files generated by autoconf. You can |
| 151 | run regen.sh (at the top level) to create these files. You will need |
| 152 | to have autoconf and automake installed on your system. |
| 153 | |
| 154 | Summary |
| 155 | ------- |
| 156 | |
| 157 | Browse: http://git.openafs.org/ |
| 158 | Clone: git clone git://git.openafs.org/openafs.git |
| 159 | |
| 160 | Step-by-step |
| 161 | ------------ |
| 162 | |
| 163 | 1. Obtain the Git software. If you are using a system with a standard |
| 164 | software repository, Git may already be available as a package named |
| 165 | something like git or git-core. Otherwise, go to http://git-scm.com/ |
| 166 | |
| 167 | 2. Run the command: |
| 168 | |
| 169 | % git clone git://git.openafs.org/openafs.git |
| 170 | |
| 171 | This will download the full repository and leave a checked-out tree in |
| 172 | a subdirectory of the current directory named openafs. The repository |
| 173 | itself is in the .git subdirectory of that directory. |
| 174 | |
| 175 | WARNING: The repository is approximately 60MiB currently and will only |
| 176 | grow, so it may take some time to download the first time over a slow |
| 177 | network connection. |
| 178 | |
| 179 | 3. Generate the additional required files: |
| 180 | |
| 181 | % cd openafs |
| 182 | % ./regen.sh |
| 183 | |
| 184 | The current development series is in the branch named master. The stable |
| 185 | releases are on separate branches named something like |
| 186 | openafs-stable_<version> with a separate branch for each major stable |
| 187 | release series. Use git branch -a to see a full list of branches. |
| 188 | |
| 189 | OpenAFS uses the Gerrit code review system to review and merge all changes |
| 190 | to OpenAFS. More details are at: |
| 191 | |
| 192 | http://wiki.openafs.org/GitDevelopers/ |
| 193 | |
| 194 | including more detailed Git instructions. |
| 195 | |
| 196 | It's by far preferred to use Gerrit to submit code changes, but if you |
| 197 | can't for whatever reason, you can instead open a bug and submit a patch |
| 198 | that way. Do this by sending mail to openafs-bugs@openafs.org with the |
| 199 | patch attached. But please use Gerrit if you can; patches sent in as bugs |
| 200 | will have to be forwarded to Gerrit by someone else, and it's easier for |
| 201 | everyone if you can enter them into Gerrit yourself. |
| 202 | |
| 203 | Backport policy |
| 204 | ------------ |
| 205 | All patches should land on master first, unless the patch fixes a bug |
| 206 | that only exists in the stable branch. |
| 207 | |
| 208 | Once a patch has been accepted into master, anyone can propose |
| 209 | backports to stable branches. |
| 210 | |
| 211 | When cherry-picking a commit from another branch, please append a |
| 212 | "cherry picked from" section in your commit message. You'll also need |
| 213 | a separate Change-ID for Gerrit to recognize this as a separate |
| 214 | change. One workflow to do this: |
| 215 | |
| 216 | 1) Use "git cherry-pick -ex" to pick your commits onto another branch. |
| 217 | The -x option will append the appropriate "cherry picked from" |
| 218 | message, and the -e option will open your editor for you to edit |
| 219 | the commit message. |
| 220 | 2) In your editor, delete the existing Change-ID line. Save and quit. |
| 221 | 3) Run "git commit --amend", saving and quitting again. Git will run |
| 222 | the commit hook and generate a new Change-ID for Gerrit. |
| 223 | |
| 224 | Warnings |
| 225 | ======== |
| 226 | |
| 227 | OpenAFS Warning detection |
| 228 | ------------------------- |
| 229 | |
| 230 | There's been a concerted effort over the last few years, by many developers, |
| 231 | to reduce the number of warnings in the OpenAFS tree. In an attempt to |
| 232 | prevent warnings from creeping back in, we now have the ability to break the |
| 233 | build when new warnings appear. |
| 234 | |
| 235 | This is only available for systems with gcc 4.2 or later or clang 3.2 or |
| 236 | later, and is disabled unless the --enable-checking option is supplied to |
| 237 | configure. Because we can't remove all of the warnings, we permit file by |
| 238 | file (and warning by warning) disabling of specific warnings. The |
| 239 | --enable-checking=all option prevents |
| 240 | this, and errors for any file containing a warning. |
| 241 | |
| 242 | Disabling warnings |
| 243 | ------------------ |
| 244 | |
| 245 | If warnings are unavoidable in a particular part of the build, they may be |
| 246 | disabled in an number of ways. |
| 247 | |
| 248 | You can disable a single warning type in a particular file by using GCC |
| 249 | pragmas. If a warning can be disabled with a pragma, then the switch to use |
| 250 | will be listed in the error message you receive from the compiler. Pragmas |
| 251 | should be wrapped in IGNORE_SOME_GCC_WARNINGS, so that they aren't used |
| 252 | with non-gcc compilers, and can be disabled if desired. For example: |
| 253 | #ifdef IGNORE_SOME_GCC_WARNINGS |
| 254 | # pragma GCC diagnostic warning "-Wold-style-definition" |
| 255 | #endif |
| 256 | |
| 257 | It would appear that when built with -Werror, the llvm clang compiler will |
| 258 | still upgrade warnings that are suppresed in this way to errors. In this case, |
| 259 | the fix is to mark that warning as ignored, but only for clang. For example: |
| 260 | #ifdef IGNORE_SOME_GCC_WARNINGS |
| 261 | # ifdef __clang__ |
| 262 | # pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
| 263 | # else |
| 264 | # pragma GCC diagnostic warning "-Wdeprecated-declarations" |
| 265 | # endif |
| 266 | #endif |
| 267 | |
| 268 | If a pragma isn't available for your particular warning, you will need to |
| 269 | disable all warnings for the file in question. You can do this by supplying |
| 270 | the autoconf macro @CFLAGS_NOERROR@ in the build options for the file. For |
| 271 | example: |
| 272 | lex.yy.o : lex.yy.c y.tab.c |
| 273 | ${CC} -c ${CFLAGS} @CFLAGS_NOERROR@ lex.yy.c |
| 274 | |
| 275 | If you add a new warning inhibition, please also add it to the list below. |
| 276 | |
| 277 | Inhibited warnings |
| 278 | ------------------ |
| 279 | |
| 280 | afs/afs_syscall.c : old-style |
| 281 | : strict-proto |
| 282 | : all (ukernel) : syscall pointer issues |
| 283 | afsd/afsd_kernel.c : deprecated : daemon() marked as deprecated on Darwin |
| 284 | auth/ktc.c : all (ukernel) : call_syscall doesn't have a prototype |
| 285 | bozo/bosserver.c : deprecated : daemon() marked as deprecated on Darwin |
| 286 | bucoord/ubik_db_if.c : strict-proto : Ubik_Call |
| 287 | bucoord/commands.c : all : Ubik_Call |
| 288 | : signed vs unsigned for dates |
| 289 | butc/tcudbprocs.c : all : ubik_Call |
| 290 | external/heimdal/hcrypto/validate.c: all: statement with empty body |
| 291 | kauth/admin_tools.c : strict-proto : ubik_Call |
| 292 | kauth/authclient.c : strict-proto : ubik_Call nonsense |
| 293 | libadmin/kas/afs_kasAdmin.c: strict-proto : ubik_Call nonsense |
| 294 | libadmin/samples/rxstat_query_peer.c : all : util_RPCStatsStateGet types |
| 295 | libadmin/samples/rxstat_query_process.c : all : util_RPCStatsStateGet types |
| 296 | libadmin/test/client.c : all : util_RPCStatsStateGet types |
| 297 | ubik/ubikclient.c : strict-protos : ubik_Call |
| 298 | volser/vol-dump.c : format : afs_sfsize_t |
| 299 | |