# Installing C-Reduce

## Using a Package Manager

Before compiling C-Reduce yourself, you might want to see if your OS
comes with a precompiled package for C-Reduce.  Ubuntu, Debian, Gentoo,
FreeBSD and Mac OS X (Homebrew) all do.  For example, on OS X:

```
$ brew install creduce
```

## From Source

### Prereqs

C-Reduce is written in Perl, C++, and C.  To compile and run C-Reduce,
you will need a development environment that supports these languages.
C-Reduce's build system requires CMake or GNU Make (*not* BSD Make).

Beyond the basic compile/build tools, C-Reduce depends on a set of
third-party software packages, including LLVM.

On Ubuntu or Mint, the prerequisites other than LLVM can be installed
like this:

```
sudo apt-get install \
  libexporter-lite-perl libfile-which-perl libgetopt-tabular-perl \
  libregexp-common-perl flex build-essential zlib1g-dev
```

On OS X, [Perlbrew](http://perlbrew.pl/) provides an easy and flexible
way to get Perl and Perl modules installed

On FreeBSD 12.1, the prerequisites can be installed like this:

```
sudo pkg install \
  llvm90 flex p5-Exporter-Lite p5-File-Which p5-Getopt-Tabular p5-Regexp-Common
```

Otherwise, install these packages either manually or using the package
manager:

* [Flex](http://flex.sourceforge.net/)

* [LLVM/Clang 9.0.0](http://llvm.org/releases/download.html#9.0.0)
  (No need to compile it: the appropriate "pre-built binaries" package is
  all you need.  If you use one of the binary packages, you may need
  to install additional packages that the binary package depends on.
  For example, the "Ubuntu 18.04" binary package depends on "libtinfo5"
  and "libxml2".  You may need to install these, e.g.:
  `sudo apt-get install libtinfo-dev libxml2-dev`.)

* Perl modules:
  - Exporter::Lite
  - File::Which
  - Getopt::Tabular
  - Regexp::Common
  - For example, (perhaps as root) `cpan -i Exporter::Lite File::Which Getopt::Tabular Regexp::Common`

* [zlib](http://www.zlib.net/)

### Optional Prereqs

`Term::ReadKey` is optional; C-Reduce will use it if it is installed.

On Ubuntu:

```
sudo apt-get install libterm-readkey-perl
```

On OS X (with Homebrew + Perlbrew installed):

```
cpan -i Term::ReadKey
```

On FreeBSD 12.1:

```
sudo pkg install p5-Term-ReadKey
```

Otherwise, install the packages either manually or using the package
manager.

## Building and installing C-Reduce

You can configure, build, and install C-Reduce with the provided
`configure` script or with CMake.

### Preface: If in Doubt, Compile With clang++

If you encounter weird C++ link-time errors while trying to compile
C-Reduce (in particular, while compiling its internal `clang_delta`
tool), please try compiling with clang++.

We have encountered link-time problems while trying to compile
C-Reduce with GCC 5.* and the precompiled LLVM binaries available
from <http://llvm.org/releases/download.html>.  If you encounter
similar problems, we strongly suggest that you use Clang instead of
GCC to compile C-Reduce and its internal tools.

If you are curious, for some discussion of this issue, see:
<https://github.com/csmith-project/creduce/issues/101>
<https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html>

### The `configure` Way

From either the source directory or a build directory:

```
[source-path/]configure [options]
make
make install
```

The `configure` script was generated by GNU Autoconf, and therefore
accepts the usual options for naming the installation directories,
choosing the compilers you want to use, and so on.  `configure --help`
summarizes the command-line options.

If LLVM/Clang is not in your search path, you can tell the `configure`
script where to find LLVM/Clang:

```
# Use the LLVM/Clang tree rooted at /opt/llvm
configure --with-llvm=/opt/llvm
```

If you choose to build LLVM and Clang yourself, *and* if you choose to
keep your LLVM and Clang build trees separate, you can tell the
`configure` script where to find your separate Clang tree:

```
# Use separate LLVM and Clang build trees, /work/my-{llvm,clang}
configure --with-llvm=/work/my-llvm --with-clang=/work/my-clang
```

You do *not* need to specify `--with-clang` if you build Clang within
your LLVM tree.  Also note that you must actually *build* LLVM and
Clang before building C-Reduce.

Note that assertions are enabled by default (which is probably what
you want).  To disable assertions:

```
configure --disable-trans-assert
```

The generated Makefiles require GNU Make.  BSD Make will not work.
If you see weird make-time errors, please check that you are using
GNU Make.

### The CMake Way

From either the source directory or a build directory:

```
cmake [source-dir] [options]
make
make install
```

If LLVM/Clang is not in your search path, you can tell CMake where to
find LLVM/Clang:

```
# Use the LLVM/Clang tree rooted at /opt/llvm
cmake [source-dir] -DCMAKE_PREFIX_PATH=/opt/llvm
```

Alternatively, if you choose to build LLVM and Clang yourself, you can
set the `LLVM_DIR` and/or `Clang_DIR` variables to paths where CMake can
find the `LLVMConfig.cmake` and/or `ClangConfig.cmake` files.  The
value of `LLVM_DIR` is usually `./lib/cmake/llvm`, relative to your LLVM
build or install directory.  Similarly, the value of `Clang_DIR` is
usually `./lib/cmake/clang`, relative to your Clang build or install
directory.  For example:

```
# Use separate LLVM and Clang build trees, /work/my-{llvm,clang}
cmake [source-dir] -DLLVM_DIR=/work/my-llvm/lib/cmake/llvm \
  -DClang_DIR=/work/my-clang/lib/cmake/clang
```

You do *not* need to set `Clang_DIR` if you build Clang within your LLVM
tree.  Also, note that you must actually *build* LLVM and Clang before
building C-Reduce.

Note that assertions are enabled by default. To disable assertions:

```
cmake ... -DENABLE_TRANS_ASSERT=OFF
```

## Regarding LLVM versions

Released versions of C-Reduce, and also our master branch at GitHub,
need to be compiled against specific released versions of LLVM, as
noted in this file.

Our GitHub repo usually also has a branch called llvm-svn-compatible
that supports building C-Reduce against LLVMs that are newer than the
last released version.  The most recent version of LLVM that the
llvm-svn-compatible branch is known to compile against is recorded in
`LAST_KNOWN_WORKING_LLVM`.  C-Reduce may happen to also build against
revisions before or after this, but we make no guarantees.

