github.com/atrn/dcc@v0.0.0-20220806184050-4470d2553272/README.md (about) 1 # dcc - a dependency-driven C/C++ compiler driver 2 3 `dcc` is a C/C++ compiler driver that that adds, parallel, 4 _dependency-based_ building to an underlying C or C++ compiler. `dcc` 5 adds many of the build-related functions of build tools such as `make` 6 to the compiler itself and allows build systems to _not_ perform that 7 work. 8 9 `dcc` uses compiler generated dependency information, along with 10 hard-coded `make`-like rules, to determine if compilation or linking 11 is actually required. This allows `dcc` to avoid running commands if 12 they are not required - `dcc` only re-compiles, or re-links, when an 13 output file is out-of-date with respect to its inputs. Inputs include 14 not only the files used in the compilation, both sources and dependent 15 header files, but also the compilation options. 16 17 Unlike building with tools such as make users don't have to do 18 anything to get this behaviour. They can use `dcc` as if it were `cc` 19 and obtain automatic, parallel, dependency-based builds for _free_. 20 21 Moving dependency checking into the compiler driver simplifies 22 build systems. Instead of using a build tool to do the work of 23 correctly, and efficiently, building the program or library using 24 knowledge of the language dependency model, we have the language's 25 compiler take care of that doing that. 26 27 `dcc` adds a number of features to the compiler-driver model to 28 simplify the development process. For instance, `dcc` can uses files 29 to store compiler options which are used as dependencies in builds 30 allowing automatic re-compilation when build options change. 31 32 ## Supported Compilers and Platforms 33 34 `dcc` has been used with a number of compilers and target OSes. `dcc` 35 can be used on UNIX-like OSes, e.g. macOS, FreeBSD, common Linux-based 36 OS distributions, and on Microsoft Windows. 37 38 `dcc` supports what it calls _gcc style compilers_, `gcc`, `clang` and 39 Intel's `icc`, and on Windows Microsoft's `cl.exe` can be used. 40 41 ## Building and Installation 42 43 `dcc` is written in Go and obviously requires Go installed to build 44 (see [golang.org](http://golang.org/)). `dcc` uses only standard Go 45 packages and is _trivially_ built using the `go build` command. 46 47 To install dcc to your Go `$GOBIN` use `go install` otherwise 48 simply copy the `dcc` executable to the desired _bin_ directory. 49 50 ## Usage 51 52 `dcc` usage is similar to that of `cc(1)`, `gcc(1)` and similar 53 compiler drivers, 54 55 ``` 56 $ dcc <option...> <pathname...> 57 ``` 58 59 Like `cc` et al `dcc` compiles source files to object files using the 60 options passed on the command line. If a `-c` is passed `dcc` stops 61 following compilation but if no `-c` option is supplied `dcc` runs the 62 linker to form an executable from the object files. 63 64 However, unlike `cc` et al `dcc` automatically generates and uses 65 dependency information and will only compile or link if an output 66 file needs to be re-created. This is entirely transparent to the 67 end-user. The effect being that re-compilation is far faster when 68 files are already up to date. 69 70 `dcc` can be used as a mostly _drop in_ replacement for `cc/c++(1)` in 71 existing build systems. Doing so adds additional dependency checking 72 to builds. There is a difference in behaviour with respect to existing 73 compiler drivers that may affect results, `dcc` does *not* remove 74 object files when no `-c` switch is used. Most build systems however 75 invoke the compiler for each source file passing `-c`. 76 77 ### Differences to cc 78 79 Although `dcc` is similar in usage to `cc(1)1 et al, enough so to 80 permit it to be used directly in its place, `dcc` does behave 81 differently in certain situations. 82 83 #### object files without `-c` 84 85 Normally, without a `-c` option, `cc` compiles the source files, 86 generating object files, and runs the linker to link those object 87 files into an executable. It then *removes* the object files. `dcc` 88 does not remove the files. 89 90 91 ## What dcc does 92 93 `dcc` _wraps_ the underlying compiler driver and passes it options to 94 have it output dependency information. `dcc` automatically determines 95 the names of the files to store this information and reads them when 96 re-compiling a file to obtain the dependencies. 97 98 When re-compiling a file `dcc` performs `make`-like dependency 99 checking to determine if compilation is actually required. If not, 100 `dcc` does nothing and exits as if it had compiled the file (note, 101 file modification times are *not* altered). Otherwise `dcc` runs the 102 compiler and lets it generate its output. Dependency generation and 103 checking is entirely transparent to the end-user and, `dcc` implements 104 additional checks on the libraries and other files used in the build. 105 106 ## Command line options 107 108 The `dcc` command line consists of options for the underling compiler, 109 a number of `dcc`-specific options and filenames to be processed. 110 111 Options to the compiler are passed through unalterted. `dcc` does 112 recognize a number of options which control its behaviour or supply 113 dependency information (libraries). 114 115 ### dcc-specific options 116 117 These options apply to `dcc` itself and are not passed on to the 118 compiler, 119 120 - \-\-help 121 Get help. 122 - \-\-version 123 Output the dcc version number and exit. 124 - \-\-debug 125 Enable `dcc` debug output. 126 - \-\-cpp 127 Compile source as C++ rather than C. 128 - \-\-force 129 Rebuild everything, ignore dependencies. 130 - \-\-quiet 131 Don't output the commands being executed. 132 - \-\-exe _path_ 133 Compile and link an executable called _path_. 134 - \-\-dll _path_ 135 Compile and create a shared library called _path_. 136 - \-\-lib _path_ 137 Compile and create a static library, _path_. 138 - \-j_number_ 139 Use _number_ parallel compilations. 140 - \-objdir _directory_ 141 Create object files in _directory_ (passed to the 142 underlying compiler but also used to defne where dcc 143 writes files). 144 - \-\-write\-compile\-commands 145 Output a `compile_commands.json` file to the same directory 146 where object files are written. 147 - \-\-append\-compile\-commands 148 Append compilation commands to the `compile_commands.json`file in the 149 same directory. 150 151 ### --exe, --dll, --plugin, --lib 152 153 `cc`-style compiler drivers traditionally worked in two modes. They 154 either compiled source files to object files or did that and linked 155 the object files to form an executable (and removed the object files). 156 Shared libraries added options to have the linker create a shared 157 library but the overall structure is the same as for an executable. 158 159 `dcc` has options that make these uses more explicit and adds the 160 feature of having the compiler driver generate a static library to 161 round out the various use cases. 162 163 The `dcc`-specific `--exe`, `--dll`, `--plugin` and `--lib` options 164 are used to tell `dcc` what is being built and the name of the output 165 file. 166 167 The `--exe` option means "build an executable", `--dll` means "build a 168 dynamic, or shared, library", `--plugin` means build a shared library 169 to be used as a plugin (see below) and `--lib` means "build a static 170 library". 171 172 #### Plugins vs DLLs 173 174 Some platfoms, e.g. macOS, make a distiction between dynamic libraries 175 and object files intended to be used as plugins, what macOS calls 176 _bundles_. To accomodate this `dcc` uses the idea of _plugin_ to 177 refer to libraries meant to be loaded as plugins and _dll_ to mean 178 dynamic libraries. On other platforms, Windows and ELF-based systems 179 such as Linux and FreeBSD, plugins **are** DLLs. 180 181 ### Language selection 182 183 `dcc` determines the language being compiled, C or C++, using a number 184 of rules and uses the appropriate underlying C or C++ compiler. C++ is 185 selected if, 186 187 - the `dcc` program name ends with `++`, e.g `dc++` 188 - an input file uses a C++ extension `.cc`, `.cpp`, `.cxx` 189 - the `--cpp` switch was supplied 190 191 The choice of lanugage affects the choice of _options files_ (see 192 below). 193 194 ## Dependency Files 195 196 `dcc` uses dependency information generated by the compiler itself 197 and information inferred from the filenames and system environment. 198 199 With gcc-style compilers `dcc` uses the `-MF` and `-MD` options to 200 have the compiler output make-format dependencies to a file which 201 `dcc` reads on the next run. With Microsoft's `cl.exe` the compiler's 202 `/showIncludes` flag is used to output the names of included files 203 which are then _scraped_ and used to create `.d` files used by 204 the next compilation. 205 206 Dependency files are stored in a `.dcc.d` directory that resides in 207 the same directory as the object file being created. The `DCCDEPS` 208 environment variable can be set to use a name other than `.dcc.d` for 209 this directory. 210 211 ## Options Files 212 213 `dcc` can read compiler and linker options stored in files called 214 _options files_. Options files are simple text files that contain the 215 options that would normally be passed on the command line. 216 217 Unlike passing options on the the comand line options files allow 218 options to be split across multiple lines and support '#'-based _line_ 219 comments. Options files are also treated as dependencies and when 220 changed, which presumably means the options within the file have been 221 change, cause recompilation. This helps ensure all files are built in 222 the same way. 223 224 The names adopted for options files are derived from the typical macro 225 names used with make(1) for the particular options, 226 227 - `CFLAGS` 228 C compiler options. 229 - `CXXFLAGS` 230 C++ compiler options. 231 - `LDFLAGS` 232 Linker options. 233 - `LIBS` 234 Libraries and library paths. 235 236 ### Locating options files 237 238 Option files are looked for by searching the directory hierarchy 239 towards the root for a file with the particular name, e.g CXXFLAGS. 240 241 Files are searched for either in the specific directory or within a 242 `$DCCDIR` directory within that directory. `$DCCDIR` defaults to `.dcc` 243 but can be override by the environment variable so we call it `$DCCDIR` 244 even though it is rarely changed from the default `.dcc`. 245 246 Looking for the files in a `$DCCDIR` directory is a quick hack to get 247 the files out of the current directory and perhaps in the future some 248 other method may be adopted (ha ha). 249 250 ### Platform-specific option files 251 252 `dcc` uses a Go-style method to support platform-specific options. 253 When searching for an options file `dcc` first searches for platform 254 and architecture specific variants of the file. `dcc` forms a file 255 name extension using names for for the host's architecture and 256 operating system and appends that extension to the filename. If a file 257 with that name exists it is used in place of the unadorned filename. 258 259 E.g. when searching for the `LIBS` file on a 64-bit FreeBSD host 260 the following files will be searched for in order, 261 262 1. `$DCCDIR/LIBS.freebsd_amd64` 263 2. `$DCCDIR/LIBS.freebsd` 264 3. `$DCCDIR/LIBS` 265 266 ### Libraries 267 268 The `LIBS` options file is used to define the libraries and library 269 directories used when linking programs and DLLs. 270 271 The `LIBS` options file behaves in a similar manner to the compiler 272 options and executables depend on the file and relink when it changes. 273 274 Lines starting with `-l` (elle) and `-L` (capital-elle) are special. 275 Any library name starting with `-l` has the `-l` removed allowing 276 users to use UNIX linker-style naming for familarity. _libraries_ with 277 names starting with `-L` are the names of of library directories. 278 279 280 ### Option File Directives 281 282 #### Inclusion 283 284 Options files may include other files using the `!include` directory 285 286 #### Inheritence 287 288 The `!inherit` directive is similar to include but _inherits_ 289 options by automatically searching for a file with the same 290 name as the one in which the directive occurs. The search for 291 the file starts in the directory above that which contains 292 the file. 293 294 With no arguments `!inherit` directive for a file with the same name 295 as the file that includes the directive in a higher level directory. 296 297 With argument `!inherit` searches for a file with that name, or 298 the platform-specific version of it. 299 300 #### Conditionals 301 302 Options files may include conditional directives to conditonally 303 define compiler and linker options, and for "LIBS" files, libraries. 304 305 As with `!include` conditional directives mimic the C pre-processor's 306 `#ifdef` and `#ifndef` but use environment variables in the place of 307 macros as with the C/C++ pre-processor. 308 309 Conditionals **must** start in the first column. 310 311 #### Raisng Errors 312 313 The `!error` directive allows options files to purposefully raise 314 errors. `!error` is useful with conditional sections to raise 315 raise errors if required environment variables are not defined. 316 317 Any text following the `!error` directive is reported as the error to 318 the user. 319 320 #### Options file directives summary 321 322 - `!include` _filename_ 323 - `!inherit` [_filename_] 324 - `!ifdef` _envvar_ 325 - `!ifndef` _envvar_ 326 - `!else` 327 - `!endif` 328 - `!error` _[_ _text_ _]_ 329 330 ## Implementation 331 332 `dcc` is written in Go and uses only standard packages in its 333 implementation. `dcc` should build in any supported Go environment and 334 be trivially cross-buildable. 335 336 `dcc` itself supports the various Linux distribtions, the BSD's, MacOS 337 and mostly likely other UNIX systems that use gcc, clang or 338 similar. 339 340 `dcc` has not really been used _in anger_ and I expect many changes if 341 it is used more extensively. There are many areas where I've just 342 hacked things in, e.g. frameworks on MacOS, which would be better 343 expressed in a more structured manner, i.e. more comprehensive 344 abstracted interfaces to the compiler and other tools to remove the 345 platform-specific conditiona. 346 347 The code has lots of comments. Many of them correct! The commenting 348 style is the result of using Visual Studio Code and its Go package's 349 default configuration which _golints_ your code producing lots of 350 annoying warnings about naming, comment style and so on. Rather than 351 disabling the tool like a sensible person I appeased it and wrote the 352 things it told me to write. That stopped it drawing little squiggles 353 and annoying little icons everywhere. 354 355 ## License 356 357 `dcc` is released under the GPL, version 2. If you advance dcc, and 358 distribute, you must share the advancements. The reasoning being that 359 a utility such as dcc is infrastructure and we should share, and 360 advance, infrastructure so we all get ahead. 361 362 As per convention the license text is in the file LICENSE. 363 364 365 ## Example 366 367 Using `dcc` in a project can vastly simplfy its build system. Instead 368 of implementing build rules via `make` or generating them via `cmake` 369 or autotools you can just use `dcc`. It takes care of the building 370 part. 371 372 A complete development `Makefile` for a simple program, with all 373 source files in one directory, can be as small as: 374 375 .PHONY: program clean 376 377 program: 378 dcc $(CFLAGS) *.c -o $@ 379 380 clean: 381 rm -f program *.o 382 rm -rf .dcc.d 383 384 The `program` target builds everything using `dcc`. It is marked 385 marked _phony_ as we rely on `dcc` to take care of things. 386 387 ## Environment Variables 388 389 - CC (or $CCFILE) 390 Name of the C compiler. 391 - CXX (or $CXXFILE) 392 Name of the C++ compiler. 393 - CCFILE 394 Name of the file that names the C compiler. 395 - CXXFILE 396 Name of the file that names the C++ compiler. 397 - CFLAGSFILE 398 Name of the C options file. 399 - CXXFLAGSFILE 400 Name of the C++ options files. 401 - LDFLAGSFILE 402 Name of the linker options file. 403 - LIBSFILE 404 Name of the linker _LIBS_ file. 405 - DCCDIR 406 Name of the `.dcc` directory. 407 - DEPSDIR 408 Name of the `.dcc.d` dependency file directory. 409 - OBJDIR 410 Name of the object file directory. 411 - NUMJOBS 412 Number of compilations to run in parallel. 413 414 415 ## Changelog 416 417 ### version 0.0.5 418 419 Initial support for Microsoft compiler on Windows. 420 421 ### version 0.0.4 422 423 Use '!' as the options file directive prefix in place of '#' 424 425 Allow `!inherit` directives to define the, base, filename of 426 the file to be inherited 427 428 Allow environment variables to be used in conditionals in 429 options files. 430 431 ### version 0.0.3 432 433 Add --plugin option and support for linking _bundle_ files on macOS 434 435 ### version 0.0.2 436 437 Added C-preprocessor style conditional and #error directives to 438 optons files. 439 440 ### version 0.0.1 441 442 Initial _alpha_ version.