Quick tour
**********


Getting help
============

To get a list of available commands and help topics:

   $ cmany help

To get help on a particular command (eg, "build") or topic (eg,
"quick_tour"), any of the following can be used, and they are all
equivalent:

   $ cmany help build
   $ cmany h build             # help has an alias: h
   $ cmany build -h
   $ cmany build --help

Note that this text is also available as a help topic. You can read it
with the help command:

   $ cmany h quick_tour


Build
=====

Consider a directory initially with this layout:

   $ ls -1
   CMakeLists.txt
   main.cpp

The following command invokes CMake to configure and build this
project:

   $ cmany build .

Like with CMake, this will look for the CMakeLists.txt file at the
given path (".") and place the build tree at the current working
directory. If the path is omitted, CMakeLists.txt is assumed to be on
the current working dir. Also, the "build" command has an alias of
"b". So the following command is exactly the same as "cmany build .":

   $ cmany b

When no compiler is specified, cmany chooses CMake's default compiler.
cmany's default build type is (explicitly set to) "Release". As an
example, using g++ 6.1 in Linux x86_64, the result of the command
above will be this:

   $ tree -fi -L 2
   build/
   build/linux-x86_64-g++6.1-Release/
   CMakeLists.txt
   main.cpp

   $ ls build/*/CMakeCache.txt
   build/linux-x86_64-g++6.1-Release/CMakeCache.txt

Note that unlike CMake, cmany will not place the resulting build tree
directly at the current working directory: it will instead nest it
under "./build". Each build tree name is made unique by combining the
names of the operating system, architecture, compiler+version and the
CMake build type.


Configure
=========

It was said above that the "cmany build" command will also configure.
In fact, cmany will detect when a configure step is needed. But you
can just use "cmany configure" if that's only what you want to do:

   $ cmany configure

Same as above: "c" is an alias to "configure":

   $ cmany c


Install
=======

The "cmany install" command does what it says, and will also
"configure" and "build" if needed. "i" is an alias to "install":

   $ cmany i

The install root defaults to "./install". So assuming the project
creates a single executable named "hello", the following will result:

   $ ls -1
   CMakeLists.txt
   build/
   install/
   main.cpp

   $ tree -fi install
   install/
   install/linux-x86_64-g++6.1-Release/
   install/linux-x86_64-g++6.1-Release/bin/
   install/linux-x86_64-g++6.1-Release/bin/hello


Choosing the build type
=======================

cmany uses Release as the default build type. To set a different build
type use "--build-types/-t". The following command chooses a build
type of Debug instead of Release:

   $ cmany b -t Debug

If the directory is initially empty, this will be the result:

   $ ls -1 build/*
   build/linux-x86_64-g++6.1-Debug/

Note that the build naming scheme will cause build trees with
different build types to be placed in different directories. Apart
from producing a better organization of your builds, this saves you a
full project rebuild when the build type changes (and the cmake
generator is not a multi-config generator like MSVC).


Choosing the compiler
=====================

cmany defaults to CMake's default compiler. To use different
compilers, use "--compilers/-c". Each argument given here must be an
executable compiler found in your path, or an absolute path to the
compiler.

The following command chooses clang++ instead of CMake's default
compiler:

   $ cmany b -c clang++

If the directory is initially empty, this will be the result:

   $ ls -1 build/*
   build/linux-x86_64-clang++3.9-Release/

Read more here.


Choosing build/install directories
==================================

By default, cmany creates the build trees nested under a directory
"build" which is created as a sibling of the "CMakeLists.txt" project
file. Similarly, the install trees are nested under the "install"
directory. However, you don't have to use these defaults. The
following command will use "foo" for building and "bar" for
installing:

   $ cmany i -c clang++,g++ --build-dir foo --install-dir bar

   $ ls -1 foo/ bar/
   bar/linux-x86_64-clang++3.9-Release/
   bar/linux-x86_64-g++6.1-Release/
   bar/linux-x86_64-icpc16.1-Release/
   foo/linux-x86_64-clang++3.9-Release/
   foo/linux-x86_64-g++6.1-Release/
   foo/linux-x86_64-icpc16.1-Release/

Note that "foo" and "bar" will still be placed under the current
working directory, since they are given as relative paths. cmany also
accepts absolute paths here.


Building many trees at once
===========================

The commands shown up to this point were only fancy wrappers for
CMake. Since defaults were being used, or single arguments were given,
the result for each command was a single build tree. But as its name
attests to, cmany will build many trees at once by combining the build
items. For example, to build both "Debug" and "Release" build types
while using defaults for the remaining parameters, you can do the
following (resulting in 2 build trees):

   $ cmany b -t Debug,Release
   $ ls -1 build/
   build/linux-x86_64-g++6.1-Debug/
   build/linux-x86_64-g++6.1-Release/

You can also do this for the compilers (2 build trees):

   $ cmany b -c clang++,g++
   $ ls -1 build/
   build/linux-x86_64-clang++3.9-Release/
   build/linux-x86_64-g++6.1-Release/

And you can also combine all of them (4 build trees):

   $ cmany b -c clang++,g++ -t Debug,Release
   $ ls -1 build/
   build/linux-x86_64-clang++3.9-Debug/
   build/linux-x86_64-clang++3.9-Release/
   build/linux-x86_64-g++6.1-Debug/
   build/linux-x86_64-g++6.1-Release/

Another example -- build using clang++,g++,icpc for
Debug,Release,MinSizeRel build types (9 build trees):

   $ cmany b -c clang++,g++,icpc -t Debug,Release,MinSizeRel
   $ ls -1 build/
   build/linux-x86_64-clang++3.9-Debug/
   build/linux-x86_64-clang++3.9-MinSizeRel/
   build/linux-x86_64-clang++3.9-Release/
   build/linux-x86_64-g++6.1-Debug/
   build/linux-x86_64-g++6.1-MinSizeRel/
   build/linux-x86_64-g++6.1-Release/
   build/linux-x86_64-icpc16.1-Debug/
   build/linux-x86_64-icpc16.1-MinSizeRel/
   build/linux-x86_64-icpc16.1-Release/

The items that can be combined by cmany are called **build items**.
cmany has the following classes of build items:

* systems: "-s/--systems sys1[,sys2[,...]]"

* architectures ("-a/--architectures arch1[,arch2[,...]]"

* compilers ("-c/--compilers comp1[,comp2[,...]]"

* build types ("-t/--build-types btype1[,btype2[,...]]"

* variants ("-v/--variants var1[,var2[,...]]"

All of the arguments above accept a comma-separated list of items. Any
omitted argument will default to a list of a single item based on the
current system (for example, omitting "-s" in linux yields an implicit
"-s linux" whereas in windows yields an implicit "-s windows"; or
omitting "-a" in a 64 bit processor system yields an implicit "-a
x86_64").

cmany will generate builds by combining every build item with every
other build item of different class. The resulting build has a name of
the form
"{system}-{architecture}-{compiler}-{build_type}[-{variant}]".

A variant is a build item which brings with it a collection of flags.
This allows for easy combination of these flags with other build
items. But note that every build item can bring specific flags with
it.

Since the number of build item combinations grows very quickly and not
every combination will make sense, cmany has arguments to exclude
certain combinations, either by the resulting build name (with a
regex) or by the names of the items that a build would be composed of.
Read more about it here.


Using flags
===========

(Full docs for flags here).

You can set cmake cache variables using "--cmake-vars/-V". For
example, the following command will be the same as if "cmake
-DCMAKE_VERBOSE_MAKEFILES=1 -DPROJECT_SOME_DEFINE=SOME_DEFINE= ."
followed by "cmake --build" was used:

   $ cmany b -V CMAKE_VERBOSE_MAKEFILES=1,PROJECT_SOME_DEFINE=SOME_DEFINE=

To add preprocessor macros, use the option "--defines/-D":

   $ cmany b -D MY_MACRO=1,FOO=bar,SOME_DEFINE

The command above has the same meaning as if "cmake -D
CMAKE_CXX_FLAGS="-DMY_MACRO=1 -DFOO=bar -DSOME_DEFINE"" followed by
"cmake --build" was used.

To add C++ compiler flags, use the command line option "--
cxxflags/-X". To prevent these flags being interpreted as cmany
command options, use quotes or single quotes:

   $ cmany b -X "--Wall","-O3"      # add -Wall -O3 to all builds

To add C compiler flags, use the option "--cflags/-C". As with C++
flags, use quotes to escape:

   $ cmany b -C "--Wall","-O3"

Using flags per build item is easy. Instead of specifying the flags at
the command level as above, specify them at build item. For example:

   $ cmany b --variant 'foo: --defines SOME_DEFINE=32 --cxxflags "-Os"' \
             --variant 'bar: --defines SOME_DEFINE=16 --cxxflags "-O2"'

To be clear, the "foo" variant will be compiled with the preprocessor
symbol named "SOME_DEFINE" defined to 32, and will use the "-Os" C++
compiler flag. In turn, the "bar" variant will be compiled with the
preprocessor symbol named "SOME_DEFINE" defined to 16, and will use
the "-O2" C++ compiler flag. So instead of the build above, we now
get:

   $ ls -1 build
   build/linux-x86_64-clang++3.9-Release-bar/
   build/linux-x86_64-clang++3.9-Release-foo/

Note above the additional "-foo" and "-bar" suffixes to denote the
originating variant.

You can make build items inherit the flags from other build items: add
a "@" reference to the variant you want to inherit from. For example:

   $ cmany b --variant 'foo: --defines SOME_DEFINE=32 --cxxflags "-Os"' \
             --variant 'bar: @foo --defines SOME_DEFINE=16 --cxxflags "-O2"'

This will result in the "bar" variant having its flags specifications
as "--defines SOME_DEFINE=32 --cxxflags "-Os" --defines SOME_DEFINE=16
--cxxflags "-O2"".


Cross-compiling
===============

Cross compilation with cmake requires passing a toolchain file. cmany
has the "--toolchain" option for this. This is more likely to be used
as a flag of the system or architecture build type.


Building dependencies
=====================

cmany offers the argument "--deps path/to/extern/CMakeLists.txt" to
enable building another CMake project which builds and installs the
dependencies of the current project. When "--deps" is given, the
external project is built for each configuration, and installed in the
configuration's build directory. Use "--deps-prefix" to specify a
different install directory for the external project. Read more here.


Argument reuse
==============

Due to the way that compilation flags are accepted, the full form of a
cmany command can become big. To save you from retyping the command,
you can set the "CMANY_ARGS" environment variable to reuse arguments
to cmany. As an experimental (and buggy) feature, you can also
permanently store these options in a "cmany.yml" project file, which
should be placed side by side with the project "CMakeLists.txt". You
can find more about this here.


Exporting build configurations
==============================

cmany has the command "export_vs", which exports the build
configurations to Visual Studio through the file "CMakeSettings.json"
(placed side by side with the project "CMakeLists.txt"). Read this MS
blog post to discover how to use the generated file.

For code-intelligence tools requiring knowledge of the compilation
commands (for example, rtags, and many other tools used with emacs),
cmany offers also the argument "-E/--export-compile". This argument
will instruct cmake to generate the file "compile_commands.json"
(placed in each build tree).
