An Enhancement Suite for the CMake Build System

Overview

cmakepp logo

A CMake Enhancement Suite

Travis branch GitHub stars GitHub forks GitHub issues Build Status Project Stats

Usage

Look through the files in the package. Most functions will be commented and the other's usage can be inferred. All functions are available as soon as you include the cmakepp.cmake file. To find functionality browse the README.md files throughout this project.

Feature Overview

cmakepp has a lot of different functions. I tried to subdivide them into some meaningful sections.

Samples

I have developed some samples to show off cmakepp's capabilities. Here you can find an overview of these samples

https://github.com/open-source-parsers/jsoncpp/archive/1.6.0.tar.gz https://github.com/leethomason/tinyxml2/archive/2.2.0.tar.gz https://yaml-cpp.googlecode.com/files/yaml-cpp-0.5.1.tar.gz

Getting cmakepp

You have multiple options to install cmakepp the only prerequisite for all options is that CMake is installed with a version >=2.8.12. cmakepp will also work with version less than 2.8.12 however some functions might fail.

Install by Console

For ease of use I provide you with simple copy paste code for your console of choice. These scripts download the install.cmake file and execute it. This file in turn downloads cmakepp and adds itself to your os (creating aliases and setting a environment variable - which allow you to use icmakepp and cmakepp cli from the console).

Bash

#!bin/bash
wget https://raw.github.com/toeb/cmakepp/master/install.cmake && cmake -P install.cmake && rm install.cmake

Powershell

((new-object net.webclient).DownloadString('https://raw.github.com/toeb/cmakepp/master/install.cmake')) |`
out-file -Encoding ascii install.cmake; `
cmake -P install.cmake; `
rm install.cmake;


Install by Downloading a Release

You can go ahead and download the current release from here. A release supplies you with a standalone version of cmakepp which contains every function of cmakepp. This standalone file can be included in any of your CMake scripts.

The following code shows you how you can retrieve and include it in any of your script files.

## downloads and includes `cmakepp.cmake` 
if(NOT EXISTS "cmakepp.cmake")
  file(DOWNLOAD "https://github.com/toeb/cmakepp/releases/download/v0.0.4/cmakepp.cmake" "cmakepp.cmake")
endif()
include("cmakepp.cmake")

Manually setting up aliases

cmake -P ./cmakepp.cmake cmakepp_setup_environment

After You run this and relogin/repoen your console/resource your .bashrc you will have access to the alias cmakepp, icmakepp, pkg, cml. Also the environment variable CMAKEPP_PATH will be set to the location were cmakepp.cmake resides.

Testing

To test the code (alot is tested but not all) run the following in the root dir of cmakepp this takes long :)

cmake -P build/script.cmake 

Developing

If you want to help to develope cmakepp or want to develope CMake scripts which use cmakepp you can do the following:

  • Install Sublime Text 3
  • Be sure you have the cmakepp repository checked out
  • open the cmakepp.sublime-project project in sublime text
  • (add the folder in which you are developing your scripts)
  • select the correct build system
    • cmakepp run test will run the current script open in SublimeText file as a test. It does not matter were this file resides. It expects a single function to exist inside this file - the name does not matter as it will be imported. Inside the test function you will be provided with the following (also see test_execute:
      • all cmakepp functions will be loaded from your current version of cmakepp.
      • a timer will run and report the time in milliseconds that your test took NOTE this is not very exact but sufficient in most cases
      • ${test_dir} contains the the path of an empty directory which will remain the same for that specific test. It is cleared before the test is run so you can write anything to it and do not have to care about housekeeping.
      • the will be set to ${test_dir} allowing you to start using all cmakepp file/process functions relative to the test directory
      • ${test_name} will contain the name chosen for this test (filename w/o extension)
    • cmakepp run all tests will run each test in cmakepp
    • cmakepp template run will execute a cmakepp template file of which the filename ends with .in (see templating)
    • you can open the cmakepp.sublime-project and modify the build system.

Developement Process

I have two persistant branches: master and devel. Then there are an arbitrary amount of volatile branches which are used to develope features / remote store developements. The master branch is only merged from devel and always is always stable - ie the build server determines that all tests were successfull. The devel branch is also built build servers but may sometime be in the failed state. The volatile branches are just used to develop and are not built - as to not clutter up the build servers with uneccessary builds.

Contributing

I would be very happy If you choose to contribute to cmakepp. You can open any issue on github and I will try to reply as soon as possible. I care about any feature you want implemented, bug you want squashed, or modification.

If you want to change something you may send pull requests through github. Normally I will check them quickly and travis-ci will build them. I suggest you run all tests using the sublime project before you create a pull request to see if anything breaks. (the master branch will have to pass the tests)

Also if you want to support me financially for all the hardwork - consider donating a couple of $ Click here to lend your support to: cmakepp  and make a donation at pledgie.com !

Developer Guidlines

I am a bit a hypocrit. I am trying to adhere to these rules though:

  • DO NOT USE SHOUTY SYNTAX
  • test your code. A single test file will suffice it should cover normal use cases and edge cases. I use tests for documentation.
  • One file per function.
  • Create a comment header with markdown above the function(with 2 # ).
  • put the function in the most suitable folder.
  • name the function in a none colliding way
    • CMake only has a global scope for functions. Therefore be sure to name them in a way that they do not collide with existing functions and will not in the future.
  • use snake_case for function names. CMake's functions are case independent so I discourage using camelcase

Implementation Notes

Formalisms

Note: This section is incomplete but will give you an idea how I formally define data and functions.

To describe cmake functions I use formalisms which I found most useful they should be intuitively understandable but here I want to describe them in detail.

  • @ denotes character data
  • ::= "\""@"\"" denotes a string literal
  • ::= "/" "/" denotes a regular expression which needs to match
  • ::= /[a-zA-Z_][a-zA-Z0-9_]*/ denotes a identifier which can be used for definitions
  • ::= "<" "any"|"bool"|"number"|""|"void"|""| ">" denotes a datatype. the elipses denotes that multiple values in array form are described else the datatype can be any, bool, number, etc..
  • ::= "<" ">"
  • ::= "<" "?"? "&"?| "&"?":" | > ("=" ">" denotes a possibly named piece of data. this is used in signatures and object descriptions e.g. generate_greeting( > >)-> specifies a function which which takes a required parameter called first_name which is of type string and an optional parameter called lastname which is of type string and returns a string
    • & indicates that the identifier is a reference - a variable exists with the name passed in the named identifier
    • ? indicates optionality (no need to specify the value)
    • `= indicates the default value which is used when the specified value is not specified
  • ::= "{" |( ":" ))...>|"}" the structured date is sometimes multiline
    • { > > }
    • { name: age: }
    • { name: address:{ street: area_code: } age: }
    • { < >: > ...> } describes a map which contains keys of type string which identify a group and associated values which are a string list representing users
  • primitive which stands for nothing
  • ::= "" primitive which is truely empty (a string of length 0)
  • :"false"|""|"no" cmake's false values (list incomplete)
  • : !
  • ::= "true":"false" indicates a well defined true or false value
  • ::= | |
  • ::= | | | |
  • ::= /a-zA-Z0-9_-/+
  • ::= "<"|"[" ( =" ")?"]"|">" specifies a named function parameter. a value identifier without a definition causes the named function parameter to be a flag a boolean is derived which is true if the flag exists, else false.
    • [--my-flag] a flag
    • [--depth ] a optional value
    • <--depth > a required value
  • ::= |
  • ::= ("[" "]")?"(" ")" "->" ("," )?
    • ( )-> a function expecting a single element and returning a
    • ( )-> a function taking a variable amount of any and returning a list of strings
    • [ ]( >)-> a function taking a variable node of type which returns a list of expects a variable depth to be defined in parent scope which needs to be a integer
    • ...

Returning values

Related Functions

  • return(...) overwritten CMake function accepting arguments which are returned
  • ans() a shorthand for getting the result of a function call and storing it in var
  • clr([PARENT_SCOPE]) clears the __ans variable in current scope or in PARENT_SCOPE if flag is set.

A CMake function can return values by accessing it's parent scope. Normally one does the following to return a value

  function(myfunc result)
    set(${result} "return value" PARENT_SCOPE)
  endfunction()
  myfunc(res)
  assert(${res} STREQUAL "return value")

This type of programming causes problems when nesting functions as one has to return every return value that a nested function returns. Doing this automatically would cause alot of overhead as the whole scope would have to be parsed to see which values are new after a function call.

A cleaner alternative known from many programming languages is using a return value. I propose and have implemented the following pattern to work around the missing function return values of cmake.

  function(myfunc)
    return("return_value")
  endfunction()
  myfunc()
  ans(res)
  # the __ans var is used as a register
  assert(${__ans} STREQUAL "return value")
  assert(${res} STREQUAL "return value")

This is possible by overwriting CMakes default return() function with a macro. It accepts variables and will call set(__ans ${ARGN} PARENT_SCOPE) so after the call to myfunc() the scope will contain the variable __ans. using the ans() function is a shorthand for set( ${__ans}).

Caveats

  • The returnvalue should immediately be consumed after the call to myfunc because it might be reused again somewhere else.
  • functions which do not call return will not set __ans in their parent scope. If it is unclear weather a function really sets __ans you may want to clear it before the function call using clr()
  • the overwrite for return has to be a macro, else accessing the PARAENT_SCOPE would be unfeasible. However macros caus the passed arguments to be re-evaluated which destroys some string - string containing escaped variables or other escaped characters. This is often a problem - therfore I have als added the return_ref function which accepts a variable name that is then returned.

Alternatives

  • a stack machine would also be a possiblity as this would allow returning multiple values. I have decided using the simpler single return value appoach as it is possible to return a structured list or a map if multiple return values are needed.

cmakepp Console Client

cmakepp can be used as a platform independent console application. When you start cmakepp.cmake in script mode it parse the passed command line arguments and execute the specified cmakepp function returning the value in a serialization format. When you install cmakepp it will create an alias for cmake -P /path/to/cmakepp.cmake called cmakepp.

cmakepp http_get http://httpbin.org/get?key=value --json { "args":{ "key":"value" }, "headers":{ "Accept":"*/*", "Host":"httpbin.org", "User-Agent":"curl/7.38.0" }, "origin":"85.180.182.43", "url":"http://httpbin.org/get?key=value" } ## parse an uri using the cmakepp alias > cmakepp uri http+https://toeb:[email protected]/path/to/file.ext?key=value&key2.subkey=value2 --select "scheme: @scheme key2.subkey: @params.key2.subkey" "scheme: http+https key2.subkey: value2"">
## return content of this directory using the cmakepp.cmake file
> cmake -P /path/to/cmakepp.cmake glob *.cmake --relative
[
 "cmakepp.cmake",
 "install.cmake",
 "package.cmake"
]

## perform a http GET request using the cmakepp alias
> cmakepp http_get http://httpbin.org/get?key=value --json
{
 "args":{
  "key":"value"
 },
 "headers":{
  "Accept":"*/*",
  "Host":"httpbin.org",
  "User-Agent":"curl/7.38.0"
 },
 "origin":"85.180.182.43",
 "url":"http://httpbin.org/get?key=value"
}

## parse an uri using the cmakepp alias
> cmakepp uri http+https://toeb:[email protected]/path/to/file.ext?key=value&key2.subkey=value2 --select "scheme: @scheme key2.subkey: @params.key2.subkey"
"scheme: http+https key2.subkey: value2"

Interactive CMake Shell

If you want to learn try or learn cmake and cmakepp you can use the interactive cmake shell by launching cmake -P icmakepp.cmake which gives you a prompt with the all functions available in cmakepp and cmake in general.

icmakepp allows you to enter valid cmake and also a more lazily you can neglect to enter the parentheses around functions e.g. cd my/path -> cd(my/path)

Since console interaction is complicated with cmake and cmake itself is not very general purpose by design the interactive cmake shell is not as user friendly as it should be. If you input an error the shell will terminate because cmake terminates. This problem might be addressed in the future (I have an idea however not the time to implement and test it) Example:

pwd "/usr/tobi" icmakepp> @echo off echo is now off icmakepp> pwd icmakepp> message("${ANS}") /usr/tobi icmakepp> @echo on echo is now on icmakepp> function(myfunc name)\ # <-- backslash allows multiline input message("hello ${name}") \ obj("{name: $name}")\ ans(person)\ return(${person})\ endfunction() "/usr/tobi" # <-- the last output of any function is always repeated. icmakepp> myfunc Tobi hello Tobi # <-- output in function using message {"name":"Tobi"} # <-- json serialized return value of function icmakepp> quit icmakepp is quitting > ">
> ./icmakepp.sh
icmakepp> cd /usr/tobi
"/usr/tobi"
icmakepp> pwd
"/usr/tobi"
icmakepp> @echo off
echo is now off
icmakepp> pwd
icmakepp> message("${ANS}")
/usr/tobi
icmakepp> @echo on
echo is now on
icmakepp> function(myfunc name)\  # <-- backslash allows multiline input
          message("hello ${name}") \
          obj("{name: $name}")\
          ans(person)\
          return(${person})\
        endfunction()
"/usr/tobi"                 # <-- the last output of any function is always repeated. 
icmakepp> myfunc Tobi
hello Tobi          # <-- output in function using message
{"name":"Tobi"}       # <-- json serialized return value of function
icmakepp> quit
icmakepp is quitting
> 
Comments
  • Process management enhancements

    Process management enhancements

    Hello Tobias, I'm here again :)

    I'm trying to use your process management system to speed up biicode Boost builds (I'm having timeouts on my travis ci builds due to Boost.Log build). Since Travis expects output, my idea was to get your process_start_script() and run each library build job as a separate process, then wait for all. If that works as expected, there will be no timeout since your process_wait_all() prints some fancy progress output.

    It works like a charm, I have it on a testing branch but I'm sure it will be part of the biicode Boost setup.

    I have a couple of suggestions/questions:

    • Custom progress information: I will be glad if some form of progress customization is made. The ....1/3... is great, but I think a bit of customization could improve a lot UX. In my case, I prompt Starting [boost lib] build job... before starting each script, one per line, will be great to print something similar when the process finishes [boost lib] build job finished. Maybe a callback on_success()/on_fail() approach?
    • Portability: As far I know the implementation uses system dependent scripting to achieve process management. To be able to use this features on biicode, I need support on Windows, linux, and mac. I remember a conversation where you pointed out that you are using PS on windows and bash on linux. Will this work on Darwin/Mac OSX too?
    opened by Manu343726 27
  • Please provide installable packages (rpm,deb) for Linux distros...

    Please provide installable packages (rpm,deb) for Linux distros...

    .. to save time, disk space and bandwidth .. to allow the use of cmakepp in build systems that diable network access during the build

    I am willing to help with that.

    Martin

    enhancement 
    opened by 15knots 15
  • Add map function for lists

    Add map function for lists

    I have a list of filenames without file extensions, and now I want to create two new derived lists which each add different file extensions to each list entry. E.g. in pseudocode:

    set(files filea fileb) set(sources lists_map(${files}, function(el) {return el ++ ".c"})) set(headers lists_map(${files}, function(el) {return el ++ ".h"}))

    opened by letmaik 7
  • Avoid variable expansion and stripping leading spaces in 'read_line'

    Avoid variable expansion and stripping leading spaces in 'read_line'

    On Windows, read_line

    • can't handle a leading = character (it crashes)
    • strips any leading spaces from the input
    • expands any variables (e.g. if the user enters %path%, the stored result is the value of the user's path environment variable rather than the string %path%).

    This patch fixes these issues.

    opened by Fraser999 7
  • Add a new function

    Add a new function "string_set_char_at"

    Add a function "string_set_char_at" (and unit tests) which corresponds to "string_char_at" in order to be able to set an abritary char in a string. Indexing is identical to "string_char_at". Example call: string_set_char_at(1 "hello" a) -> returns "hallo"

    opened by ahueck 4
  • What files do I need to include cmakepp without downloading it?

    What files do I need to include cmakepp without downloading it?

    One example shows how to download cmakepp when it is not available, directly from cmake. While that is very neat, I'm concerned about relying on github (and a working internet connection) for a build. Is there a release I can just drop in the project directory?

    opened by sztomi 3
  • Release candidate of title case algorithm for cmakepp

    Release candidate of title case algorithm for cmakepp

    A title case algorithm written in cmake for cmakepp. It automatically tries to set the title case of a sentence. Example: "my simple title" -> "My Simple Title" It tries to keep certain words in lower case, as set by a style guide (easily changed). Caveat: it only works for English sentences correctly. Use case example: documentation, where title case might be useful for a section

    opened by ahueck 3
  • complex dependency constraints

    complex dependency constraints

    currently complex constraints (constraints other than true,false or null) only allow {optional:true|false}

    these dependency constraints should allow more. (e.g. content_dir = relative path to package is linked to content dir of dependency)

    version constraints...

    opened by toeb 3
  • Add progress seed to process_wait_all() idle callbacks

    Add progress seed to process_wait_all() idle callbacks

    This way it's easy to print progress status based on that seed. It's not a real progress value, but a seed to be used to generate output.

    I'm using it to generate dynamic ellipsis output with \r on the boost-biicode scripts.

    opened by Manu343726 3
  • String - Documentation and API changes

    String - Documentation and API changes

    Overview

    This is an attempt to start to streamline the documentation of the cmake/string function folder. At the same time, the corresponding tests were created/extended/streamlined in order to ensure a more thorough testing.

    What was added:

    • Comments what each function does and specifying the type of input and output
    • Create a reasonable unit test base line
    • Bug fixes due to testing

    TODO

    • Validate the documentation: errors, form
    • Validate that the changed API has no further side effects
    • Finish the documentation. A few functions are missing.

    Caveat

    For a few functions, the order of the parameters were changed (hence the API changes). I tried to update the calls and tests seemingly work (cmake -P cmakepp.cmake test_execute_glob_parallel "tests//.cmake"). However, executing "cmake -P build/script.cmake" fails (same as the master itself?)

    opened by ahueck 2
  • CMake 3.0.1 testing

    CMake 3.0.1 testing

    Hi,

    I've added cmake 3.0.1 version to travis-ci config. Seems that some test fails with message:

    CMake Error at cmake/core/message.cmake:142 (_message):
    
    'assertion failed1: '1.0.0-+;STREQUAL;1.0.0''
    
    opened by ruslo 2
  • CMake Error at __cmakepp.cmake:15936 (endforeach):   Flow control statements are not properly nested. Call Stack (most recent call first):   install.cmake:17 (include)

    CMake Error at __cmakepp.cmake:15936 (endforeach): Flow control statements are not properly nested. Call Stack (most recent call first): install.cmake:17 (include)

    curl -OL https://raw.github.com/toeb/cmakepp/master/install.cmake && cmake -P install.cmake && rm install.cmake
    

    on macOS 11.4 (20F71) with cmake version 3.21.2

    opened by SamuelMarks 2
  • SemVer regex used to parse SemVer strings is broken.

    SemVer regex used to parse SemVer strings is broken.

    In semver_parse.cmake, you have:

     set(semver_identifier_regex "[0-9A-Za-z-]+")
     set(semver_major_regex "[0-9]+")
     set(semver_minor_regex "[0-9]+")
     set(semver_patch_regex "[0-9]+")
     set(semver_identifiers_regex "${semver_identifier_regex}(\\.${semver_identifier_regex})*") 
     set(semver_prerelease_regex "${semver_identifiers_regex}")
     set(semver_metadata_regex "${semver_identifiers_regex}")
     set(semver_version_regex "(${semver_major_regex})\\.(${semver_minor_regex})\\.(${semver_patch_regex})")
     set(semver_regex "(${semver_version_regex})(-${semver_prerelease_regex})?(\\+${semver_metadata_regex})?")
    
    

    I am not familiar with the cmake language, but I don't see where any of this excludes leading zeroes in numeric fields. As per the SemVer 2.0 spec, numeric fields may appear in the version triple (either major, minor or patch) and in prerelease fields (fields are dot delimited), and they may not have leading zeros. The following version strings are not SemVer compliant:

    • 01.0.0 // Leading zero in major field.
    • 1.01.0 // Leading zero in minor field.
    • 1.0.01 // Leading zero in patch filed.
    • 1.0.0-01 // Leading zero in prerelease field.
    • 1.0.0-1.01 // Leading zero in prerelease field.

    Please see the suggested regex's provided near the end of the FAQ and the discussion threads that eventually lead to their adoption, particularly the minimal set of oracles used to test them.

    For major, minor and patch, you should have (0|[1-9]\d*), and prerelease is something like (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*. The reason for the more complex prerelease part is due to the fact that a prerelease tag consists of either numeric or alphanumeric fields, delimited by periods.

    Based on what you have in that file, I think you would also reject a valid SemVer strings of the form 1.0.0+meta and 1.0.0-prr+meta.1.

    opened by jwdonahue 1
  • Download link for

    Download link for "Biicode Block" gives security warning

    README.rd (4c20943) says: "Use the Biicode Block" but that URL (https://www.biicode.com/toeb/cmakepp) gives a scary security warning in Firefox.

    opened by PerMildner 1
  • CMake deprecation warning

    CMake deprecation warning

    I'm getting deprecation warnings of policies CMP0053 and CMP0054, running CMake 3.12.3 on macOS.

    CMake Deprecation Warning at submodules/cmakepp/cmakepp.cmake:25 (cmake_policy):
      The OLD behavior for policy CMP0053 will be removed from a future version
      of CMake.
    
      The cmake-policies(7) manual explains that the OLD behaviors of all
      policies are deprecated and that a policy should be set to OLD only under
      specific short-term circumstances.  Projects should be ported to the NEW
      behavior and not rely on setting a policy to OLD.
    Call Stack (most recent call first):
      CMakeLists.txt:15 (include)
    
    
    CMake Deprecation Warning at submodules/cmakepp/cmakepp.cmake:28 (cmake_policy):
      The OLD behavior for policy CMP0054 will be removed from a future version
      of CMake.
    
      The cmake-policies(7) manual explains that the OLD behaviors of all
      policies are deprecated and that a policy should be set to OLD only under
      specific short-term circumstances.  Projects should be ported to the NEW
      behavior and not rely on setting a policy to OLD.
    Call Stack (most recent call first):
      CMakeLists.txt:15 (include)
    

    Personally I didn't get any errors when setting both policies to NEW, but I'm only using the following functions from CMake++.

    • semver_parse
    • ans
    • scope_import_map
    opened by vidavidorra 0
  • cross-platform and toolchains / external programs / advanced examples

    cross-platform and toolchains / external programs / advanced examples

    Hi @toeb ,

    Hope you are all well !

    I was wondering how CMake++ could help me to manage different types of external project schemes and to cache some cross-platform build with a project version + toolchain tag.

    Goal:

    • Support of CMake, QMake, Automake, Maven packages or some package installation in non-standard location packages (prefix) (eg link)
    • Support a registry of C/C++ packages, or stack of packages, with specific CMake args, and trigger some override commands for custom POST_BUILD actions (eg copy all runtime libraries with dependencies libraries to custom install prefix)
    • Support packages or project manifests (eg. with CMake++ with a JSON or YAML like FIPS and create on the fly CMake package configuration files for external project with a namespace (eg. link)
    • Analyze and generate external projects config file with the list of targets and options into a JSON or YAML file. (Would be useful to disable options incompatible with some platforms, (eg for iPhoneOS and Android builds, BLAS libraries are not all compatible)

    Questions:

    1. I prefer YAML formats as more human readable and more easy to connect with some other scripts (often Golang based for my part) but I could not make fully work the yaml function from the test function. Is it something that you intend to implement soon ? It would work perfectly with FIPS ^^ ?

    2. Would it be possible to have an example with CMake++ building an OpenCV project and some dependencies like Caffe for mobile without conflicting with the server version Caffe or tensorflow or tiny-dnn with your recent additions on package functions (link ? (more precisely I cannot get if it could manage some kind of build/install cache strategy like hunter per toolchains and prevent duplicate builds of dependencies like Protobuf for example but still be able to set custom args per platfroms ^^)

    3. Would it be possible to see such project build example with a cross-platform approach using toolchains from either Polly or FIPS with CMake++ ?

    4. Is it possible to create executable wrappers from a list of vcs uris and install their pre-requisiste ? (eg. install and wrap CppSharp requires a wrap around premake5, mono, xbuild and nuget in order to wrap CppSharp-Cli ? (eg link) (btw, I am working with an Apple laptop)

    Thanks for this awesome project Tobias ! Have an awesome week !

    Cheers, Richard

    opened by roscopecoltran 0
  • cmakepp errors on MacOSX + bonus questions

    cmakepp errors on MacOSX + bonus questions

    Hi,

    hope you are all well !

    I tried to build the example, described on your blog (link), and I got the following errors.

    1. eigen3 is not included
    2. several CMake Warning

    Errors:

      Cannot set "__ans": current scope has no parent.
    Call Stack (most recent call first):
      /opt/local/share/cmake-3.7/Modules/Compiler/Clang.cmake:7 (return)
      /opt/local/share/cmake-3.7/Modules/Compiler/AppleClang-CXX.cmake:1 (include)
      /opt/local/share/cmake-3.7/Modules/CMakeCXXInformation.cmake:25 (include)
      cmakepp.cmake:5706 (_project)
      CMakeLists.txt:26 (project)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    CMake Warning (dev) at cmakepp.cmake:11098 (set):
      Cannot set "__ans": current scope has no parent.
    Call Stack (most recent call first):
      /opt/local/share/cmake-3.7/Modules/Platform/Darwin-Clang.cmake:7 (return)
      /opt/local/share/cmake-3.7/Modules/Platform/Darwin-Clang-CXX.cmake:1 (include)
      /opt/local/share/cmake-3.7/Modules/Platform/Darwin-AppleClang-CXX.cmake:1 (include)
      /opt/local/share/cmake-3.7/Modules/CMakeCXXInformation.cmake:48 (include)
      cmakepp.cmake:5706 (_project)
      CMakeLists.txt:26 (project)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
    -- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    {
     "myproject":{
      "name":"myproject",
      "directory":"/Users/Luccio/cpp/cmakepp",
      "targets":{
       "name":"myexe",
       "project_name":"myproject"
      }
     }
    }
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /Users/Luccio/cpp/cmakepp/_builds
    Scanning dependencies of target myexe
    [ 50%] Building CXX object CMakeFiles/myexe.dir/main.cpp.o
    /Users/Luccio/cpp/cmakepp/main.cpp:3:10: fatal error: 'Eigen/Dense' file not found
    #include <Eigen/Dense>
             ^
    1 error generated.
    gmake[2]: *** [CMakeFiles/myexe.dir/build.make:63: CMakeFiles/myexe.dir/main.cpp.o] Error 1
    gmake[1]: *** [CMakeFiles/Makefile2:68: CMakeFiles/myexe.dir/all] Error 2
    gmake: *** [Makefile:84: all] Error 2
    

    CMakeLists.txt:

    cmake_minimum_required(VERSION 2.8.12)
    ## CMakeLists.txt for a simple project 
    set(current_dir "${CMAKE_CURRENT_SOURCE_DIR}")
    ## get cmakepp
    if(NOT EXISTS "${current_dir}/cmakepp.cmake")
      file(DOWNLOAD "https://github.com/toeb/cmakepp/releases/download/v0.3.1-alpha/cmakepp.cmake" "${current_dir}/cmakepp.cmake")
    endif()
    
    include("${current_dir}/cmakepp.cmake")
    
    if(NOT EXISTS ${current_dir}/dependencies/eigen3)
     message(STATUS "installing Eigen3 from bitbucket")
     pull_package(eigen/eigen?tag=3.1.0 ${current_dir}/dependencies/eigen3)
     ans(package_handle)
     if(NOT package_handle)
      message(FATAL_ERROR "could not pull Eigen3")
     endif()
     ## print the package information returned
     json_print(${package_handle})
    
     message(STATUS "${current_dir}/dependencies/eigen3")
    
    endif()
    
    ## from here on everything can be a normal cmakelists file
    project(myproject)
    
    include_directories("dependencies/eigen3")
    
    fwrite("main.cpp" "
    #include <iostream>
    #include <Eigen/Dense>
    using Eigen::MatrixXd;
    int main()
    {
      MatrixXd m(2,2);
      m(0,0) = 3;
      m(1,0) = 2.5;
      m(0,1) = -1;
      m(1,1) = m(1,0) + m(0,1);
      std::cout << m << std::endl;
    }
    ")
    add_executable(myexe "main.cpp")
    
    print_project_tree()
    print_targets()
    

    Is there any way to solve these issues ?

    Bonus questions:

    Did you ever thought or start to develop some toolchains management for cmakepp ?

    My use case is aimed for building cross-platform unity3d plugins for iOS, Android, WSA, MacOSX and Linux of CMake driven project (eg. Tensorflow)

    More precisely, it would be really cool to manage a list of toolchains like Polly and some dockerized transpilers like with Dockcross.

    It would help to create a template through cmake, as I would like to create a build bot to replace such bash scripts:

    #!/bin/bash
    
    ## ##################################################################################################################################
    # Copyright (c) 2017, Rosco Pecoltran
    # All rights reserved.
    ## ##################################################################################################################################
    
    set -e
    
    clear ## clear terminal screen
    pwd ## check current workdir
    
    ## #################################################################
    ## Project SDK name
    ## #################################################################
    
    if [ ! -z "$1" ]; then
        PROJECT_NAME="$1"  # Custom SDK name (eg. SnipAR in order to gather in on Unity3D project all packages build, per platforms)
    else
        echo "[Sniper] No arguments supplied for output SDK name"
        PROJECT_NAME="Eigen3" # Default output SDK name
    fi
    
    ## #################################################################
    ## Project CMake Arguments
    ## #################################################################
    
    PROJECT_CMAKE_ARGS_FILE=$(basename "$0" .sh) # filename to source inside the sniper bots ENV/CMake args for cross-compilation build with polly
    PROJECT_CMAKE_HOME="." # home directory hosting root CMakeLists.txt
    
    ## #################################################################
    ## Project Global Arguments
    ## #################################################################
    
    PROJECT_BUILD_TYPE="Release" # Release/Debug
    PROJECT_LIBRARY_TARGET="eigen3" # Target name, libname ouput
    
    ## #################################################################
    ## Project VCS settings
    ## #################################################################
    
    PROJECT_VCS_URL="https://github.com/hunter-packages/eigen"
    PROJECT_VCS_BRANCH="hunter-3.3.1"
    
    # notes: build package 
    # - common:
    #  - iOS (static libs)
    #    - Architectures: i386, x86_64
    #  - MacOSX (shared libs)
    #    - Architectures: i386, x86_64
    #  - Android (shared libs)
    #    - Architectures: armv7a, armv7a-neon, arm64-v8a, x86, x86-64, mips, mips64
    # - extras:
    #  - Apple Frameworks (shared libs): iOS, MacOSX
    
    ## #################################################################
    ## Project Sniper Bot - settings
    ## #################################################################
    
    SNIPER_BOTS_SCRIPT="bundle-unity3d.sh" # script filename to use for creating the new bundle of libraries
    
    # Prefix Path with All SNIPER Bots Scripts
    SNIPER_WORKDIR_DIR=$(pwd)
    SNIPER_BOTS_PREFIX_PATH="./scripts"
    SNIPER_BOTS_COMMAND="${SNIPER_BOTS_PREFIX_PATH}/${SNIPER_BOTS_SCRIPT}"
    chmod a+x ${SNIPER_BOTS_COMMAND}
    
    # Note: 
    #  - enable/disable global settings for those helepers, please check: ./config/_init_.sh
    SNIPER_BOTS_CONFIG_HELPERS_PREFIX_PATH="./config"
    SNIPER_BOTS_CONFIG_HELPERS_INIT="_init_.sh"
    
    # load global configuration settings for sniper bots dependencies (Polly, Hunter)
    . ${SNIPER_BOTS_CONFIG_HELPERS_PREFIX_PATH}/${SNIPER_BOTS_CONFIG_HELPERS_INIT}
    
    ## #################################################################
    ## project build common arguments
    ## #################################################################
    
    # common flags
    PROJECT_BUILD_EXAMPLES=OFF
    PROJECT_BUILD_TESTS=OFF
    PROJECT_BUILD_DOCS=OFF
    
    # libprotobuf-lite
    PROJECT_COMMON_BUILD_ARGS=\
    (
        "HUNTER_CONFIGURATION_TYPES=${PROJECT_BUILD_TYPE}"
        # build
        "EIGEN_BUILD_BTL=OFF"
        "EIGEN_BUILD_PKGCONFIG=ON"
        "EIGEN_DEFAULT_TO_ROW_MAJOR=OFF"
        "EIGEN_SPLIT_LARGE_TESTS=ON"
        # tests
        "EIGEN_FAILTEST=${PROJECT_BUILD_TESTS}"
        "BUILD_TESTING=${PROJECT_BUILD_DOCS}"
        "EIGEN_TEST_SSE2=OFF"
        "EIGEN_TEST_SSE3=OFF"
        "EIGEN_TEST_SSSE3=OFF"
        "EIGEN_TEST_SSE4_1=OFF"
        "EIGEN_TEST_SSE4_2=OFF"
        "EIGEN_TEST_AVX=OFF"
        "EIGEN_TEST_FMA=OFF"
        "EIGEN_TEST_AVX512=OFF"
        "EIGEN_TEST_F16C=OFF"
        "EIGEN_TEST_ALTIVEC=OFF"
        "EIGEN_TEST_VSX=OFF"
        "EIGEN_TEST_NEON=OFF"
        "EIGEN_TEST_NEON64=OFF"
        "EIGEN_TEST_ZVECTOR=OFF"
        "EIGEN_TEST_OPENMP=OFF"
        "EIGEN_TEST_SSE2=OFF"
        "EIGEN_TEST_NO_EXPLICIT_VECTORIZATION=OFF"
        "EIGEN_TEST_X87=OFF"
        "EIGEN_TEST_32BIT=OFF"
        "EIGEN_TEST_SYCL=OFF"
    )
    
    # Apple Frameworks - iOS and MacOSX 
    PROJECT_BUILD_ARGS_UNITY3D_APPLE_FRAMEWORKS=\
    (
        "BUILD_SHARED_LIBS=ON"
    )
    
    # PROJECT_PUBLIC_HEADERS_PREFIX_PATH=""
    
    # iOS armv7, arm64
    PROJECT_BUILD_ARGS_UNITY3D_APPLE_IOS=\
    (
        "BUILD_SHARED_LIBS=OFF"
    )
    
    # MacOSX i386, x86_64
    PROJECT_BUILD_ARGS_UNITY3D_APPLE_OSX=\
    (
        "BUILD_SHARED_LIBS=ON"
    )
    
    # Android arm
    PROJECT_BUILD_ARGS_UNITY3D_ANDROID=\
    (
        "BUILD_SHARED_LIBS=ON"
    )
    
    # Linux
    PROJECT_BUILD_ARGS_UNITY3D_LINUX=\
    (
        "BUILD_SHARED_LIBS=ON"
    )
    
    # Windows WSA / SDK8.1 / PhoneSDK8.1
    PROJECT_BUILD_ARGS_UNITY3D_WSA=\
    (
        "BUILD_SHARED_LIBS=ON"
    )
    
    ## #################################################################
    ## project build - active platforms/toolchains
    ## #################################################################
    
    SNIPER_BOT_QUEUE_DEV=(\
        # Apple
        UNITY3D_APPLE_OSX_FRAMEWORK=TRUE        
        UNITY3D_APPLE_IOS_FRAMEWORK=TRUE            
    )
    
    SNIPER_BOT_QUEUE=(\
        UNITY3D_APPLE_OSX_FRAMEWORK=TRUE
        UNITY3D_APPLE_MACOSX=TRUE
        UNITY3D_APPLE_IOS_FRAMEWORK=TRUE
        UNITY3D_APPLE_IOS=TRUE
        UNITY3D_ANDROID_ARMEABI_V7A_NEON=TRUE
        UNITY3D_ANDROID_ARMEABI_V7A=TRUE
        UNITY3D_ANDROID_ARM64_V8A=TRUE
        UNITY3D_ANDROID_X86=TRUE
        UNITY3D_ANDROID_X86_64=TRUE
        UNITY3D_ANDROID_MIPS=TRUE
        UNITY3D_ANDROID_MIPS64=TRUE
        UNITY3D_LINUX_X86=TRUE
        UNITY3D_LINUX_X86_64=TRUE
        UNITY3D_WSA_PHONESDK81_ARM=TRUE
        UNITY3D_WSA_PHONESDK81_X86=TRUE
        UNITY3D_WSA_SDK81_ARM=TRUE
        UNITY3D_WSA_SDK81_X86=TRUE
        UNITY3D_WSA_SDK81_X64=TRUE
        UNITY3D_WSA_UWP_ARM=TRUE
        UNITY3D_WSA_UWP_X86=TRUE
        UNITY3D_WSA_UWP_X64=TRUE
    )
    
    ## #################################################################
    ## Sniper BOT mode
    ## #################################################################
    
    if [ $# -eq 0 ]
      then
        echo "[Sniper] No arguments supplied"
    fi
    
    if [ ! -z "$2" ]; then
        PROJECT_ENV="$2"  # Custom SDK name (eg. SnipAR in order to gather in on Unity3D project all packages build, per platforms)
    else
        echo "[Sniper] No arguments supplied for bot actions mode"
        PROJECT_ENV="BOT_MODE" # Default output SDK name
    fi
    
    ## #################################################################
    ## project prepare and build
    ## #################################################################
    
    if [ "$2" == "ENV_MODE" ]; then
        echo "[Sniper] CMake arguments loaded..."
    else
        ${SNIPER_BOTS_COMMAND}  ${PROJECT_NAME} \
                                ${PROJECT_BUILD_TYPE} \
                                ${PROJECT_VCS_URL} \
                                ${PROJECT_VCS_BRANCH} \
                                ${PROJECT_CMAKE_ARGS_FILE} \
                                ${PROJECT_CMAKE_HOME} \
                                ${PROJECT_LIBRARY_TARGET} \
                                ${PROJECT_EXECUTABLE_TARGET}
    fi
    
    ## #################################################################
    ## project extra post-build commands
    ## #################################################################
    
    ## Copy output to a cache repository (eg. Hunter)
    ## Push output to github repository
    
    
    
    ## #################################################################
    ## output library integration / symbolification
    ## #################################################################
    
    ## Execute unit tests and re-symbolofication
    
    
    
    ## #################################################################
    ## project build reports and analysis
    ## #################################################################
    
    ## Check additional issues related to project or project forks
    
    
    #
    #
    #
    #### END ############################################################################################################################ END ####
    
    

    Have a great day !

    Cheers, Richard

    opened by roscopecoltran 0
Releases(v0.3.2-alpha)
Owner
Tobias Becker
Tobias Becker
Arduino CMake Build system

Arduino Cmake Example Project This is the Cmake project settings for the Arduino platform. You can use this project as an example to develop C++ progr

Francois Campbell 57 Oct 13, 2022
📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Setup-free CMake dependency management CPM.cmake is a CMake script that adds dependency management capabilities to CMake. It's built as a thin wrapper

CPM.cmake 1.5k Nov 25, 2022
CMake checks cache helper modules – for fast CI CMake builds!

cmake-checks-cache Cross platform CMake projects do platform introspection by the means of "Check" macros. Have a look at CMake's How To Write Platfor

Cristian Adam 64 Nov 18, 2022
CMake scripts for painless usage of SuiteSparse+METIS from Visual Studio and the rest of Windows/Linux/OSX IDEs supported by CMake

CMake scripts for painless usage of Tim Davis' SuiteSparse (CHOLMOD,UMFPACK,AMD,LDL,SPQR,...) and METIS from Visual Studio and the rest of Windows/Lin

Jose Luis Blanco-Claraco 394 Nov 24, 2022
cmake-font-lock - Advanced, type aware, highlight support for CMake

cmake-font-lock - Advanced, type aware, highlight support for CMake

Anders Lindgren 39 Oct 2, 2022
cmake-avr - a cmake toolchain for AVR projects

cmake-avr - a cmake toolchain for AVR projects Testing the example provided The toolchain was created and tested within the following environment: Lin

Matthias Kleemann 162 Oct 24, 2022
Make CMake less painful when trying to write Modern Flexible CMake

Izzy's eXtension Modules IXM is a CMake library for writing Modern flexible CMake. This means: Reducing the amount of CMake written Selecting reasonab

IXM 107 Sep 1, 2022
CMake module to enable code coverage easily and generate coverage reports with CMake targets.

CMake-codecov CMake module to enable code coverage easily and generate coverage reports with CMake targets. Include into your project To use Findcodec

HPC 82 Oct 25, 2022
unmaintained - CMake module to activate certain C++ standard, feature checks and appropriate automated workarounds - basically an improved version of cmake-compile-features

Compatibility This library provides an advanced target_compile_features() and write_compiler_detection_header(). The problem with those is that they a

Jonathan Müller 72 Apr 14, 2022
[CMake] [BSD-2] CMake module to find ICU

FindICU.cmake A CMake module to find International Components for Unicode (ICU) Library Note that CMake, since its version 3.7.0, includes a FindICU m

julp 29 Nov 2, 2022
curl cmake module libcurl build with msvc x86

curl-msvc Infomation curl cmake module libcurl build with MSVC10.0 arch (x86 | i386) source from https://github.com/curl/curl tags: curl-7_79_1 Usage

Jason Payne 0 May 16, 2022
Project to enable using CMake from a Maven build.

CMake-Maven-Project Introduction A Maven project for the CMake build system. It can be used by including it as a plugin within your Maven project's po

null 60 Nov 14, 2022
CMake and other scripts to help build process of FlyEM software

The BuildEM System The buildem repo is a modular CMake-based system that leverages CMake's ExternalProject to simplify and automate a complex build pr

null 27 Jun 9, 2022
A fast build system that encourages the creation of small, reusable modules over a variety of platforms and languages.

Buck Buck is a build tool. To see what Buck can do for you, check out the documentation at http://buck.build/. Installation Since Buck is used to buil

Facebook 8.4k Nov 25, 2022
Tundra is a code build system that tries to be accurate and fast for incremental builds

Tundra, a build system Tundra is a high-performance code build system designed to give the best possible incremental build times even for very large s

Andreas Fredriksson 393 Nov 19, 2022
a small build system with a focus on speed

Ninja Ninja is a small build system with a focus on speed. https://ninja-build.org/ See the manual or doc/manual.asciidoc included in the distribution

null 8.8k Nov 25, 2022
muon is an implementation of the meson build system in C with minimal dependencies.

muon muon is an implementation of the meson build system in C with minimal dependencies. Non-features bug-for-bug compatibility with meson. In fact, m

Stone Tickle 50 Nov 17, 2022
A basic build system for the Skript scripting language.

skib A basic build system for the Skript scripting language. Features #include other files recursively #define preprocessor symbols and macros Usage #

Daniel 1 Jun 27, 2022
Improved build system generator for CPython C, C++, Cython and Fortran extensions

scikit-build Improved build system generator for CPython C/C++/Fortran/Cython extensions. Better support is available for additional compilers, build

null 371 Nov 23, 2022