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.