1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-07-31 00:03:08 +03:00

cmake: add linter, fix issues

Ref: https://cmake-format.readthedocs.io/en/latest/cmake-lint.html
Ref: https://github.com/cheshirekow/cmake_format

Closes #1610
This commit is contained in:
Viktor Szakats
2025-06-10 22:30:54 +02:00
parent d7cf63bb05
commit 694b9d964b
12 changed files with 112 additions and 41 deletions

View File

@ -49,6 +49,19 @@ jobs:
- name: 'shellcheck' - name: 'shellcheck'
run: ./ci/shellcheck.sh run: ./ci/shellcheck.sh
cmakelint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
persist-credentials: false
name: checkout
- name: cmakelint
run: |
python3 -m pip install --break-system-packages cmakelang==0.6.13
ci/cmakelint.sh
cicheck: cicheck:
runs-on: macos-latest runs-on: macos-latest
timeout-minutes: 1 timeout-minutes: 1

View File

@ -52,7 +52,8 @@ include(CheckNonblockingSocketSupport)
project(libssh2 C) project(libssh2 C)
function(libssh2_dumptargetprops _target) # Dump all target properties # Dump all target properties
function(libssh2_dumptargetprops _target)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19 AND TARGET "${_target}") if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19 AND TARGET "${_target}")
execute_process(COMMAND "${CMAKE_COMMAND}" "--help-property-list" OUTPUT_VARIABLE _cmake_property_list) execute_process(COMMAND "${CMAKE_COMMAND}" "--help-property-list" OUTPUT_VARIABLE _cmake_property_list)
string(REPLACE "\n" ";" _cmake_property_list "${_cmake_property_list}") string(REPLACE "\n" ";" _cmake_property_list "${_cmake_property_list}")
@ -80,7 +81,8 @@ function(libssh2_dumptargetprops _target) # Dump all target properties
endif() endif()
endfunction() endfunction()
function(libssh2_dumpvars) # Dump all defined variables with their values # Dump all defined variables with their values
function(libssh2_dumpvars)
message("::group::CMake Variable Dump") message("::group::CMake Variable Dump")
get_cmake_property(_vars VARIABLES) get_cmake_property(_vars VARIABLES)
foreach(_var IN ITEMS ${_vars}) foreach(_var IN ITEMS ${_vars})
@ -186,11 +188,11 @@ set(LIBSSH2_LIBS "")
if(WIN32) if(WIN32)
list(APPEND LIBSSH2_LIBS_SOCKET "ws2_32") list(APPEND LIBSSH2_LIBS_SOCKET "ws2_32")
else() else()
check_function_exists_may_need_library("socket" HAVE_SOCKET "socket") libssh2_check_function_exists_may_need_library("socket" HAVE_SOCKET "socket")
if(NEED_LIB_SOCKET) if(NEED_LIB_SOCKET)
list(APPEND LIBSSH2_LIBS_SOCKET "socket") list(APPEND LIBSSH2_LIBS_SOCKET "socket")
endif() endif()
check_function_exists_may_need_library("inet_addr" HAVE_INET_ADDR "nsl") libssh2_check_function_exists_may_need_library("inet_addr" HAVE_INET_ADDR "nsl")
if(NEED_LIB_NSL) if(NEED_LIB_NSL)
list(APPEND LIBSSH2_LIBS_SOCKET "nsl") list(APPEND LIBSSH2_LIBS_SOCKET "nsl")
endif() endif()
@ -390,7 +392,7 @@ endif()
if(NOT WIN32) if(NOT WIN32)
cmake_push_check_state() cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBS_SOCKET}) list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBSSH2_LIBS_SOCKET})
check_nonblocking_socket_support() libssh2_check_nonblocking_socket_support()
cmake_pop_check_state() cmake_pop_check_state()
endif() endif()
@ -435,7 +437,7 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND)
HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS} HINTS ${_OPENSSL_ROOT_HINTS} PATHS ${_OPENSSL_ROOT_PATHS}
PATH_SUFFIXES "bin" NO_DEFAULT_PATH) PATH_SUFFIXES "bin" NO_DEFAULT_PATH)
if(DLL_LIBCRYPTO) if(DLL_LIBCRYPTO)
list(APPEND _RUNTIME_DEPENDENCIES ${DLL_LIBCRYPTO}) list(APPEND __runtime_dependencies ${DLL_LIBCRYPTO})
message(STATUS "Found libcrypto DLL: ${DLL_LIBCRYPTO}") message(STATUS "Found libcrypto DLL: ${DLL_LIBCRYPTO}")
else() else()
message(WARNING "Unable to find OpenSSL libcrypto DLL, executables may not run") message(WARNING "Unable to find OpenSSL libcrypto DLL, executables may not run")
@ -509,7 +511,7 @@ endif()
# Global functions # Global functions
# Convert GNU Make assignments into CMake ones. # Convert GNU Make assignments into CMake ones.
function(transform_makefile_inc _input_file _output_file) function(libssh2_transform_makefile_inc _input_file _output_file)
file(READ ${_input_file} _makefile_inc_cmake) file(READ ${_input_file} _makefile_inc_cmake)
string(REGEX REPLACE "\\\\\n" "" _makefile_inc_cmake ${_makefile_inc_cmake}) string(REGEX REPLACE "\\\\\n" "" _makefile_inc_cmake ${_makefile_inc_cmake})

55
ci/cmakelint.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/sh
# Copyright (C) Dan Fandrich, <dan@coneharvesters.com>, Viktor Szakats, et al.
#
# SPDX-License-Identifier: curl
# https://cmake-format.readthedocs.io/en/latest/cmake-lint.html
# https://cmake-format.readthedocs.io/en/latest/lint-usage.html
# https://github.com/cheshirekow/cmake_format/blob/master/cmakelang/configuration.py
# Run cmakelint on the curl source code. It will check all files given on the
# command-line, or else all relevant files in git, or if not in a git
# repository, all files starting in the tree rooted in the current directory.
#
# cmake-lint can be installed from PyPi with the command "python3 -m pip
# install cmakelang".
#
# The xargs invocation is portable, but does not preserve spaces in file names.
# If such a file is ever added, then this can be portably fixed by switching to
# "xargs -I{}" and appending {} to the end of the xargs arguments (which will
# call cmakelint once per file) or by using the GNU extension "xargs -d'\n'".
{
if [ -n "$1" ]; then
for A in "$@"; do printf "%s\n" "$A"; done
elif git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
git ls-files
else
# strip off the leading ./ to make the grep regexes work properly
find . -type f | sed 's@^\./@@'
fi
} | grep -E '(^CMake|/CMake|\.cmake$)' | grep -v -E '(\.h\.cmake|\.in|\.c)$' \
| xargs \
cmake-lint \
--suppress-decorations \
--disable \
--line-width 132 \
--tab-size 2 \
--use-tabchars false \
--disabled-codes C0113 \
--function-pattern 'libssh2_[0-9a-z_]+' \
--macro-pattern 'libssh2_[0-9a-z_]+' \
--global-var-pattern '[A-Z][0-9A-Z_]+' \
--internal-var-pattern '_[a-z][0-9a-z_]+' \
--local-var-pattern '_[a-z][0-9a-z_]+' \
--private-var-pattern '_[0-9a-z_]+' \
--public-var-pattern '([A-Z][0-9A-Z_]+|[A-Z][A-Za-z0-9]+_FOUND|[a-z]+_SOURCES|prefix|exec_prefix|includedir|libdir)' \
--argument-var-pattern '_[a-z][0-9a-z_]+' \
--keyword-pattern '[A-Z][0-9A-Z_]+' \
--max-conditionals-custom-parser 2 \
--min-statement-spacing 1 \
--max-statement-spacing 2 \
--max-returns 6 \
--max-branches 12 \
--max-arguments 5 \
--max-localvars 15 \
--max-statements 50

View File

@ -35,8 +35,10 @@
# #
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
include(CheckFunctionExists)
include(CheckLibraryExists)
# - check_function_exists_maybe_need_library(<function> <var> [lib1 ... libn]) # libssh2_check_function_exists_may_need_library(<function> <var> [lib1 ... libn])
# #
# Check if function is available for linking, first without extra libraries, and # Check if function is available for linking, first without extra libraries, and
# then, if not found that way, linking in each optional library as well. This # then, if not found that way, linking in each optional library as well. This
@ -56,11 +58,7 @@
# CMAKE_REQUIRED_INCLUDES = list of include directories # CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link # CMAKE_REQUIRED_LIBRARIES = list of libraries to link
# #
function(libssh2_check_function_exists_may_need_library _function _variable)
include(CheckFunctionExists)
include(CheckLibraryExists)
function(check_function_exists_may_need_library _function _variable)
check_function_exists(${_function} ${_variable}) check_function_exists(${_function} ${_variable})
@ -72,7 +70,7 @@ function(check_function_exists_may_need_library _function _variable)
check_library_exists(${_lib} ${_function} "" HAVE_${_function}_IN_${_lib}) check_library_exists(${_lib} ${_function} "" HAVE_${_function}_IN_${_lib})
if(HAVE_${_function}_IN_${_lib}) if(HAVE_${_function}_IN_${_lib})
set(${_variable} 1 CACHE INTERNAL "Function ${_function} found in library ${_lib}") set(${_variable} 1 CACHE INTERNAL "Function ${_function} found in library ${_lib}")
set(NEED_LIB_${_up_lib} 1 CACHE INTERNAL "Need to link ${_lib}") set(NEED_LIB_${_up_lib} 1 CACHE INTERNAL "Need to link ${_lib}") # cmake-lint: disable=C0103
break() break()
endif() endif()
endforeach() endforeach()

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
include(CheckCSourceCompiles) include(CheckCSourceCompiles)
# - check_nonblocking_socket_support() # libssh2_check_nonblocking_socket_support()
# #
# Check for how to set a socket to non-blocking state. There seems to exist # Check for how to set a socket to non-blocking state. There seems to exist
# four known different ways, with the one used almost everywhere being POSIX # four known different ways, with the one used almost everywhere being POSIX
@ -24,7 +24,7 @@ include(CheckCSourceCompiles)
# CMAKE_REQUIRED_INCLUDES = list of include directories # CMAKE_REQUIRED_INCLUDES = list of include directories
# CMAKE_REQUIRED_LIBRARIES = list of libraries to link # CMAKE_REQUIRED_LIBRARIES = list of libraries to link
# #
macro(check_nonblocking_socket_support) macro(libssh2_check_nonblocking_socket_support)
# There are two known platforms (AIX 3.x and SunOS 4.1.x) where the # There are two known platforms (AIX 3.x and SunOS 4.1.x) where the
# O_NONBLOCK define is found but does not work. # O_NONBLOCK define is found but does not work.
check_c_source_compiles(" check_c_source_compiles("

View File

@ -37,11 +37,12 @@
include(CMakeParseArguments) include(CMakeParseArguments)
function(add_target_to_copy_dependencies) # Add target to copy dependencies
set(options) function(libssh2_add_target_to_copy_dependencies)
set(oneValueArgs TARGET) set(_options)
set(multiValueArgs DEPENDENCIES BEFORE_TARGETS) set(_one_value_args TARGET)
cmake_parse_arguments(COPY "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(_multi_value_args DEPENDENCIES BEFORE_TARGETS)
cmake_parse_arguments(COPY "${_options}" "${_one_value_args}" "${_multi_value_args}" ${ARGN})
if(NOT COPY_DEPENDENCIES) if(NOT COPY_DEPENDENCIES)
return() return()

View File

@ -260,8 +260,9 @@ if(PICKY_COMPILER)
list(APPEND _picky "-wd4668") # 'M' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' (in winbase.h) list(APPEND _picky "-wd4668") # 'M' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' (in winbase.h)
list(APPEND _picky "-wd4710") # 'snprintf': function not inlined list(APPEND _picky "-wd4710") # 'snprintf': function not inlined
list(APPEND _picky "-wd4711") # function 'A' selected for automatic inline expansion list(APPEND _picky "-wd4711") # function 'A' selected for automatic inline expansion
list(APPEND _picky "-wd4746") # volatile access of '<expression>' is subject to /volatile:<iso|ms> setting; # volatile access of '<expression>' is subject to /volatile:<iso|ms> setting;
# consider using __iso_volatile_load/store intrinsic functions (ARM64) # consider using __iso_volatile_load/store intrinsic functions (ARM64)
list(APPEND _picky "-wd4746")
list(APPEND _picky "-wd4774") # 'snprintf': format string expected in argument 3 is not a string literal list(APPEND _picky "-wd4774") # 'snprintf': format string expected in argument 3 is not a string literal
list(APPEND _picky "-wd4820") # 'A': 'N' bytes padding added after data member 'B' list(APPEND _picky "-wd4820") # 'A': 'N' bytes padding added after data member 'B'
if(MSVC_VERSION GREATER_EQUAL 1900) if(MSVC_VERSION GREATER_EQUAL 1900)
@ -284,7 +285,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND MSVC)
list(APPEND _picky_tmp "-clang:${_ccopt}") list(APPEND _picky_tmp "-clang:${_ccopt}")
endif() endif()
endforeach() endforeach()
set("${_wlist}" ${_picky_tmp}) set("${_wlist}" ${_picky_tmp}) # cmake-lint: disable=C0103
endforeach() endforeach()
endif() endif()

View File

@ -36,7 +36,7 @@
# #
# SPDX-License-Identifier: BSD-3-Clause # SPDX-License-Identifier: BSD-3-Clause
transform_makefile_inc("Makefile.am" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake") libssh2_transform_makefile_inc("Makefile.am" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake")
# Get 'dist_man_MANS' variable # Get 'dist_man_MANS' variable
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.am.cmake")

View File

@ -40,7 +40,7 @@ include(CopyRuntimeDependencies)
list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET}) list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET})
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") libssh2_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
# Get 'noinst_PROGRAMS' variable # Get 'noinst_PROGRAMS' variable
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
@ -55,7 +55,7 @@ foreach(_example IN LISTS noinst_PROGRAMS)
set_target_properties(${_example} PROPERTIES UNITY_BUILD OFF) set_target_properties(${_example} PROPERTIES UNITY_BUILD OFF)
endforeach() endforeach()
add_target_to_copy_dependencies( libssh2_add_target_to_copy_dependencies(
TARGET copy_example_dependencies TARGET copy_example_dependencies
DEPENDENCIES ${RUNTIME_DEPENDENCIES} DEPENDENCIES ${_runtime_dependencies}
BEFORE_TARGETS ${_example_targets}) BEFORE_TARGETS ${_example_targets})

View File

@ -80,7 +80,7 @@ endif()
## Sources ## Sources
include(GNUInstallDirs) include(GNUInstallDirs)
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") libssh2_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
# Get 'CSOURCES' and 'HHEADERS' variables # Get 'CSOURCES' and 'HHEADERS' variables
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
set(_sources ${CSOURCES} ${HHEADERS}) set(_sources ${CSOURCES} ${HHEADERS})
@ -198,10 +198,10 @@ if(BUILD_SHARED_LIBS)
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
list(APPEND _RUNTIME_DEPENDENCIES $<TARGET_FILE:${LIB_SHARED}>) list(APPEND __runtime_dependencies $<TARGET_FILE:${LIB_SHARED}>)
endif() endif()
set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL set(_runtime_dependencies ${__runtime_dependencies} CACHE INTERNAL
"Files that must be in the same directory as the executables at runtime.") "Files that must be in the same directory as the executables at runtime.")
# Package config # Package config

View File

@ -40,7 +40,7 @@ include(CopyRuntimeDependencies)
list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET}) list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET})
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") libssh2_transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
# Get 'DOCKER_TESTS', 'DOCKER_TESTS_STATIC', 'STANDALONE_TESTS', 'STANDALONE_TESTS_STATIC', 'SSHD_TESTS', # Get 'DOCKER_TESTS', 'DOCKER_TESTS_STATIC', 'STANDALONE_TESTS', 'STANDALONE_TESTS_STATIC', 'SSHD_TESTS',
# 'librunner_la_SOURCES' variables # 'librunner_la_SOURCES' variables
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
@ -106,7 +106,7 @@ foreach(_test IN LISTS DOCKER_TESTS STANDALONE_TESTS SSHD_TESTS)
target_link_libraries(${_test} PRIVATE "gcov") target_link_libraries(${_test} PRIVATE "gcov")
endif() endif()
list(APPEND TEST_TARGETS ${_test}) list(APPEND _test_targets ${_test})
endif() endif()
endforeach() endforeach()
@ -164,15 +164,16 @@ endif()
add_custom_target(coverage add_custom_target(coverage
COMMAND gcovr --root "${PROJECT_SOURCE_DIR}" --exclude tests/* COMMAND gcovr --root "${PROJECT_SOURCE_DIR}" --exclude tests/*
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/coverage" COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/coverage"
COMMAND gcovr --root "${PROJECT_SOURCE_DIR}" --exclude tests/* --html-details --output "${CMAKE_CURRENT_BINARY_DIR}/coverage/index.html") COMMAND gcovr --root "${PROJECT_SOURCE_DIR}" --exclude tests/* --html-details
--output "${CMAKE_CURRENT_BINARY_DIR}/coverage/index.html")
add_custom_target(clean-coverage add_custom_target(clean-coverage
COMMAND rm -rf "${CMAKE_CURRENT_BINARY_DIR}/coverage") COMMAND rm -rf "${CMAKE_CURRENT_BINARY_DIR}/coverage")
add_target_to_copy_dependencies( libssh2_add_target_to_copy_dependencies(
TARGET copy_test_dependencies TARGET copy_test_dependencies
DEPENDENCIES ${RUNTIME_DEPENDENCIES} DEPENDENCIES ${_runtime_dependencies}
BEFORE_TARGETS ${TEST_TARGETS}) BEFORE_TARGETS ${_test_targets})
if(BUILD_OSSFUZZ) if(BUILD_OSSFUZZ)
add_subdirectory(ossfuzz) add_subdirectory(ossfuzz)

View File

@ -26,12 +26,12 @@ if(TEST_INTEGRATION_MODE STREQUAL "find_package" OR
TEST_INTEGRATION_MODE STREQUAL "ExternalProject") TEST_INTEGRATION_MODE STREQUAL "ExternalProject")
find_package(libssh2 REQUIRED CONFIG) find_package(libssh2 REQUIRED CONFIG)
find_package(libssh2 REQUIRED CONFIG) # Double-inclusion test find_package(libssh2 REQUIRED CONFIG) # Double-inclusion test
foreach(result_var IN ITEMS foreach(_result_var IN ITEMS
libssh2_FOUND libssh2_FOUND
libssh2_VERSION libssh2_VERSION
) )
if(NOT ${result_var}) if(NOT ${_result_var})
message(FATAL_ERROR "'${result_var}' variable expected, but not set by the libssh2 package.") message(FATAL_ERROR "'${_result_var}' variable expected, but not set by the libssh2 package.")
endif() endif()
endforeach() endforeach()
# Show variables set by find_package() # Show variables set by find_package()