Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
CMake
CMake
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 3,226
    • Issues 3,226
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 10
    • Merge Requests 10
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • External Wiki
    • External Wiki
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • CMake
  • CMakeCMake
  • Issues
  • #19889

Closed
Open
Opened Oct 28, 2019 by stryku@strykuContributor

CMakeSL - proposal of a new scripting language for CMake

Proposal about using CMakeSL (CMake Scripting Language) as an alternative CMake's scripting language.

Hello, I've been working on an alternative scripting language for CMake and I'd like to propose merging it into the CMake codebase.

Table of Contents

  • Proposal about using CMakeSL (CMake Scripting Language) as an alternative CMake's scripting language.
  • Purpose of this proposal
  • Quick links
  • tl;dr list of pros and cons of the language
    • Pros
    • Cons
  • Integration with CMake codebase
  • CMakeSL
    • Current state of CMakeSL
    • Hello world
    • High-level design
    • C++ish style
    • Mixing CMakeSL with 'old' CMake scripts
    • Tools
    • Tests
  • Why not use any of the ready made languages
  • Work to be done before the eventual merge
  • Summary
  • Thanks

Purpose of this proposal

My goal is to present the approach that I took with all its pros and cons, and explain why I think it's a good way for the future of CMake.

The thing that I'd not want to spend too much time on is CMakeSL's API. In this proposal and in CMakeSL's documentation you'll find code like cmake::minimum_required(cmake::version(3, 14, 4)); where the cmake:: seems to be a boilerplate, the code looks verbose etc. I want to explicitly point out that it's only an API and, if there will be a need, it can be very easily changed.

Quick links

  • CMakeSL repo: https://github.com/stryku/cmakesl
  • Language user guide: https://github.com/stryku/cmakesl/blob/master/doc/UserGuide.md
  • Builtin stuff documentation files: https://github.com/stryku/cmakesl/tree/master/examples. Documentation is generated from them, using Doxygen.
  • Example usage of CMakeSL and its tools: https://github.com/stryku/cmakesl/tree/master/examples (for more information about the tools, see the tools section in README)

tl;dr list of pros and cons of the language

Pros

  • Easy to pick up by people with C/C++ (and similar) background.
  • C++ tools like clang-format and Doxygen work out-of-the-box.
  • Easy to divide into smaller files.
  • Can be mixed with 'old' CMake scripts (at add_subdirectory() level), which eases migration process.
  • Features like classes, namespaces, modularity, type safety and more, which help to work with huge projects.
  • It's easy to write tools that provide semantic information: indexer and syntax completion, which help IDE creators.

Cons

  • Probably not the easiest way to write simple things. That, actually, depends on what API CMakeSL would eventually have.
  • C++ish syntax can be verbose.

Integration with CMake codebase

Here's a high-level diagram of CMakeSL and how it's integrated with CMake codebase.

CMakeSL

CMakeSL bases on CMake 3.14 (that was the latest version when I started working on it). You can find forked repo here: https://github.com/stryku/cmake_for_cmakesl. All required changes are on cmakesl branch. A good starting point to check out is the cmCMakeFacade class. That's the interface between CMakeSL and complex CMake systems.

CMakeSL

CMakeSL is basically a set of libraries that implement a statically typed scripting language. The scripting language is (using some integration code) used by CMake to execute CMakeLists.cmsl scripts. The libraries are statically linked to the cmake binary, so the result is a regular cmake binary with 'old' CMake and CMakeSL support. In the script you can find how to build CMake with CMakeSL support.

It is implemented in C++17 and a little of python3.

Current state of CMakeSL

CMakeSL is advanced enough to build itself (without generating documentation). See CMakeLists.cmsl files in the repo.

Hello world

int main()
{
    cmake::minimum_required(cmake::version(3, 14, 3));

    auto hello_world = cmake::project("Hello world");

    auto sources = { "main.cpp" };
    hello_world.add_executable("hw_exec", sources);

    return 0;
}

High-level design

The only thing that CMakeSL is supposed to change in a CMake User's life is how they write CMake scripts. CMakeSL is a scripting language and the scripting language only. All well known CMake's concepts like targets, modules, exporting etc. are supposed to be preserved. You can think of CMakeSL as a thin layer, an API to complex CMake systems.

The only stage of CMake usage that CMakeSL affects is the configuration step. The generation step, all the already supported generators, building and other CMake features remain the same.

C++ish style

You hate it or you love it. I know that a lot of people don't like it and I know that a lot of people complain about imperative paradigm. CMakeSL is highly inspired by C++. It looks and works a lot like C++. It provides well known concepts like types (including builtin generics, e.g. list<T>), variables, references, functions, classes with members and methods, namespaces and more. Here's why:

  • A lot of C/C++ project uses CMake - If user comes from C/C++ or similar background, it'll be very easy to they to pick up the CMakeSL language, read and maintain its code. Additionally, it's easier to switch between C/C++ and CMakeSL files/tasks.
  • In C/C++ projects it's almost certain that there is integrated code formatter and other tools that works with C/C++ language. Thanks to the fact that CMakeSL looks almost exactly like subset of C++, all C/C++ tools, that don't require semantic information, work with CMakeSL files as well. An example can be the CMakeSL repository itself. All *.cmsl files there are formatted using clang-format, with a style got from the .clang-format file - the very same file that is used to format C++ code in the repository. Another example can be CMakeSL's builtin stuff documentation. All its files are under doc/builtin directory. There are files that document all the builtin types and namespaces. The documentation is generated using Doxygen. Doxygen also works with regular CMakeSL files.

The whole CMakeSL machinery seems to be an overkill for such a simple task as writing a couple of scripts that instruct CMake how to build a project. Well, that's partially right. It seems complex and unnecessary if you think about the hello world example or a one-executable project. But, CMakeSL aims to make doing simple tasks simple, that's for sure. Furthermore, it provides features like functions, classes, namespaces, modularity, type safety and more, which make it powerful enough to be clear and elegant in huge projects, with thousands of lines of CMakeSL code.

Mixing CMakeSL with 'old' CMake scripts

CMakeSL scripts can be mixed with 'old' CMake scripts at a directory level. You can NOT mix them in one file or even include() 'old' CMake module in a CMakeSL script.

On the other hand, in a CMakeSL script you CAN call add_subdirectory() with a CMakeLists.txt written in 'old' CMake. In the CMakeSL repo you can see an example of such. In the root CMakeLists.cmsl file, there is an add_subdirectory call that adds external/googletest subdirectory. Of course the googletest library doesn't provie CMakeSL scripts. It provides 'old' CMakeLists.txt. The gtest and gmock libraries created there are later on used in tests, in CMakeLists.cmsl scripts. Such behavior mitigates eventual migration of a given project, form 'old' CMake to CMakeSL. You don't need to migrate the whole project at once. You migrate a directory after directory, which eases the process.

It works the other way as well. In 'old' CMakeLists.txt you can call add_subdirectory() with a script implemented in CMakeSL.

Tools

While C/C++ tools that don't require semantic information (e.g. clang-format, Doxygen) work out-of-the-box, tools like clang code completion can not be used just like that. Because of that, CMakeSL brings two tools that provide CMakeSL's code semantic information. Indexer and code completion. They are implemented in cmsl_tools library. It has C language interface, so it can be used practically everywhere. See the tools section in README for more info.

Tests

Every CMakeSL library has automated tests. They are run on CI. Additionally, Clang's AddressSanitizer, LeakSanitizer and UndefinedBehaviorSanitizer don't complain (they are not integrated on CI yet).

Why not use any of the ready made languages

That's a very good question that I heard a lot. I agree that using an already existing language would be and option, but I think that it'd be an option in the short term. Look, CMake has been here for almost 20 years. It has a great community. It's been used by huge projects and companies. More projects are migrating to CMake, e.g. Qt. In short, it seems that CMake is going to be used for a long, long time. Which is great, of course, but when you're in a perspective of a couple of decades of project maintaining, you want to keep as many parts of the project as possible in your garden. I believe creating and maintaining scripting language will pay-off in the long term. That's why I designed and wrote CMakeSL without a big list of dependencies and requirements. It's relatively easy to embed CMakeSL into the existing CMake codebase.

Work to be done before the eventual merge

  • The most basic one is the coding style. CMakeSL has different from the rest of CMake. It would need to be aligned.
  • Refactor of the integration code. The code at the cmake_for_cmakesl/cmakesl branch.
  • Review of the CMakeSL code. I've been implementing it basically on my own, without a second pair of reviewing eyes. I believe there is a lot of room for improvement.
  • Rewrite Doxygen docs to Sphinx.
  • C++17 is required, so CI would need to be updated.
  • Test compilation on more architectures and compilers.

Summary

I think CMakeSL, thanks to its features and compatibility with a lot of C/C++ tools, would be a step in the right direction of CMake life.

I'm open for discussion about any aspect of the project and I'm very curious what do you think about all this.

Thanks

I'd like to thank to Bartosz Duszel, Piotr Płaza, Stanisław Kubiak and Wojciech Stróżyński for help with this proposal (:

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: cmake/cmake#19889