aimotive-legacy / cmakex

lightweight package manager for CMake
4 stars 1 forks source link

cmakex

Extension for the cmake command

Keywords: lightweight, non-intrusive C/C++ package management, multiple repos tool, applying common cmake build/toolchain options, package server

Show me quickly what I can do with this

Say, you have a CMake-enabled project which depends on jsoncpp and GTest and on another inhouse library of yours. Simply create a cmake file deps.cmake next to your project's CMakeLists.txt with this content:

add_pkg(GTest GIT_URL https://github.com/google/googletest
  CMAKE_ARGS -Dgtest_force_shared_crt=1)
add_pkg(jsoncpp
  GIT_URL https://github.com/open-source-parsers/jsoncpp GIT_TAG 1.7.1
  CMAKE_ARGS -DJSONCPP_WITH_TESTS=0 -DJSONCPP_WITH_POST_BUILD_UNITTEST=0
    -DJSONCPP_WITH_CMAKE_PACKAGE=1)
add_pkg(mylibfoo GIT_URL https://github.com/thatsme/mylibfoo)

Then build your project from scratch with this one-liner:

cmakex br -H myproj -B myproj-build --deps

That single line downloads and installs the dependencies and [b]uilds the [r]elease configuration of your project.

Edit your main project or mylibfoo (or any other dependency) and rebuild:

cmakex br myproj-build

Contents

Overview

cmakex is a command-line tool, which extends the functionality of the cmake command adding these interdependent features:

  1. Multiple cmake-commands with concise syntax: For example, configure, install, test a project for debug & release configs with a single command.
  2. Preset management: Define common CMake option groups (presets) in a YAML file. A preset can be a set of cmake-generator settings, platform and toolchain options. It can be added to the current command line with a single argument.
  3. Lightweight package-management: Describe your projects' dependencies in a cmake-script with ExternalProject_Add-like syntax. The dependencies will be automatically downloaded and installed before building your main project. No change needed in your CMakeLists.txt and you can use unchanged thirdparties as dependencies.
  4. Multiple-repos: Work in multiple projects simultaneously and build only the out-of-date projects automatically.
  5. Binary package server: (to be implemented) Install a local or remote build- server which builds, caches and provides installable packages, automatically managing the full dependency graph, keeping track of versions and build settings.

And all this is

Building and Installing

Prerequisites: CMake version 3.1 (this could be lowered on demand)

All other dependencies are cloned and built within this project. For a quick build execute these commands: (use git-bash on Windows)

./configure.sh && ./make.sh

Getting Started

...

Usage

cmakex [--help] [--version]
       [c][b][i][t][d][r][w] [<source/build-dir-spec]
       [<cmake-args>...] [<additional-args>...]
       [-- <native-build-tool-args>...]

Note: Invoke CTest is not yet implemented.

General commands:

--help       display this message
--version    display version information
-V           verbose

CMake-wrapper mode:

Execute multiple CMake commands with concise syntax.

The command-word consisting of the letters c, b, i, t, d, r, w specifies the CMake steps to execute and the configurations.

Use one or more of:

c, b, i, t: to perform CMake configure/build/install/test steps
   d, r, w: for Debug, Release and RelWithDebInfo configurations

The order of the letters is not important.

<source/build-dir-spec> is one of

-H <path-to-source> -B <path-to-build>
<path-to-existing-build>
-B <path-to-existing-build>
<path-to-source> (build directory is the current working directory)

-H and -B options can be written with or without spaces.

Accepted <cmake-args>:

For detailed help on these arguments see the documentation of the cmake command: cmake(1).

--config <cfg>: For specifying configs other than Debug, Release
                RelWithDebInfo. Can be used multiple times.

--target <tgt>: For specifying targets other than ALL (default) and INSTALL
                (for that one, use 'i' in the command-word). Can be used
                multiple times.

--clean-first

-C, -D, -U, -G, -T, -A

-N, all the -W* options

--debug-trycompile, --debug-output, --trace, --trace-expand
--warn-uninitialized, --warn-unused-vars, --no-warn-unused-cli,
--check-system-vars, --graphwiz=

Package-management

--deps[=<path>]
              Before executing the cmake-steps on the main project, process
              the dependency-script at <source-dir>/deps.cmake (default) or
              at <path> and download/configure/build/install the packages
              defined in the script (on demand)

--deps-only[=<path>]
              Same as `--deps` but does not process the main project.
              Tip: use `cmakex -B <path-to-new-or-existing-build>
              --deps-only=<path> ...` to build a list of packages without a
              main project

--force-build Configure and build each dependency even if no build options
              or dependencies have been changed for a package.

--update[=MODE]
              The update operation tries to set the previously cloned repos
              of the dependencies to the state as if they were freshly cloned.
              The MODE option can be `if-clean`, `if-very-clean`, `all-clean`,
              `all-very-clean` and `force`.

              The `all-clean` mode updates only if there are no local changes
              and allows only fast-forward merge. It may change (or leave) the
              current branch, for another branch, tag or commit, as needed.
              Halts with an error if the update is not possible.

              The `all-very-clean` is similar does not allow to change (or
              leave) the current branch.

              The `if-clean` and `if-very-clean` modes are similar, but they
              don't stop at the first error, simply skip updating the project
              where it's not possible.

              The `force` mode updates in all cases, may abandon local changes
              and commits (uses 'git reset --hard' when fast-forward merge is
              not possible)

              The default MODE is 'all-very-clean`, the safest mode.

--update-includes
              The CMake `include()` command used in the dependency scripts
              can include a URL. The file the URL refers to will be
              downloaded and included with the normal `include` command.
              Further runs will use the local copy. Use this option to purge
              the local copies and download the files again.

Presets

-p <path>#preset[#preset]...
              Load the YAML file from <path> and add the args defined for
              the presets to the current command line.

-p preset[#preset]...
              Use the file specified in the CMAKEX_PRESET_FILE environment
              variable.

If the CMAKEX_PRESET_FILE environment variable is not set and there's a default-cmakex-presets.yaml file in the directory of the cmakex executable it will be used as default preset file.

cmakex configuration

--deps-source=<DIR>
--deps-build=<DIR>
--deps-install=<DIR>
                Parent directories of the of the source directories (cloned
                repositories), build directories and install directory for
                the dependencies. The default values are `_deps`,
                `_deps-build` and `_deps-install` under `CMAKE_BINARY_DIR`.

--single-build-dir
                With makefile-generators (as opposed to multiconfig) the
                default is to create separate build directories for each
                configuration (Debug, Release, etc..).
                Use this option to force a single build directory.
                Effective only on the initial configuration and only
                for makefile-generators.

Miscellaneous

--manifest=<path>
          Save a manifest file to <path> which can be used to reproduce the
          same build later. It contains `add_pkg` commands to describe the
          dependencies and also information about the command line and the
          main project. It's advised to use the `.cmake` extenstion so it
          can be given to the `--deps=` argument later.

-q        Quiet logging of cmake operations on dependencies. The stdout and
          stderr from cmake will only be saved to disk but not forwarded to
          stdout, except if the command fails.

Environment variables

CMAKEX_LOG_GIT=<cmake-recognized-boolean-value>
          If enabled, logs all git commands to stdout. For debugging.

Examples:

Configure, install and test a project from scrach, for Debug and Release configurations, clean build:

cmakex itdr -H . -B b -DCMAKE_INSTALL_PREFIX=$PWD/out -DFOO=BAR

Configure new project, Debug config, use a preset:

cmakex cd -H . -B b -p preset-dir/presets.yaml#android-toolchain

Build Release config in existing build dir, with dependencies

cmakex br my-build-dir --deps

Tutorial

...