# Copyright (c) 2017-2019, Lawrence Livermore National Security, LLC and
# other BLT Project Developers. See the top-level COPYRIGHT file for details
#
# SPDX-License-Identifier: (BSD-3-Clause)
#------------------------------------------------------------------------------
# Targets related to source code checks (formatting, static analysis, etc)
#------------------------------------------------------------------------------
add_custom_target(${BLT_CODE_CHECK_TARGET_NAME})
add_custom_target(${BLT_CODE_STYLE_TARGET_NAME})
if(ASTYLE_FOUND)
# targets for verifying formatting
add_custom_target(astyle_check)
add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} astyle_check)
# targets for modifying formatting
add_custom_target(astyle_style)
add_dependencies(${BLT_CODE_STYLE_TARGET_NAME} astyle_style)
endif()
if(CLANGFORMAT_FOUND)
# targets for verifying formatting
add_custom_target(clangformat_check)
add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} clangformat_check)
# targets for modifying formatting
add_custom_target(clangformat_style)
add_dependencies(${BLT_CODE_STYLE_TARGET_NAME} clangformat_style)
endif()
if(UNCRUSTIFY_FOUND)
# targets for verifying formatting
add_custom_target(uncrustify_check)
add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} uncrustify_check)
# targets for modifying formatting
add_custom_target(uncrustify_style)
add_dependencies(${BLT_CODE_STYLE_TARGET_NAME} uncrustify_style)
endif()
if(CPPCHECK_FOUND)
add_custom_target(cppcheck_check)
add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} cppcheck_check)
endif()
if(CLANGQUERY_FOUND)
# note: interactive_clang_query_check
# is for the use of code developers who
# want to check specific attributes of
# specific targets, and does not make
# sense as a dependency of check
add_custom_target(clang_query_check)
add_custom_target(interactive_clang_query_check)
add_dependencies(${BLT_CODE_CHECK_TARGET_NAME} clang_query_check)
endif()
# Code check targets should only be run on demand
foreach(target
check uncrustify_check astyle_check clangformat_check cppcheck_check
style uncrustify_style astyle_style clangformat_style
clang_query_check interactive_clang_query_check)
if(TARGET ${target})
set_property(TARGET ${target} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${target} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endif()
endforeach()
##------------------------------------------------------------------------------
## blt_add_code_checks( PREFIX
## SOURCES [source1 [source2 ...]]
## ASTYLE_CFG_FILE
## CLANGFORMAT_CFG_FILE
## UNCRUSTIFY_CFG_FILE
## CPPCHECK_FLAGS )
##
## This macro adds all enabled code check targets for the given SOURCES. It
## filters checks based on file extensions.
##------------------------------------------------------------------------------
macro(blt_add_code_checks)
set(options )
set(singleValueArgs PREFIX ASTYLE_CFG_FILE CLANGFORMAT_CFG_FILE UNCRUSTIFY_CFG_FILE)
set(multiValueArgs SOURCES CPPCHECK_FLAGS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT DEFINED arg_PREFIX)
message(FATAL_ERROR "blt_add_code_checks requires the parameter PREFIX.")
endif()
if (NOT DEFINED arg_SOURCES)
message(FATAL_ERROR "blt_add_code_checks requires the parameter SOURCES.")
endif()
# Make the sources relative to the bin directory
set(_rel_sources)
foreach(_file ${arg_SOURCES})
# Get full path
if(IS_ABSOLUTE ${_file})
set(_full_path ${_file})
else()
set(_full_path ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
endif()
file(RELATIVE_PATH _rel_path ${CMAKE_BINARY_DIR} ${_full_path})
list(APPEND _rel_sources ${_rel_path})
endforeach()
# Generate source lists based on language
set(_c_sources)
set(_f_sources)
blt_split_source_list_by_language(SOURCES ${_rel_sources}
C_LIST _c_sources
Fortran_LIST _f_sources)
# Check that at most one formatting config file was supplied
if (DEFINED arg_UNCRUSTIFY_CFG_FILE AND DEFINED arg_ASTYLE_CFG_FILE)
message(FATAL_ERROR
"blt_add_code_checks macro does not support multiple "
"style config parameters within the same invocation. "
"Both UNCRUSTIFY_CFG_FILE and ASTYLE_CFG_FILE were supplied.")
endif()
# Add code checks
set(_error_msg "blt_add_code_checks tried to create an already existing target with given PREFIX: ${arg_PREFIX}. ")
if (ASTYLE_FOUND AND DEFINED arg_ASTYLE_CFG_FILE)
set(_check_target_name ${arg_PREFIX}_astyle_check)
blt_error_if_target_exists(${_check_target_name} ${_error_msg})
set(_style_target_name ${arg_PREFIX}_astyle_style)
blt_error_if_target_exists(${_style_target_name} ${_error_msg})
blt_add_astyle_target( NAME ${_check_target_name}
MODIFY_FILES FALSE
CFG_FILE ${arg_ASTYLE_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
blt_add_astyle_target( NAME ${_style_target_name}
MODIFY_FILES TRUE
CFG_FILE ${arg_ASTYLE_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
endif()
if (CLANGFORMAT_FOUND AND DEFINED arg_CLANGFORMAT_CFG_FILE)
set(_check_target_name ${arg_PREFIX}_clangformat_check)
blt_error_if_target_exists(${_check_target_name} ${_error_msg})
set(_style_target_name ${arg_PREFIX}_clangformat_style)
blt_error_if_target_exists(${_style_target_name} ${_error_msg})
blt_add_clangformat_target( NAME ${_check_target_name}
MODIFY_FILES FALSE
CFG_FILE ${arg_CLANGFORMAT_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
blt_add_clangformat_target( NAME ${_style_target_name}
MODIFY_FILES TRUE
CFG_FILE ${arg_CLANGFORMAT_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
endif()
if (UNCRUSTIFY_FOUND AND DEFINED arg_UNCRUSTIFY_CFG_FILE)
set(_check_target_name ${arg_PREFIX}_uncrustify_check)
blt_error_if_target_exists(${_check_target_name} ${_error_msg})
set(_style_target_name ${arg_PREFIX}_uncrustify_style)
blt_error_if_target_exists(${_style_target_name} ${_error_msg})
blt_add_uncrustify_target( NAME ${_check_target_name}
MODIFY_FILES FALSE
CFG_FILE ${arg_UNCRUSTIFY_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
blt_add_uncrustify_target( NAME ${_style_target_name}
MODIFY_FILES TRUE
CFG_FILE ${arg_UNCRUSTIFY_CFG_FILE}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources} )
endif()
if (CPPCHECK_FOUND)
set(_cppcheck_target_name ${arg_PREFIX}_cppcheck_check)
blt_error_if_target_exists(${_cppcheck_target_name} ${_error_msg})
blt_add_cppcheck_target( NAME ${_cppcheck_target_name}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources}
PREPEND_FLAGS ${arg_CPPCHECK_FLAGS})
endif()
if (CLANGQUERY_FOUND)
set(_clang_query_target_name ${arg_PREFIX}_clang_query_check)
blt_error_if_target_exists(${_clang_query_target_name} ${_error_msg})
blt_add_clang_query_target( NAME ${_clang_query_target_name}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
SRC_FILES ${_c_sources})
endif()
endmacro(blt_add_code_checks)
##-----------------------------------------------------------------------------
## blt_add_clang_query_target( NAME
## WORKING_DIRECTORY
## COMMENT
## CHECKERS
## DIE_ON_MATCH
## SRC_FILES [FILE1 [FILE2 ...]] )
##
## Creates a new target with the given NAME for running clang_query over the given SRC_FILES
##-----------------------------------------------------------------------------
macro(blt_add_clang_query_target)
if(CLANGQUERY_FOUND)
## parse the arguments to the macro
set(options)
set(singleValueArgs NAME COMMENT WORKING_DIRECTORY DIE_ON_MATCH)
set(multiValueArgs SRC_FILES CHECKERS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} )
# Check required parameters
if(NOT DEFINED arg_NAME)
message(FATAL_ERROR "blt_add_clang_query_target requires a NAME parameter")
endif()
if(NOT DEFINED arg_SRC_FILES)
message(FATAL_ERROR "blt_add_clang_query_target requires a SRC_FILES parameter")
endif()
if(DEFINED arg_WORKING_DIRECTORY)
set(_wd ${arg_WORKING_DIRECTORY})
else()
set(_wd ${CMAKE_CURRENT_SOURCE_DIR})
endif()
set(interactive_target_name interactive_${arg_NAME})
set(CLANG_QUERY_HELPER_SCRIPT ${BLT_ROOT_DIR}/cmake/clang-query-wrapper.py)
set(CLANG_QUERY_HELPER_COMMAND python ${CLANG_QUERY_HELPER_SCRIPT} --clang-query ${CLANGQUERY_EXECUTABLE} --checker-directories ${BLT_CLANG_QUERY_CHECKER_DIRECTORIES} --compilation-database-path ${CMAKE_BINARY_DIR})
if(arg_DIE_ON_MATCH)
set(CLANG_QUERY_HELPER_COMMAND ${CLANG_QUERY_HELPER_COMMAND} --die-on-match)
endif()
if(DEFINED arg_CHECKERS)
STRING(REGEX REPLACE " " ":" CHECKER_ARG_STRING ${arg_CHECKERS})
add_custom_target(${arg_NAME}
COMMAND ${CLANG_QUERY_HELPER_COMMAND} -i --checkers=${CHECKER_ARG_STRING} ${arg_SRC_FILES}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running specified clang_query source code static analysis checks.")
else() #DEFINED CHECKERS
add_custom_target(${arg_NAME}
COMMAND ${CLANG_QUERY_HELPER_COMMAND} ${arg_SRC_FILES}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running all clang_query source code static analysis checks.")
endif()
add_custom_target(${interactive_target_name}
COMMAND ${CLANG_QUERY_HELPER_COMMAND} -i ${arg_SRC_FILES}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running clang_query source code static analysis checks.")
# hook our new target into the proper dependency chain
add_dependencies(clang_query_check ${arg_NAME})
add_dependencies(interactive_clang_query_check ${interactive_target_name})
# Code check targets should only be run on demand
set_property(TARGET ${interactive_target_name} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${interactive_target_name} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endif()
endmacro(blt_add_clang_query_target)
##-----------------------------------------------------------------------------
## blt_add_cppcheck_target( NAME
## WORKING_DIRECTORY
## PREPEND_FLAGS
## APPEND_FLAGS
## COMMENT
## SRC_FILES [FILE1 [FILE2 ...]] )
##
## Creates a new target with the given NAME for running cppcheck over the given SRC_FILES
##-----------------------------------------------------------------------------
macro(blt_add_cppcheck_target)
## parse the arguments to the macro
set(options)
set(singleValueArgs NAME COMMENT WORKING_DIRECTORY)
set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} )
# Check required parameters
if(NOT DEFINED arg_NAME)
message(FATAL_ERROR "blt_add_cppcheck_target requires a NAME parameter")
endif()
if(NOT DEFINED arg_SRC_FILES)
message(FATAL_ERROR "blt_add_cppcheck_target requires a SRC_FILES parameter")
endif()
if(DEFINED arg_WORKING_DIRECTORY)
set(_wd ${arg_WORKING_DIRECTORY})
else()
set(_wd ${CMAKE_CURRENT_SOURCE_DIR})
endif()
add_custom_target(${arg_NAME}
COMMAND ${CPPCHECK_EXECUTABLE} ${arg_PREPEND_FLAGS} ${arg_SRC_FILES} ${arg_APPEND_FLAGS}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running cppcheck source code static analysis checks.")
# hook our new target into the proper dependency chain
add_dependencies(cppcheck_check ${arg_NAME})
# Code check targets should only be run on demand
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endmacro(blt_add_cppcheck_target)
##------------------------------------------------------------------------------
## blt_add_astyle_target( NAME
## MODIFY_FILES [TRUE | FALSE (default)]
## CFG_FILE
## PREPEND_FLAGS
## APPEND_FLAGS
## COMMENT
## WORKING_DIRECTORY
## SRC_FILES [FILE1 [FILE2 ...]] )
##
## Creates a new target with the given NAME for running astyle over the given SRC_FILES.
##------------------------------------------------------------------------------
macro(blt_add_astyle_target)
## parse the arguments to the macro
set(options)
set(singleValueArgs NAME MODIFY_FILES CFG_FILE COMMENT WORKING_DIRECTORY)
set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} )
# Check/Set required parameters
if(NOT DEFINED arg_NAME)
message(FATAL_ERROR "blt_add_astyle_target requires a NAME parameter")
endif()
if(NOT DEFINED arg_CFG_FILE)
message(FATAL_ERROR "blt_add_astyle_target requires a CFG_FILE parameter")
endif()
if(NOT DEFINED arg_SRC_FILES)
message(FATAL_ERROR "blt_add_astyle_target requires a SRC_FILES parameter")
endif()
if(NOT DEFINED arg_MODIFY_FILES)
set(arg_MODIFY_FILES FALSE)
endif()
if(DEFINED arg_WORKING_DIRECTORY)
set(_wd ${arg_WORKING_DIRECTORY})
else()
set(_wd ${CMAKE_CURRENT_SOURCE_DIR})
endif()
set(_generate_target TRUE)
if(${arg_MODIFY_FILES})
set(MODIFY_FILES_FLAG --suffix=none)
else()
set(MODIFY_FILES_FLAG --dry-run)
# Check the version -- output is of the form "Artistic Style Version X.Y.Z"
execute_process(
COMMAND ${ASTYLE_EXECUTABLE} --version
OUTPUT_VARIABLE _version_str
ERROR_VARIABLE _version_str
OUTPUT_STRIP_TRAILING_WHITESPACE )
string(REGEX MATCH "([0-9]+(\\.)?)+$" _astyle_version ${_version_str})
# Skip 'check' target if version is not high enough
if(_astyle_version VERSION_LESS 2.05)
set(_generate_target FALSE)
message(WARNING "blt_add_astyle_target requires AStyle v2.05 or greater "
" for style check targets. "
" Current AStyle executable: '${ASTYLE_EXECUTABLE}' "
" Current AStyle version is: ${_astyle_version}." )
endif()
endif()
if(_generate_target)
# AStyle doesn't report failure when there are files that require formatting.
# Fix this with a wrapper script that parses the output.
set(wrapped_astyle_script ${CMAKE_CURRENT_BINARY_DIR}/WrapAstyle_${arg_NAME}.cmake)
configure_file(
${BLT_ROOT_DIR}/cmake/WrapAstyle.cmake.in
${wrapped_astyle_script}
@ONLY )
add_custom_target(
${arg_NAME}
COMMAND ${CMAKE_COMMAND} -P ${wrapped_astyle_script}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running AStyle source code formatting checks.")
# Hook our new target into the proper dependency chain
if(${arg_MODIFY_FILES})
add_dependencies(astyle_style ${arg_NAME})
else()
add_dependencies(astyle_check ${arg_NAME})
endif()
# Code formatting targets should only be run on demand
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endif()
endmacro(blt_add_astyle_target)
##------------------------------------------------------------------------------
## blt_add_clangformat_target( NAME
## MODIFY_FILES [TRUE | FALSE (default)]
## CFG_FILE
## PREPEND_FLAGS
## APPEND_FLAGS
## COMMENT
## WORKING_DIRECTORY
## SRC_FILES [FILE1 [FILE2 ...]] )
##
## Creates a new target with the given NAME for running ClangFormat over the given SRC_FILES.
##------------------------------------------------------------------------------
macro(blt_add_clangformat_target)
## parse the arguments to the macro
set(options)
set(singleValueArgs NAME MODIFY_FILES CFG_FILE COMMENT WORKING_DIRECTORY)
set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} )
# Check/Set required parameters
if(NOT DEFINED arg_NAME)
message(FATAL_ERROR "blt_add_clangformat_target requires a NAME parameter")
endif()
if(NOT DEFINED arg_CFG_FILE)
message(FATAL_ERROR "blt_add_clangformat_target requires a CFG_FILE parameter")
endif()
if(NOT DEFINED arg_SRC_FILES)
message(FATAL_ERROR "blt_add_clangformat_target requires a SRC_FILES parameter")
endif()
if(NOT DEFINED arg_MODIFY_FILES)
set(arg_MODIFY_FILES FALSE)
endif()
if(DEFINED arg_WORKING_DIRECTORY)
set(_wd ${arg_WORKING_DIRECTORY})
else()
set(_wd ${CMAKE_CURRENT_SOURCE_DIR})
endif()
set(_generate_target TRUE)
# Copy config file to given working directory since ClangFormat doesn't support pointing to one
configure_file(${arg_CFG_FILE} ${arg_WORKING_DIRECTORY}/.clang-format COPYONLY)
if(_generate_target)
# ClangFormat does not support --dry-run until version 10 which isn't on many machines.
# For now, use run-clang-format for dry running purposes.
if(${arg_MODIFY_FILES})
add_custom_target(${arg_NAME}
COMMAND ${CLANGFORMAT_EXECUTABLE} ${arg_PREPEND_FLAGS}
--style=file -i ${arg_SRC_FILES} ${arg_APPEND_FLAGS}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running ClangFormat source code formatting checks.")
else()
set(_run_clangformat "${BLT_ROOT_DIR}/cmake/run-clang-format.py" --clang-format-executable ${CLANGFORMAT_EXECUTABLE})
add_custom_target(${arg_NAME}
COMMAND ${_run_clangformat} -j1 ${arg_SRC_FILES}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running ClangFormat source code formatting checks.")
endif()
# Hook our new target into the proper dependency chain
if(${arg_MODIFY_FILES})
add_dependencies(clangformat_style ${arg_NAME})
else()
add_dependencies(clangformat_check ${arg_NAME})
endif()
# Code formatting targets should only be run on demand
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endif()
endmacro(blt_add_clangformat_target)
##------------------------------------------------------------------------------
## blt_add_uncrustify_target( NAME
## MODIFY_FILES [TRUE | FALSE (default)]
## CFG_FILE
## PREPEND_FLAGS
## APPEND_FLAGS
## COMMENT
## WORKING_DIRECTORY
## SRC_FILES [FILE1 [FILE2 ...]] )
##
## Creates a new target with the given NAME for running uncrustify over the given SRC_FILES.
##------------------------------------------------------------------------------
macro(blt_add_uncrustify_target)
## parse the arguments to the macro
set(options)
set(singleValueArgs NAME MODIFY_FILES CFG_FILE COMMENT WORKING_DIRECTORY)
set(multiValueArgs SRC_FILES PREPEND_FLAGS APPEND_FLAGS)
cmake_parse_arguments(arg
"${options}" "${singleValueArgs}" "${multiValueArgs}" ${ARGN} )
# Check/Set required parameters
if(NOT DEFINED arg_NAME)
message(FATAL_ERROR "blt_add_uncrustify_target requires a NAME parameter")
endif()
if(NOT DEFINED arg_CFG_FILE)
message(FATAL_ERROR "blt_add_uncrustify_target requires a CFG_FILE parameter")
endif()
if(NOT DEFINED arg_SRC_FILES)
message(FATAL_ERROR "blt_add_uncrustify_target requires a SRC_FILES parameter")
endif()
if(NOT DEFINED arg_MODIFY_FILES)
set(arg_MODIFY_FILES FALSE)
endif()
if(DEFINED arg_WORKING_DIRECTORY)
set(_wd ${arg_WORKING_DIRECTORY})
else()
set(_wd ${CMAKE_CURRENT_SOURCE_DIR})
endif()
set(_generate_target TRUE)
if(${arg_MODIFY_FILES})
set(MODIFY_FILES_FLAG --replace;--no-backup)
else()
set(MODIFY_FILES_FLAG "--check")
# Check the version -- output is of the form "uncrustify X.Y.Z"
execute_process(
COMMAND ${UNCRUSTIFY_EXECUTABLE} --version
OUTPUT_VARIABLE _version_str
OUTPUT_STRIP_TRAILING_WHITESPACE )
string(REGEX MATCH "([0-9]+(\\.)?)+(_[a-zA-Z])?" _uncrustify_version ${_version_str})
# Skip 'check' target if version is not high enough
if(_uncrustify_version VERSION_LESS 0.61)
set(_generate_target FALSE)
message(WARNING "blt_add_uncrustify_target requires uncrustify v0.61 or greater "
" for style check targets. "
" Current uncrustify executable: '${UNCRUSTIFY_EXECUTABLE}' "
" Current uncrustify version is: ${_uncrustify_version}." )
endif()
endif()
if(_generate_target)
add_custom_target(${arg_NAME}
COMMAND ${UNCRUSTIFY_EXECUTABLE} ${arg_PREPEND_FLAGS}
-c ${arg_CFG_FILE} ${MODIFY_FILES_FLAG} ${arg_SRC_FILES} ${arg_APPEND_FLAGS}
WORKING_DIRECTORY ${_wd}
COMMENT "${arg_COMMENT}Running uncrustify source code formatting checks.")
# hook our new target into the proper dependency chain
if(${arg_MODIFY_FILES})
add_dependencies(uncrustify_style ${arg_NAME})
else()
add_dependencies(uncrustify_check ${arg_NAME})
endif()
# Code formatting targets should only be run on demand
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
set_property(TARGET ${arg_NAME} PROPERTY EXCLUDE_FROM_DEFAULT_BUILD TRUE)
endif()
endmacro(blt_add_uncrustify_target)