File: README.rst

package info (click to toggle)
cmake-format 0.6.13-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,436 kB
  • sloc: python: 16,990; makefile: 14
file content (646 lines) | stat: -rw-r--r-- 22,387 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
============
cmake format
============

.. image:: https://travis-ci.com/cheshirekow/cmake_format.svg?branch=master
    :target: https://travis-ci.com/cheshirekow/cmake_format

.. image:: https://readthedocs.org/projects/cmake-format/badge/?version=latest
    :target: https://cmake-format.readthedocs.io

The ``cmake-format`` project provides Quality Assurance (QA) tools
for ``cmake``:


* ``cmake-annotate`` can generate pretty HTML from your listfiles

* ``cmake-format`` can format your listfiles nicely so that they don't
  look like crap.

* ``cmake-lint`` can check your listfiles for problems

* ``ctest-to`` can parse a ctest output tree and translate it into a
  more structured format (either JSON or XML).

------------
Installation
------------

Install from ``pypi`` using ``pip``::

    pip install cmakelang

Or see the `online documentation`__ for additional options.

.. __: https://cmake-format.readthedocs.io/en/latest/installation.html

------------
Integrations
------------

* There is an official `vscode extension`__
* Someone also created a `sublime plugin`__
* You can add ``cmake-format`` to your ``pre-commit`` configuration__

.. __: https://marketplace.visualstudio.com/items?itemName=cheshirekow.cmake-format
.. __: https://packagecontrol.io/packages/CMakeFormat
.. __: https://cmake-format.readthedocs.io/en/latest/installation.html#pre-commit

-----
Usage
-----

.. dynamic: format-usage-short-begin

.. code:: text

    usage:
    cmake-format [-h]
                 [--dump-config {yaml,json,python} | -i | -o OUTFILE_PATH]
                 [-c CONFIG_FILE]
                 infilepath [infilepath ...]

    Parse cmake listfiles and format them nicely.

    Formatting is configurable by providing a configuration file. The configuration
    file can be in json, yaml, or python format. If no configuration file is
    specified on the command line, cmake-format will attempt to find a suitable
    configuration for each ``inputpath`` by checking recursively checking it's
    parent directory up to the root of the filesystem. It will return the first
    file it finds with a filename that matches '\.?cmake-format(.yaml|.json|.py)'.

    cmake-format can spit out the default configuration for you as starting point
    for customization. Run with `--dump-config [yaml|json|python]`.

    positional arguments:
      infilepaths

    optional arguments:
      -h, --help            show this help message and exit
      -v, --version         show program's version number and exit
      -l {error,warning,info,debug}, --log-level {error,warning,info,debug}
      --dump-config [{yaml,json,python}]
                            If specified, print the default configuration to
                            stdout and exit
      --dump {lex,parse,parsedb,layout,markup}
      --no-help             When used with --dump-config, will omit helptext
                            comments in the output
      --no-default          When used with --dump-config, will omit any unmodified
                            configuration value.
      -i, --in-place
      --check               Exit with status code 0 if formatting would not change
                            file contents, or status code 1 if it would
      -o OUTFILE_PATH, --outfile-path OUTFILE_PATH
                            Where to write the formatted file. Default is stdout.
      -c CONFIG_FILES [CONFIG_FILES ...], --config-files CONFIG_FILES [CONFIG_FILES ...]
                            path to configuration file(s)


.. dynamic: format-usage-short-end

.. dynamic: lint-usage-short-begin

.. code:: text

    usage:
    cmake-lint [-h]
               [--dump-config {yaml,json,python} | -o OUTFILE_PATH]
               [-c CONFIG_FILE]
               infilepath [infilepath ...]

    Check cmake listfile for lint

    positional arguments:
      infilepaths

    optional arguments:
      -h, --help            show this help message and exit
      -v, --version         show program's version number and exit
      -l {error,warning,info,debug}, --log-level {error,warning,info,debug}
      --dump-config [{yaml,json,python}]
                            If specified, print the default configuration to
                            stdout and exit
      -o OUTFILE_PATH, --outfile-path OUTFILE_PATH
                            Write errors to this file. Default is stdout.
      --no-help             When used with --dump-config, will omit helptext
                            comments in the output
      --no-default          When used with --dump-config, will omit any unmodified
                            configuration value.
      --suppress-decorations
                            Suppress the file title decoration and summary
                            statistics
      -c CONFIG_FILES [CONFIG_FILES ...], --config-files CONFIG_FILES [CONFIG_FILES ...]
                            path to configuration file(s)


.. dynamic: lint-usage-short-end

-------------
Configuration
-------------

``cmake-format`` accepts configuration files in yaml, json, or python format.
An example configuration file is given `in the online documentation`__.
Providing the structure of your custom commands will help ``cmake-format`` to
break them up in a pleasant way, and will help `cmake-lint` detect improper
usages of them.

.. __: https://cmake-format.readthedocs.io/en/latest/configuration.html

An example short configuration file in python format is:

.. code:: python

    # -----------------------------
    # Options effecting formatting.
    # -----------------------------
    with section("format"):

      # How wide to allow formatted cmake files
      line_width = 80

      # How many spaces to tab for indent
      tab_size = 2

      # If true, separate flow control names from their parentheses with a space
      separate_ctrl_name_with_space = False

      # If true, separate function names from parentheses with a space
      separate_fn_name_with_space = False

      # If a statement is wrapped to more than one line, than dangle the closing
      # parenthesis on its own line.
      dangle_parens = False

You may specify a path to one or more configuration files with the
``--config-file`` command line option. Otherwise, ``cmake-format`` will search
the ancestry of each ``infilepath`` looking for a configuration file to use.
If no configuration file is found it will use sensible defaults.

A automatically detected configuration files may have any name that matches
``\.?cmake-format(.yaml|.json|.py)``.

If you'd like to create a new configuration file, ``cmake-format`` can help
by dumping out the default configuration in your preferred format. You can run
``cmake-format --dump-config [yaml|json|python]`` to print the default
configuration ``stdout`` and use that as a starting point.

.. dynamic: features-begin

-------
Markup
-------

``cmake-format`` is for the exceptionally lazy. It will even format your
comments for you. It will reflow your comment text to within the configured
line width. It also understands a very limited markup format for a couple of
common bits.

**rulers**: A ruler is a line which starts with and ends with three or more
non-alphanum or space characters::

    # ---- This is a Ruler ----
    # cmake-format will know to keep the ruler separated from the
    # paragraphs around it. So it wont try to reflow this text as
    # a single paragraph.
    # ---- This is also a Ruler ---


**list**: A list is started on the first encountered list item, which starts
with a bullet character (``*``) followed by a space followed by some text.
Subsequent lines will be included in the list item until the next list item
is encountered (the bullet must be at the same indentation level). The list
must be surrounded by a pair of empty lines. Nested lists will be formatted in
nested text::

    # here are some lists:
    #
    # * item 1
    # * item 2
    #
    #   * subitem 1
    #   * subitem 2
    #
    # * second list item 1
    # * second list item 2

**enumerations**: An enumeration is similar to a list but the bullet character
is some integers followed by a period. New enumeration items are detected as
long as either the first digit or the punctuation lines up in the same column
as the previous item. ``cmake-format`` will renumber your items and align their
labels for you::

    # This is an enumeration
    #
    #   1. item
    #   2. item
    #   3. item

**fences**: If you have any text which you do not want to be formatted you can
guard it with a pair of fences. Fences are three or more tilde characters::

    # ~~~
    # This comment is fenced
    #   and will not be formatted
    # ~~~

Note that comment fences guard reflow of *comment text*, and not cmake code.
If you wish to prevent formatting of cmake, code, see below. In addition to
fenced-literals, there are three other ways to preserve comment text from
markup and/or reflow processing:

* The ``--first-comment-is-literal`` configuration option will exactly preserve
  the first comment in the file. This is intended to preserve copyright or
  other formatted header comments.
* The ``--literal-comment-pattern`` configuration option allows for a more
  generic way to identify comments which should be preserved literally. This
  configuration takes a regular expression pattern.
* The ``--enable-markup`` configuration option globally enables comment markup
  processing. It defaults to true so set it to false if you wish to globally
  disable comment markup processing. Note that trailing whitespace is still
  chomped from comments.

--------------------------
Disable Formatting Locally
--------------------------

You can locally disable and enable code formatting by using the special
comments ``# cmake-format: off`` and ``# cmake-format: on``.

-------------------
Sort Argument Lists
-------------------

Starting with version `0.5.0`, ``cmake-format`` can sort your argument lists
for you. If the configuration includes ``autosort=True`` (the default), it
will replace::

    add_library(foobar STATIC EXCLUDE_FROM_ALL
                sourcefile_06.cc
                sourcefile_03.cc
                sourcefile_02.cc
                sourcefile_04.cc
                sourcefile_07.cc
                sourcefile_01.cc
                sourcefile_05.cc)

with::

    add_library(foobar STATIC EXCLUDE_FROM_ALL
                sourcefile_01.cc
                sourcefile_02.cc
                sourcefile_03.cc
                sourcefile_04.cc
                sourcefile_05.cc
                sourcefile_06.cc
                sourcefile_07.cc)

This is implemented for any argument lists which the parser knows are
inherently sortable. This includes the following cmake commands:

* ``add_library``
* ``add_executable``

For most other cmake commands, you can use an annotation comment to hint to
``cmake-format`` that the argument list is sortable. For instance::

    set(SOURCES
        # cmake-format: sortable
        bar.cc
        baz.cc
        foo.cc)

Annotations can be given in a line-comment or a bracket comment. There is a
long-form and a short-form for each. The acceptable formats are:

+-----------------+-------+------------------------------+
| Line Comment    | long  | ``# cmake-format: <tag>``    |
+-----------------+-------+------------------------------+
| Line Comment    | short | ``# cmf: <tag>``             |
+-----------------+-------+------------------------------+
| Bracket Comment | long  | ``#[[cmake-format: <tag>]]`` |
+-----------------+-------+------------------------------+
| Bracket Comment | short | ``#[[cmf: <tag>]]``          |
+-----------------+-------+------------------------------+

In order to annotate a positional argument list as sortable, the acceptable
tags are: ``sortable`` or ``sort``. For the commands listed above where
the positinal argument lists are inherently sortable, you can locally disable
sorting by annotating them with ``unsortable`` or ``unsort``. For example::

    add_library(foobar STATIC
                # cmake-format: unsort
                sourcefile_03.cc
                sourcefile_01.cc
                sourcefile_02.cc)

Note that this is only needed if your configuration has enabled ``autosort``,
and you can globally disable sorting by making setting this configuration to
``False``.


---------------
Custom Commands
---------------

Due to the fact that cmake is a macro language, `cmake-format` is, by
necessity, a *semantic* source code formatter. In general it tries to make
smart formatting decisions based on the meaning of arguments in an otherwise
unstructured list of arguments in a cmake statement. `cmake-format` can
intelligently format your custom commands, but you will need to tell it how
to interpret your arguments.

Currently, you can do this by adding your command specifications to the
`additional_commands` configuration variables, e.g.:

.. code::

    # Additional FLAGS and KWARGS for custom commands
    additional_commands = {
      "foo": {
        "pargs": 2,
        "flags": ["BAR", "BAZ"],
        "kwargs": {
          "HEADERS": '*',
          "SOURCES": '*',
          "DEPENDS": '*',
        }
      }
    }

The format is a nested dictionary mapping statement names (dictionary keys)
to `argument specifications`__. For the example specification above, the
custom command would look something like this:

.. code::

   foo(hello world
       HEADERS a.h b.h c.h d.h
       SOURCES a.cc b.cc c.cc d.cc
       DEPENDS flub buzz bizz
       BAR BAZ)


.. __: https://cmake-format.rtfd.io/en/latest/custom_parsers.html
.. dynamic: features-end

---------------------------------
Reporting Issues and Getting Help
---------------------------------

If you encounter any bugs or regressions or if ``cmake-format`` doesn't behave
in the way that you expect, please post an issue on the
`github issue tracker`_. It is especially helpful if you can provide cmake
listfile snippets that demonstrate any issues you encounter.

.. _`github issue tracker`: https://github.com/cheshirekow/cmakelang/issues

You can also join the ``#cmake-format`` channel on our `discord server`_.

.. _`discord server`: https://discord.gg/NgjwyPy


----------
Developers
----------

If you want to hack on ``cmake-format``, please see the `documentation`__ for
contribution rules and guidelines.

.. __: https://cmake-format.rtfd.io/en/latest/contributing.html

-------
Example
-------

Will turn this:

.. dynamic: example-in-begin

.. code:: cmake

    # The following multiple newlines should be collapsed into a single newline




    cmake_minimum_required(VERSION 2.8.11)
    project(cmakelang_test)

    # This multiline-comment should be reflowed
    # into a single comment
    # on one line

    # This comment should remain right before the command call.
    # Furthermore, the command call should be formatted
    # to a single line.
    add_subdirectories(foo bar baz
      foo2 bar2 baz2)

    # This very long command should be wrapped
    set(HEADERS very_long_header_name_a.h very_long_header_name_b.h very_long_header_name_c.h)

    # This command should be split into one line per entry because it has a long argument list.
    set(SOURCES source_a.cc source_b.cc source_d.cc source_e.cc source_f.cc source_g.cc source_h.cc)

    # The string in this command should not be split
    set_target_properties(foo bar baz PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall -Wextra")

    # This command has a very long argument and can't be aligned with the command
    # end, so it should be moved to a new line with block indent + 1.
    some_long_command_name("Some very long argument that really needs to be on the next line.")

    # This situation is similar but the argument to a KWARG needs to be on a
    # newline instead.
    set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-sign-compare -Wno-unused-parameter -xx")

    set(HEADERS header_a.h header_b.h # This comment should
                                      # be preserved, moreover it should be split
                                      # across two lines.
        header_c.h header_d.h)


    # This part of the comment should
    # be formatted
    # but...
    # cmake-format: off
    # This bunny should remain untouched:
    # .   _ ∩
    #   レヘヽ| |
    #     (・x・)
    #    c( uu}
    # cmake-format: on
    #          while this part should
    #          be formatted again

    # This is a paragraph
    #
    # This is a second paragraph
    #
    # This is a third paragraph

    # This is a comment
    # that should be joined but
    # TODO(josh): This todo should not be joined with the previous line.
    # NOTE(josh): Also this should not be joined with the todo.

    if(foo)
    if(sbar)
    # This comment is in-scope.
    add_library(foo_bar_baz foo.cc bar.cc # this is a comment for arg2
                                          # this is more comment for arg2, it should be joined with the first.
        baz.cc) # This comment is part of add_library

    other_command(some_long_argument some_long_argument) # this comment is very long and gets split across some lines

    other_command(some_long_argument some_long_argument some_long_argument) # this comment is even longer and wouldn't make sense to pack at the end of the command so it gets it's own lines
    endif()
    endif()


    # This very long command should be broken up along keyword arguments
    foo(nonkwarg_a nonkwarg_b HEADERS a.h b.h c.h d.h e.h f.h SOURCES a.cc b.cc d.cc DEPENDS foo bar baz)

    # This command uses a string with escaped quote chars
    foo(some_arg some_arg "This is a \"string\" within a string")

    # This command uses an empty string
    foo(some_arg some_arg "")

    # This command uses a multiline string
    foo(some_arg some_arg "
        This string is on multiple lines
    ")

    # No, I really want this to look ugly
    # cmake-format: off
    add_library(a b.cc
      c.cc         d.cc
               e.cc)
    # cmake-format: on

.. dynamic: example-in-end

into this:

.. dynamic: example-out-begin

.. code:: cmake

    # The following multiple newlines should be collapsed into a single newline

    cmake_minimum_required(VERSION 2.8.11)
    project(cmakelang_test)

    # This multiline-comment should be reflowed into a single comment on one line

    # This comment should remain right before the command call. Furthermore, the
    # command call should be formatted to a single line.
    add_subdirectories(foo bar baz foo2 bar2 baz2)

    # This very long command should be wrapped
    set(HEADERS very_long_header_name_a.h very_long_header_name_b.h
                very_long_header_name_c.h)

    # This command should be split into one line per entry because it has a long
    # argument list.
    set(SOURCES
        source_a.cc
        source_b.cc
        source_d.cc
        source_e.cc
        source_f.cc
        source_g.cc
        source_h.cc)

    # The string in this command should not be split
    set_target_properties(foo bar baz PROPERTIES COMPILE_FLAGS
                                                 "-std=c++11 -Wall -Wextra")

    # This command has a very long argument and can't be aligned with the command
    # end, so it should be moved to a new line with block indent + 1.
    some_long_command_name(
      "Some very long argument that really needs to be on the next line.")

    # This situation is similar but the argument to a KWARG needs to be on a newline
    # instead.
    set(CMAKE_CXX_FLAGS
        "-std=c++11 -Wall -Wno-sign-compare -Wno-unused-parameter -xx")

    set(HEADERS
        header_a.h header_b.h # This comment should be preserved, moreover it should
                              # be split across two lines.
        header_c.h header_d.h)

    # This part of the comment should be formatted but...
    # cmake-format: off
    # This bunny should remain untouched:
    # .   _ ∩
    #   レヘヽ| |
    #     (・x・)
    #    c( uu}
    # cmake-format: on
    # while this part should be formatted again

    # This is a paragraph
    #
    # This is a second paragraph
    #
    # This is a third paragraph

    # This is a comment that should be joined but
    # TODO(josh): This todo should not be joined with the previous line.
    # NOTE(josh): Also this should not be joined with the todo.

    if(foo)
      if(sbar)
        # This comment is in-scope.
        add_library(
          foo_bar_baz
          foo.cc bar.cc # this is a comment for arg2 this is more comment for arg2,
                        # it should be joined with the first.
          baz.cc) # This comment is part of add_library

        other_command(
          some_long_argument some_long_argument) # this comment is very long and
                                                 # gets split across some lines

        other_command(
          some_long_argument some_long_argument some_long_argument) # this comment
                                                                    # is even longer
                                                                    # and wouldn't
                                                                    # make sense to
                                                                    # pack at the
                                                                    # end of the
                                                                    # command so it
                                                                    # gets it's own
                                                                    # lines
      endif()
    endif()

    # This very long command should be broken up along keyword arguments
    foo(nonkwarg_a nonkwarg_b
        HEADERS a.h b.h c.h d.h e.h f.h
        SOURCES a.cc b.cc d.cc
        DEPENDS foo
        bar baz)

    # This command uses a string with escaped quote chars
    foo(some_arg some_arg "This is a \"string\" within a string")

    # This command uses an empty string
    foo(some_arg some_arg "")

    # This command uses a multiline string
    foo(some_arg some_arg "
        This string is on multiple lines
    ")

    # No, I really want this to look ugly
    # cmake-format: off
    add_library(a b.cc
      c.cc         d.cc
               e.cc)
    # cmake-format: on

.. dynamic: example-out-end