Skip to content

laserpants/foomake

Repository files navigation

foomake

Wouldn't it be nice to have a more grokkable way to express CMake build requirements? So that, instead of…

# CMakeLists.txt

cmake_minimum_required(VERSION 3.2)

project(example VERSION 0.1.0 LANGUAGES CXX)

set(DEFAULT_BUILD_TYPE "Release")

add_library(grok STATIC src/laserpants/grok.cpp)

target_include_directories(grok PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_compile_features(grok PUBLIC cxx_std_17)

add_executable(main src/main.cpp)

target_link_libraries(main grok)

…we could write something like:

name:                   example
version:                0.1.0
description:            An example of a declarative CMakeLists configuration
homepage:               http://github.com/laserpants/foomake#readme
languages:              CXX
variables:
  DEFAULT_BUILD_TYPE:   Release

executables:
  main:
    source-files:
      - src/main.cpp
    link-libraries:
      - grok

libraries:
  grok:
    type: static
    source-files:
      - src/laserpants/grok.cpp
    include-directories:
      public:
        - '${CMAKE_CURRENT_SOURCE_DIR}/include'
    compile-features:
      public:
        - cxx_std_17

Top-level keys

Key Type Description
name string Set the PROJECT_NAME variable
version string Set the PROJECT_VERSION variable
description string Set the CMAKE_PROJECT_DESCRIPTION variable
homepage string Set the CMAKE_PROJECT_HOMEPAGE_URL variable
languages list (or string) Set the project LANGUAGES
cmake-minimum-required dict (or string) Set the minimum required version of CMake
executables dict Executable targets (binaries)
libraries dict Library targets
variables dict
options dict
install dict
configure list Copy and perform variable substitution on files
dependencies list

†) Required if any of version, description, homepage, or languages are set.


name, version, description, homepage

These properties set the project details. For example,

name: Your project
version: '1.3'
description: One project to rule them all

translates to:

project(Your project
  VERSION
    1.3
  DESCRIPTION
    One project to rule them all
  )

Surround the version string in single or double quoutes to avoid the value being interpreted as a number.


languages

A list of languages that your project supports. For example,

name: example
languages:
  - CXX
  - Fortran

translates to:

project(example LANGUAGES CXX Fortran)

A string can also be used:

languages: CXX

cmake-minimum-required

cmake-minimum-required:
  version: '3.2'

The following form is also accepted:

cmake-minimum-required: '3.2'

Or to specify a range:

cmake-minimum-required: '3.1...3.13'

executables

executables:
  <target-name>: <dictionary>
  <target-name>: <dictionary>
  ...

See Targets


libraries

libraries:
  <target-name>: <dictionary>
  <target-name>: <dictionary>
  ...

See Targets


variables

A dictionary where each key corresponds to the name of a variable.

variables:
  <variable-name>: <value>
  <variable-name>: <value>
  ...

The values are either strings (the variable's value), or objects of the following form:

Key Type Required Description
value string yes
TODO
variables:
  MY_VARIABLE: rocks
set(MY_VARIABLE "rocks")
variables:
  MY_VARIABLE:
    value: rocks

options

options:
  <option-name>: <dictionary>
  <option-name>: <dictionary>
  ...
Key Type Required Description
description string
initial-value string
options:
  DISCO_PANTS:
    description: Whether to clothe oneself in disco attire or not
    initial-value: 'YES'

install


configure

A list of files to perform variable substitution on. List entries should be dictionaries of the following form:

Key Type Required Description
file list yes A two-element list of the form [ input, output ]
arguments dict Arguments accepted by the configure_file command

Example:

configure:
  - file: ['config.h.in', 'config.h']
    arguments:
      @ONLY: true

file

arguments


Targets

Targets are specified under the executables, and libraries top-level keys respectively.

  executables:
    <target-name>: <dictionary>
    <target-name>: <dictionary>
    ...

  libraries:
    <target-name>: <dictionary>
    <target-name>: <dictionary>
    ...

The following keys appear in mappings of both types.

Key Type Required Default Alias Description
source-files list
include-directories dict or list [] include-dirs
link-libraries list link-libs
compile-features dict

include-directories

    include-directories:
      public:
        - 'include'
        - 'include/stuff'
    include-directories:
      - 'include'
      - 'include/stuff'
    include-directories:
      public:
        - path: 'include'
      private:
        - path: 'include/stuff'

link-libraries


source-files


Executables

Key Type Required Default Alias Description

Libraries

Key Type Required Default Alias Description
type static | shared | module static

type


Dependencies

name: example
find-package: 
  - name: Boost
    version: '1.55'
    components: 'asio'

executables:
  main:
    link-libraries:
      - Boost::boost
name: example
find-package: 
  - Boost

Examples

The following examples are adapted from https://cmake.org/cmake-tutorial/

Step 1

cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# the version number
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# configure a header file to pass some of the CMake settings to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

# add the binary tree to the search path for include files so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")

# add the executable
add_executable(Tutorial tutorial.cxx)
name: Tutorial
version: '1.0'                      # the version number

cmake-minimum-required:
  version: '2.6'

executables:
  Tutorial:                         # add the executable
    source-files:
      - tutorial.cxx
    include-directories:
      public:
        - '${PROJECT_BINARY_DIR}'   # add the binary tree to the search path for include files
                                    # so that we will find TutorialConfig.h

# configure a header file to pass some of the CMake settings to the source code
configure:
  - file: ['${PROJECT_SOURCE_DIR}/TutorialConfig.h.in',
           '${PROJECT_BINARY_DIR}/TutorialConfig.h']

Step 2

# CMakeLists.txt

cmake_minimum_required (VERSION 2.6)
project (Tutorial)

# the version number
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)

# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)

# configure a header file to pass some of the CMake settings to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
  "${PROJECT_BINARY_DIR}/TutorialConfig.h"
  )

# add the binary tree to the search path for include files so that we will find TutorialConfig.h
include_directories ("${PROJECT_BINARY_DIR}")

# add the MathFunctions library?
if (USE_MYMATH)
  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")
  add_subdirectory (MathFunctions)
  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif ()

# add the executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial  ${EXTRA_LIBS})
# MathFunctions/CMakeLists.txt

add_library(MathFunctions mysqrt.cxx)
name: Tutorial
version: '1.0'

cmake-minimum-required:
  version: '2.6'

options:
  USE_MYMATH:
    description: Use tutorial provided math implementation
    initial-value: 'ON'

executables:
  Tutorial:
    source-files:
      - tutorial.cxx
    include-directories:
      public:
        - '${PROJECT_BINARY_DIR}'
    .if-USE_MYMATH-link-libraries:
      - MathFunctions

libraries:
  .if-USE_MYMATH-MathFunctions:
    source-files:
      - MathFunctions/mysqrt.cxx
    include-directories:
      public:
        - '${PROJECT_SOURCE_DIR}/MathFunctions'

configure:
  - file: ['${PROJECT_SOURCE_DIR}/TutorialConfig.h.in',
           '${PROJECT_BINARY_DIR}/TutorialConfig.h']

Releases

No releases published

Packages

No packages published