cheshirekow / cmake_format Goto Github PK
View Code? Open in Web Editor NEWSource code formatter for cmake listfiles.
License: GNU General Public License v3.0
Source code formatter for cmake listfiles.
License: GNU General Public License v3.0
Looks like a very promising project! I tried to install using pip install cmake_format
, but got this error message:
(.venv) c:\home\simulator\dchipset>pip install --user cmake_format
Collecting cmake_format
Downloading <local pypi proxy path>/cmake_format-0.2.0.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "C:\Users\jce\AppData\Local\Temp\pip-build-1yx3c08l\cmake-format\setup.py", line 4, in <module>
long_description = infile.read()
File "C:\Python36\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x8d in position 3710: character maps to <undefined>
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\jce\AppData\Local\Temp\pip-build-1yx3c08l\cmake-format\
Maybe it's because the README.rst
file is a symbolic link, which is not really supported on Windows.
For commands with many keyword arguments, it can be nice to align the values to the keywords like this:
some_command(
KEYWORD arg
MULTI_KEYWORD arg
arg)
Where values are aligned to indentation levels. Combined with #5, it could look like this:
some_command(
KEYWORD
arg
MULTI_KEYWORD
arg
arg)
The MULTI_KEYWORD
arguments could also be collapsed to a single line following line length limits.
I'm trying to use the formatter with vim-autoformat and I'm not seeing what I'm doing wrong.
Error
Formatter cmake_format has errors: b'Traceback (most recent call last):\n File "/usr/bin/cmake-format", line 11, in <module>\n load_entry_point(\'cmake-format==0.3.5\', \'console_scripts\', \'cmake-format\')()\n File "/usr/li
b/python3.6/site-packages/cmake_format/__main__.py", line 243, in main\n ("if more than one input file is specified, then formatting must be done"\nAssertionError: if more than one input file is specified, then formatting must
be done in-place or written to stdout\n'
The lines in init.vim
let g:formatdef_cmake_format = '"cmake-format --dangle-parens true --line-ending unix --tab-size 0"'
let g:formatters_cmake = ['cmake_format']
I've tried manually running it from the terminal with the same command and on the same file, and it writes to stdout as expected.
Side-note, is --tab-size 0
correct to use tabs instead of spaces? I didn't see anything mentioning tabs/spaces, only that it controlled the number of spaces used.
Some ways I've seen it done is..
--use-tabs
option that doesn't take input--use-tabs
option that takes a true
or false
--tab-size
is set to 0
I'd say either 1 or 2 are good choices, because then --tab-size
can still be used for indent level, just with tabs instead of spaces.
Ref #30 (comment)
I have noticed some strange behavior when formatting commands with long arguments. When formatting this example CMakeLists.txt, the output I get is:
# Normal wrapping
message(FATAL_ERROR
"82 character line -----------------------------------------")
# Abnormal wrapping
message(FATAL_ERROR
"81 character line ----------------------------------------"
)
message(
FATAL_ERROR
"100 character line ----------------------------------------------------------"
) # Closing parenthesis is indented one space!
message(
"100 character line ----------------------------------------------------------------------"
) # Closing parenthesis is indented one space!
I am using version 0.3.2 with the default formatting settings.
Hello. Found another bug related to comments. Pretty self-explanatory from the lines below.
Input:
if(True) #Comment
message(STATUS "nanana")
endif() #ending comment
Output:
if(True) # Comment
message(STATUS "nanana")
endif()
Expected:
if(True) # Comment
message(STATUS "nanana")
endif() # ending comment
The funny thing is that this works:
self.do_format_test("""\
if(True) #Comment
message(STATUS "nanana")
endif(True) #ending comment
""", """\
if(True) # Comment
message(STATUS "nanana")
endif(True) # ending comment
""")
Create a file test.cmake
with the following content
set (answer
42 # comment
)
Run cmake-format
cmake-format test.cmake
The command cmake-format
prints a nicely formatted version of the given CMake code.
The command produces the following syntactically incorrect code:
set(answer 42 # comment)
.
This may be a different aspect of issues #46 and #47
If a comment is already indented, cmake-format seems to consider it as an end-of-line comment for the previous line and appends it to that previous line.
Given this original input file f0.txt, where the if(A)
block is unformatted, and the if(E)
block is already correctly formatted:
$ cmake-format --version
0.3.6
$ cat f0.txt
if(A)
# comment about B
baz(B)
# comment about C
baz(C)
endif()
if(E)
# comment about F
baz(F)
# comment about G
baz(G)
endif()
Running cmake-format on f0.txt to generate f1.txt, where the if(A)
block is correctly formatted, but the if(E)
block now has comments incorrectly appended to the previous lines:
$ cmake-format f0.txt | tee f1.txt
if(A)
# comment about B
baz(B)
# comment about C
baz(C)
endif()
if(E) # comment about F
baz(F) # comment about G
baz(G)
endif()
Running cmake-format again with the previous output f1.txt to generate f2.txt, where both if(A)
and if(E)
blocks have comments incorrectly appended to the previous lines:
$ cmake-format f1.txt | tee f2.txt
if(A) # comment about B
baz(B) # comment about C
baz(C)
endif()
if(E) # comment about F
baz(F) # comment about G
baz(G)
endif()
$ diff -q f1.txt f2.txt
Files f1.txt and f2.txt differ
Currently in my CMakeLists.txt there is something like
string(REPLACE "/w44668" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
After reformatting by cmake-format it becomes
string(REPLACE "/w44668"
""
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS}")
which imo is less readable. Is it possible to change it so it doesn't line break if everything can be fitted to one single line?
There seems to be a scary bug when running cmake-format in scripts that use while(...)
loops! cmake-format just removes them!
Sample file:
set(A "a")
while(condition)
fun1()
fun2()
endwhile()
set(B "b")
If you run cmake-format on the latter we end up with this:
set(A "a")
set(B "b")
Any pointers?
I like to have spaces between the command and parentheses for control flow commands (if
, elseif
, else
, endif
, while
, endwhile
, foreach
, endforeach
, continue
, break
, return
, function
, endfunction
, macro
, endmacro
). Having a toggle to preserve that would be nice to have.
I am seeing an issue since the last release when formatting files in-place with bracket comments and Windows line endings such as this CMakeLists.txt. When formatted in-place, the lines of the bracket comment pick up an extra carriage return, but the rest of the file is written correctly. The output seems correct when writing to stdout or using Unix line endings.
If I run cmake-format on something like
cmake_minimum_required(VERSION 3.9)
project(test)
sdfsdfsd
There will be error
While processing CMakeLists.txt
Traceback (most recent call last):
File "/usr/local/bin/cmake-format", line 11, in <module>
load_entry_point('cmake-format==0.4.0', 'console_scripts', 'cmake-format')()
File "/usr/local/lib/python2.7/dist-packages/cmake_format/__main__.py", line 336, in main
process_file(cfg, infile, outfile, args.dump)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/__main__.py", line 58, in process_file
parse_tree = parser.parse(tokens, config.fn_spec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 600, in parse
return consume_body(tokens, cmdspec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 579, in consume_body
subtree = consume_statement(tokens, cmdspec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 451, in consume_statement
if tokens[0].type != lexer.TokenType.LEFT_PAREN:
IndexError: list index out of range
and here is another example
cmake_minimum_required(VERSION 3.9)
project(test
While processing CMakeLists.txt
Traceback (most recent call last):
File "/usr/local/bin/cmake-format", line 11, in <module>
load_entry_point('cmake-format==0.4.0', 'console_scripts', 'cmake-format')()
File "/usr/local/lib/python2.7/dist-packages/cmake_format/__main__.py", line 336, in main
process_file(cfg, infile, outfile, args.dump)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/__main__.py", line 58, in process_file
parse_tree = parser.parse(tokens, config.fn_spec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 600, in parse
return consume_body(tokens, cmdspec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 579, in consume_body
subtree = consume_statement(tokens, cmdspec)
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 464, in consume_statement
consume_arguments(subtree, tokens, cmdspec.get(fnname, None), [])
File "/usr/local/lib/python2.7/dist-packages/cmake_format/parser.py", line 428, in consume_arguments
.format(node.get_location()))
ValueError: Token stream expired while parsing statement arguments starting at 3:8
It would be nice if cmake-format will just simply do nothing and return if the syntax is invalid. On top of that perhaps show an error message.
The main reason I am asking this is because for the sublime cmake format plugin I am maintaining sublime_cmake_format there is a format on save functionality that is intended for speeding up development, but the problem is if the developer is typing something halfway and habitually click ctrl+s
it will crash because the syntax is invalid.
If we reference clang-format, even if we type in some gibberish that can't be compiled clang-format will still attempt to format it into something instead of crashing it, so there's no problem running it with format on save.
Currently in my CMakeLists.txt there is something like
install(TARGETS ${PROJECT_NAME}
EXPORT ${CMAKE_PROJECT_NAME}Targets
ARCHIVE DESTINATION lib COMPONENT install-app
LIBRARY DESTINATION lib COMPONENT install-app
RUNTIME DESTINATION bin COMPONENT install-app)
After reformatting by cmake-format it becomes
install(TARGETS ${PROJECT_NAME}
EXPORT ${CMAKE_PROJECT_NAME}Targets
ARCHIVE DESTINATION lib
COMPONENT install-app
LIBRARY DESTINATION lib
COMPONENT install-app
RUNTIME DESTINATION bin
COMPONENT install-app)
which imo is less readable. Is it possible to treat the COMPONENT keyword differently so it doesn't line break ?
There are some new configs to set in the Configuration section,
dangle_parens = False
bullet_char = u'*'
enum_char = u'.'
line_ending = u'unix'
command_case = u'lower'
but they are not mentioned in the Usage --> Override configfile options section. It should be updated as well. I guess some of them myself like cmake-format --command-case upper CMakeLists.txt
and it actually works.
Normally I will do a PR for this but I know PR is generally not accepted in this repo.
Currently in my CMakeLists.txt
there is something like
install(EXPORT ${CMAKE_PROJECT_NAME}Targets
NAMESPACE jas::
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
After reformatting by cmake-format it becomes
install(EXPORT ${CMAKE_PROJECT_NAME}Targets
NAMESPACE
jas::
DESTINATION
lib/cmake/${CMAKE_PROJECT_NAME})
which imo is less readable. Is it possible to treat the NAMESPACE and DESTINATION keyword differently so it doesn't line break ?
๐ Hi,
thank you for providing this very useful utility.
The last version of cmake-format
(0.4.0
) requires the package NumPy. However, setup.py
does not list numpy
as dependency, as far as I can tell. This causes cmake-format
to fail, if you do not install numpy
too. For example, after I upgraded to the latest version of cmake-format
, the command
cmake-format --version
failed printing the following error message:
Traceback (most recent call last):
File "/Users/rene/.pyenv/versions/3.7.0/bin/cmake-format", line 11, in <module>
load_entry_point('cmake-format==0.4.0', 'console_scripts', 'cmake-format')()
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 476, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2700, in load_entry_point
return ep.load()
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2318, in load
return self.resolve()
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2324, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/cmake_format/__main__.py", line 29, in <module>
from cmake_format import formatter
File "/Users/rene/.pyenv/versions/3.7.0/lib/python3.7/site-packages/cmake_format/formatter.py", line 10, in <module>
import numpy as np
ModuleNotFoundError: No module named 'numpy'
.
$ clang-format --version
0.3.6
When I run cmake-format
on a code block like this:
my_function(
# This comment causes a parse error
stuff
)
cmake-format
gives me the following error:
$ cmake-format test.cmake
Error while processing test.cmake
While processing test.cmake
Traceback (most recent call last):
File "/usr/local/bin/cmake-format", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python3.6/site-packages/cmake_format/__main__.py", line 312, in main
process_file(cfg, infile, outfile)
File "/usr/local/lib/python3.6/site-packages/cmake_format/__main__.py", line 54, in process_file
fst = parser.construct_fst(tok_seqs)
File "/usr/local/lib/python3.6/site-packages/cmake_format/parser.py", line 426, in construct_fst
block_stack[-1].children.append(Statement(tok_seq))
File "/usr/local/lib/python3.6/site-packages/cmake_format/parser.py", line 315, in __init__
assert self.body
AssertionError
(using 0.3.6 on Ubuntu 14.04)
While using json, python, or yaml config files or command line option the trailing parentheses of a multi-line source list is placed at the end of the last line no matter what the setting of dangle_parens. I see no effect of this setting(perhaps a regression issue?).
$ clang-format --version
0.3.6
When I run cmake-format
on a code block like this:
my_function(
item1
# Some comment
item2
)
cmake-format
gives me the following output:
my_function(item1 # Some comment item2)
There should be a line break before item2
.
I'm really looking forward to integrating your project with our workflow. I've been looking for something clang-format-for-cmake-like for years.
Using cmake_format from pypi on python 3.5 in a virtualenv, I've run into a speedbump processing this file:
Error while processing OTHERPATH/dune-xt-common/cmake/modules/DuneXTInstallPythonPackage.cmake
While processing OTHERPATH/dune-xt-common/cmake/modules/DuneXTInstallPythonPackage.cmake
Traceback (most recent call last):
File "SOMEPATH/python-env/bin/cmake-format", line 11, in <module>
sys.exit(main())
File "SOMEPATH/python-env/lib/python3.5/site-packages/cmake_format/__main__.py", line 279, in main
process_file(cfg, infile, outfile)
File "SOMEPATH/python-env/lib/python3.5/site-packages/cmake_format/__main__.py", line 41, in process_file
tok_seqs = parser.digest_tokens(tokens)
File "SOMEPATH/python-env/lib/python3.5/site-packages/cmake_format/parser.py", line 148, in digest_tokens
tokens[0].line, tokens[0].col))
AssertionError: Unexpected token of type UNQUOTED_LITERAL at 160:38
I'm only using defaults for config options atm.
Hey. I noticed that updated config has only default values.
get_config returns a dict with tab_size
= 10
after config_dict.update(vars(args))
it's 2 (default value)
Therefore it's only using default values, no matter what I put in the config file. Same goes for other parameters.
Python 2.7.14
Formatting:
project(sxx)
cmake_minimum_required(VERSION 2.8)
include_directories(include)
set(CMAKE_CXX_FLAGS "-std=c++11 -Werror -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -Wold-style-cast -Wcast-align -Wunused -Wcast-qual -Woverloaded-virtual -Wconversion -Wformat-security -Wwrite-strings -fdiagnostics-show-option")
if (COVERAGE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
elseif (ASAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=leak")
elseif (UBSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -fsanitize=undefined")
elseif (TSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1 -fsanitize=thread")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif ()
add_executable(${PROJECT_NAME} src/sxx.cpp)
target_link_libraries(${PROJECT_NAME} PocoFoundation)
# packaging
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
find_program(rpmbuild_path "rpmbuild" FALSE)
if (rpmbuild_path) # is rpm based
message(STATUS "rpmbuild found, enabling RPM for the 'package' target")
list(APPEND CPACK_GENERATOR RPM)
if (EXISTS "/etc/redhat-release") # is rhel or centos
execute_process(COMMAND /bin/bash -c "rpm -E %{?dist} | sed -e 's/\\.//g' | sed 's/centos//g'"
OUTPUT_VARIABLE DISTRO_AND_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_RPM_PACKAGE_REQUIRES "poco-foundation")
else () # is opensuse
execute_process(COMMAND /bin/bash -c ". /etc/os-release; printf \"%s%.0f\" \"$ID\" \"$VERSION_ID\""
OUTPUT_VARIABLE DISTRO_AND_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_RPM_PACKAGE_REQUIRES "libPocoFoundation60")
endif ()
endif ()
find_program(dpkg_path "dpkg" FALSE)
if (dpkg_path) # is dpkg based
message(STATUS "dpkg found, enabling DEB for the 'package' target")
list(APPEND CPACK_GENERATOR DEB)
execute_process(COMMAND /bin/bash -c "printf \"$(lsb_release -i | awk '{printf tolower($NF)}')\""
OUTPUT_VARIABLE DISTRO)
if (${DISTRO} STREQUAL "debian") # is debian
execute_process(COMMAND /bin/bash -c "printf \"%.f\" \"$(lsb_release -r | awk '{printf int($NF)}')\""
OUTPUT_VARIABLE DISTRO_VERSION)
if (${DISTRO_VERSION} EQUAL 8)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9")
else ()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation46")
endif ()
else () # is ubuntu
execute_process(COMMAND /bin/bash -c "printf \"$(lsb_release -r | awk '{printf $NF}')\""
OUTPUT_VARIABLE DISTRO_VERSION)
if (${DISTRO_VERSION} EQUAL 14.04)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9")
elseif (${DISTRO_VERSION} EQUAL 16.04)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9v5")
else ()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation50")
endif ()
endif ()
set(DISTRO_AND_VERSION "${DISTRO}${DISTRO_VERSION}")
endif ()
execute_process(COMMAND /bin/bash -c "uname -m" OUTPUT_VARIABLE CPU_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_PACKAGE_CONTACT "[email protected]")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "sxx is a tool that allows you to easily run shell commands on multiple hosts or transfer files to multiple hosts")
set(CPACK_PACKAGE_URL "https://github.com/ericcurtin/sxx")
set(CPACK_PACKAGE_VERSION_MAJOR 1)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 1)
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${DISTRO_AND_VERSION}-${CPU_ARCH}")
include(CPack)
# man pages
add_custom_target(doc)
add_custom_command(TARGET doc SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod
COMMAND podchecker --nowarnings ${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod
COMMAND pod2man -c 'sxx manual' -q none -r 'sxx ${CPACK_PACKAGE_VERSION}' ${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod ${CMAKE_CURRENT_BINARY_DIR}/sxx.1
COMMAND gzip -f ${CMAKE_CURRENT_BINARY_DIR}/sxx.1
OUTPUTS ${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz)
add_custom_command(TARGET doc SOURCE doc
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz
DESTINATION ${CMAKE_install_PREFIX}/man/man1)
# ctest
enable_testing()
add_subdirectory(test)
# make format - clang-format
add_custom_target(format COMMAND clang-format -i -style=file ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp)
with:
cmake-format CMakeLists.txt --separate-ctrl-name-with-space True --line-ending unix --keyword-case upper --command-case lower
produces:
project(sxx)
cmake_minimum_required(VERSION 2.8)
include_directories(include)
set(
CMAKE_CXX_FLAGS
"-std=c++11 -Werror -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic -Wold-style-cast -Wcast-align -Wunused -Wcast-qual -Woverloaded-virtual -Wconversion -Wformat-security -Wwrite-strings -fdiagnostics-show-option"
)
if (COVERAGE)
set(
CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
elseif(ASAN)
set(
CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -g -O1 -fno-omit-frame-pointer -fsanitize=address -fsanitize=leak"
)
elseif(UBSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -fsanitize=undefined")
elseif(TSAN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1 -fsanitize=thread")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
endif ()
add_executable(${PROJECT_NAME} src/sxx.cpp)
target_link_libraries(${PROJECT_NAME} PocoFoundation)
# packaging
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
find_program(rpmbuild_path "rpmbuild" FALSE)
if (rpmbuild_path) # is rpm based
message(STATUS "rpmbuild found, enabling RPM for the 'package' target")
list(APPEND CPACK_GENERATOR RPM)
if (EXISTS "/etc/redhat-release") # is rhel or centos
execute_process(
COMMAND /bin/bash -c
"rpm -E %{?dist} | sed -e 's/\\.//g' | sed 's/centos//g'"
OUTPUT_VARIABLE DISTRO_AND_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_RPM_PACKAGE_REQUIRES "poco-foundation")
else() # is opensuse
execute_process(
COMMAND /bin/bash -c
". /etc/os-release; printf \"%s%.0f\" \"$ID\" \"$VERSION_ID\""
OUTPUT_VARIABLE DISTRO_AND_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_RPM_PACKAGE_REQUIRES "libPocoFoundation60")
endif ()
endif ()
find_program(dpkg_path "dpkg" FALSE)
if (dpkg_path) # is dpkg based
message(STATUS "dpkg found, enabling DEB for the 'package' target")
list(APPEND CPACK_GENERATOR DEB)
execute_process(
COMMAND /bin/bash -c
"printf \"$(lsb_release -i | awk '{printf tolower($NF)}')\""
OUTPUT_VARIABLE DISTRO)
if (${DISTRO} STREQUAL "debian") # is debian
execute_process(
COMMAND /bin/bash -c
"printf \"%.f\" \"$(lsb_release -r | awk '{printf int($NF)}')\""
OUTPUT_VARIABLE DISTRO_VERSION)
if (${DISTRO_VERSION} EQUAL 8)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation46")
endif ()
else() # is ubuntu
execute_process(COMMAND /bin/bash -c
"printf \"$(lsb_release -r | awk '{printf $NF}')\""
OUTPUT_VARIABLE DISTRO_VERSION)
if (${DISTRO_VERSION} EQUAL 14.04)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9")
elseif(${DISTRO_VERSION} EQUAL 16.04)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation9v5")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libpocofoundation50")
endif ()
endif ()
set(DISTRO_AND_VERSION "${DISTRO}${DISTRO_VERSION}")
endif ()
execute_process(COMMAND /bin/bash -c "uname -m"
OUTPUT_VARIABLE CPU_ARCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CPACK_PACKAGE_CONTACT "[email protected]")
set(
CPACK_PACKAGE_DESCRIPTION_SUMMARY
"sxx is a tool that allows you to easily run shell commands on multiple hosts or transfer files to multiple hosts"
)
set(CPACK_PACKAGE_URL "https://github.com/ericcurtin/sxx")
set(CPACK_PACKAGE_VERSION_MAJOR 1)
set(CPACK_PACKAGE_VERSION_MINOR 0)
set(CPACK_PACKAGE_VERSION_PATCH 1)
set(
CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
)
set(
CPACK_PACKAGE_FILE_NAME
"${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${DISTRO_AND_VERSION}-${CPU_ARCH}")
include(CPack)
# man pages
add_custom_target(doc)
add_custom_command(TARGET
doc
SOURCE
${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod
COMMAND podchecker
--NOWARNINGS ${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod
COMMAND pod2man -C 'sxx manual' -Q none -R
'sxx ${CPACK_PACKAGE_VERSION}'
${CMAKE_CURRENT_SOURCE_DIR}/doc/sxx.pod
${CMAKE_CURRENT_BINARY_DIR}/sxx.1
COMMAND gzip -F ${CMAKE_CURRENT_BINARY_DIR}/sxx.1 OUTPUTS
${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz)
add_custom_command(TARGET
doc
SOURCE
doc
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/sxx.1.gz
DESTINATION ${CMAKE_install_PREFIX}/man/man1)
# ctest
enable_testing()
add_subdirectory(test)
# make format - clang-format
add_custom_target(format
COMMAND clang-format -I -STYLE=FILE
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp)
I would expect "if (", "elseif (", "else (" and "endif (" consistently.
https://aomedia-review.googlesource.com/c/aom/+/65362/1/test/test.cmake
At the end of the file, running cmake-update removed the entire block after
# cmake-format: off
originally requested in the discussion for #26
Add support for line_ending=auto
which will detect the current line-ending mode of a file and preserve it on output. Possibly implemented by counting the number of \r\n
versus [^\r]\n
and picking whichever there are more of.
Currently in my CMakeLists.txt there is something like
file(WRITE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
"include(CMakeFindDependencyMacro)\n"
"include(\${CMAKE_CURRENT_LIST_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)\n")
After reformatting by cmake-format it becomes
file(
WRITE
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
"include(CMakeFindDependencyMacro)\n"
"include(\${CMAKE_CURRENT_LIST_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)\n")
which imo is less readable. Is it possible to change it so it doesn't line break twice on the first (
and WRITE?
$ cat CMakeLists.txt
[...]
INSTALL(TARGETS gridDynMain RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
[...]
Expected:
[...]
- INSTALL(TARGETS gridDynMain RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
+ install(TARGETS gridDynMain
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT
+ runtime)
[...]
Got:
[...]
- INSTALL(TARGETS gridDynMain RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT runtime)
+ install(TARGETS gridDynMain
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT
+ RUNTIME)
[...]
runtime
is not a keyword if it immediately follows COMPONENT
(or EXPORT
/DESTINATION
, but I didn't check to see if it was capitalized in either of those cases)
It seems that the prevailing style here is:
some_long_command_name(arg arg arg
arg)
It'd be nice to have an option for this instead:
some_long_command_name(arg arg arg
arg)
Create a file test.cmake
with the following content
cmake_parse_arguments(ARG
"SILENT" # optional keywords
"" # one value keywords
"" # multi value keywords
${ARGN})
Create a configuration file .cmake-format.yaml
with the following content
line_width: 140
Run cmake-format
cmake-format test.cmake
The command cmake-format
prints a nicely formatted version of the given CMake code.
The command produces the following syntactically incorrect code:
cmake_parse_arguments(ARG "SILENT" # optional keywords "" # one value keywords "" # multi value keywords ${ARGN})
.
The following set of commands don't respect the tab-size:
if(condition)
include_diredctories(...)
...
...
endif()
I expect that when I run cmake-format --tab-size 4 that the directives inside the if
are going to be indented at 4 spaces as shown below, but instead clang-format overrides it and formats it at 2 spaces anyway.
if(condition)
include_diredctories(...)
endif()
Any pointers on this?
Thanks very much!
As far as I can tell from the documentation there is no way for the user to specify a custom string (e.g., "#####" as a fence string that wont be formatted.
Can we add this sort of feature. Also it would make sense to make this a list of strings e.g.,
fence_string_specifiers = ["~~~", "#####"]
# first fenced block
# ~~~
...
...
# ~~~
# second fenced block
# #####
...
...
# #####
This can be handy in cases where the users don't want to polute their CMakeLists.txt filese with cmake-format: off
specifiers
Add non-builtin commands from standard cmake modules, like write_basic_package_version_file
. See #54 for example.
Currently cmake_format reports it as an error if you indent a line earlier than when it is needed.
For me personally I like to 'overintend' especially with functions and the like that get messy to read otherwise.
It would be great to add an option that would allow this kind of behaviour.
Currently our codebase is almost random in using upper or lower case for commands. It would be really nice if cmake_format had an option to harmonize this as well.
Combining conditions with the variable (NOT X) and Breaking on () would help a lot
https://aomedia-review.googlesource.com/c/aom/+/57102/3/test/test.cmake
if (("${var}" MATCHES "_TEST_" AND NOT
"${var}" MATCHES
"_DATA_\|_CMAKE_\|INTRA_PRED\|_COMPILED\|_HOSTING\|_PERF_\|CODER_")
OR (CONFIG_AV1_ENCODER AND CONFIG_ENCODE_PERF_TESTS AND
"${var}" MATCHES "_ENCODE_PERF_TEST_")
OR (CONFIG_AV1_DECODER AND CONFIG_DECODE_PERF_TESTS AND
"${var}" MATCHES "_DECODE_PERF_TEST_")
OR (CONFIG_AV1_ENCODER AND "${var}" MATCHES "_TEST_ENCODER_")
OR (CONFIG_AV1_DECODER AND "${var}" MATCHES "_TEST_DECODER_"))
list(APPEND aom_test_source_vars ${var})
endif ()
converted
if((
"${var}"
MATCHES
"_TEST_"
AND
NOT
"${var}"
MATCHES
"_DATA_\|_CMAKE_\|INTRA_PRED\|_COMPILED\|_HOSTING\|_PERF_\|CODER_"
)
OR
(
CONFIG_AV1_ENCODER
AND
CONFIG_ENCODE_PERF_TESTS
AND
"${var}"
MATCHES
"_ENCODE_PERF_TEST_"
)
OR
(
CONFIG_AV1_DECODER
AND
CONFIG_DECODE_PERF_TESTS
AND
"${var}"
MATCHES
"_DECODE_PERF_TEST_"
)
OR
(
CONFIG_AV1_ENCODER
AND
"${var}"
MATCHES
"_TEST_ENCODER_"
)
OR
(
CONFIG_AV1_DECODER
AND
"${var}"
MATCHES
"_TEST_DECODER_"
))
https://aomedia-review.googlesource.com/c/aom/+/57102/3/test/test_data_download_worker.cmake
if (NOT AOM_ROOT OR NOT AOM_CONFIG_DIR OR NOT AOM_TEST_FILE OR NOT AOM_TEST_CHECKSUM)
converted to
if(NOT
AOM_ROOT
OR
NOT
AOM_CONFIG_DIR
OR
NOT
AOM_TEST_FILE
OR
NOT
AOM_TEST_CHECKSUM)
http://python-future.org/compatible_idioms.html#execfile
flake8 testing of https://github.com/cheshirekow/cmake_format on Python 3.6.4
$ flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
./cmake_format/__main__.py:87:5: F821 undefined name 'execfile'
execfile(configfile_path, config_dict)
^
./cmake_format/__main__.py:115:9: F821 undefined name 'execfile'
execfile(configfile_path, config_dict)
^
2 F821 undefined name 'execfile'
cmake-format 0.3.6
if(test)
# comment about test_function
test_function()
endif()
gets reformatted to:
if(test) # comment about test_function
test_function()
endif()
Is there any way to keep the comment on it's own line? From the example this seems like it should be possible:
if(foo)
if(sbar)
# This comment is in-scope.
add_library(foo_bar_baz
Currently in my CMakeLists.txt there is something like
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
OR CMAKE_COMPILER_IS_GNUCC
OR CMAKE_COMPILER_IS_GNUCXX)
endif()
After reformatting by cmake-format it keeps it the same, which is great. But for the below
if(MSVC)
elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
OR CMAKE_COMPILER_IS_GNUCC
OR CMAKE_COMPILER_IS_GNUCXX)
endif()
it got reformats to
if(MSVC)
elseif((CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
OR
CMAKE_COMPILER_IS_GNUCC
OR
CMAKE_COMPILER_IS_GNUCXX)
endif()
which imo is less readable. Is it possible to change it so elseif gets treated similarly like if?
First of all I want to thank you for making this awesome tool. I also made a sublime plugin based on this which can run cmake-format
automatically on save and I hope you will also find it useful.
Would it be possible to allow individual configurations to be passed from the command line instead of just from a config file? Kind of like what clang-format is doing. The reason why it's good to have this functionality is because it allows me to support custom configuration in my sublime plugin so no .cmake-format
or cmake-format.yaml
is needed as long as you are using sublime.
If it's possible, can you make LICENSE permissive? (MIT/BSD/Apache, etc?)
Use the same LICENSE as CMake? https://cmake.org/licensing/
GPL causes conflicts with formatting plugins (since they are permissively licensed). GPL is only forward compatible with OSI licenses, not backward compatible. There are also tricky clauses in GPL that can become non-issues when a simpler license is used.
Our CMake list files start with a copyright block. It would be desirable to have an option that prevents reflow of the first comment block on a file. I can use fences (# ~~~
) to work around this, but that seems unnecessarily ugly, maybe?
Thanks for the great tool btw.
Very cool project you've created!
Many of my CMake scripts begin with a multi-line comment of the form #[[comment]]
. I get the following error when attempting to format this example CMakeLists.txt:
Error while processing CMakeLists.txt
While processing CMakeLists.txt
Traceback (most recent call last):
File "C:\Python27\Scripts\cmake-format-script.py", line 9, in
load_entry_point('cmake-format==0.3.0', 'console_scripts', 'cmake-format')()
File "c:\python27\lib\site-packages\cmake_format_main_.py", line 211, in main
process_file(config, infile, outfile)
File "c:\python27\lib\site-packages\cmake_format_main_.py", line 35, in process_file
tok_seqs = parser.digest_tokens(tokens)
File "c:\python27\lib\site-packages\cmake_format\parser.py", line 145, in digest_tokens
tokens[0].line, tokens[0].col))
AssertionError: Unexpected token of type UNQUOTED_LITERAL at 2:0
Would you consider adding support for this style of comment?
Description is pretty much the same as in #42
Let the user specify the ruler pattern. Perhaps even use a regular expression here:
let ruler_string_specifiers = ["### .* ###"]
$ cmake-format CMakeLists.txt
Error while processing CMakeLists.txt
While processing CMakeLists.txt
Traceback (most recent call last):
File "/Users/$USER/miniconda3/envs/python27/bin/cmake-format", line 11, in <module>
load_entry_point('cmake-format', 'console_scripts', 'cmake-format')()
File "/Users/$USER/GitRepos/cmake_format/cmake_format/__main__.py", line 111, in main
process_file(config, infile, outfile)
File "/Users/$USER/GitRepos/cmake_format/cmake_format/__main__.py", line 26, in process_file
fst = parser.construct_fst(tok_seqs)
File "/Users/$USER/GitRepos/cmake_format/cmake_format/parser.py", line 365, in construct_fst
assert block_stack and block_stack[-1].block_type == IF_BLOCK
AssertionError
Currently in my CMakeLists.txt there is something like
export(TARGETS ${PROJECT_NAME}
APPEND FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
After reformatting by cmake-format it becomes
export(TARGETS
${PROJECT_NAME}
APPEND
FILE
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
which imo is less readable. Is it possible to change it so it doesn't line break on TARGETS and APPEND FILE?
Can it be possible to turn off comment formatting globally? I'd rather not wrap license headers and commented-out code with # ~~~
or # cmake-format: on/off
. cmake-format
is also inferring bulleted lists where we didn't mean them.
(These are things we need to fix, but it makes running cmake-format incrementally a little harder).
...
This:
diff --git a/cmake_format/formatter.py b/cmake_format/formatter.py
index 4a80f17..4de3a96 100644
--- a/cmake_format/formatter.py
+++ b/cmake_format/formatter.py
@@ -72,8 +72,7 @@ def format_comment_lines(node, config, line_width):
inlines.append(token.spelling.strip().lstrip('#'))
items = markup.parse(inlines)
- markup_lines = markup.format_items(config, max(10, line_width - 2), items)
- return ["#" + (" " * len(line[:1])) + line for line in markup_lines]
+ return ["#" + " " + line for item in items for line in item.lines]
def normalize_line_endings(instr):
works well enough for now
When I try to invoke cmake-format
with Python 3 from a command prompt in Windows, I get the following error.
c:\>cmake-format
Traceback (most recent call last):
File "C:\Python36\Scripts\cmake-format-script.py", line 11, in <module>
load_entry_point('cmake-format==0.3.2', 'console_scripts', 'cmake-format')()
File "c:\python36\lib\site-packages\cmake_format\__main__.py", line 184, in main
for key, value in configuration.Configuration().as_dict().iteritems():
AttributeError: 'dict' object has no attribute 'iteritems'
In Python 3 the iteritems
does not exist for dict
. Use items
instead.
Thanks for this cool program! I've been looking for something like this for CMake for a while.
I noticed that trailing whitespace seems to confuse the program.
Input CMakeLists.txt
:
set(FOO "f")
set(BAR "b")
Note the trailing whitespace on the first line:
Test:
$ python2.7 -m cmake_format CMakeLists.txt
Expected:
set(FOO "f")
set(BAR "b")
Got:
set(FOO "f")set(BAR "b")
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.