summaryrefslogtreecommitdiffstats
path: root/config/sanitizer/formatting.cmake
blob: 677a69a3749d20818b6d4cc7eb1fa3d8c9adea77 (plain)
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
#
# Copyright (C) 2019 by George Cave - gcave@stablecoder.ca
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

#
# clang-format
#
find_program(CLANG_FORMAT_EXE "clang-format")
mark_as_advanced(FORCE CLANG_FORMAT_EXE)
if(CLANG_FORMAT_EXE)
  message(STATUS "clang-format found: ${CLANG_FORMAT_EXE}")
else()
  message(STATUS "clang-format not found!")
endif()

# Generates a 'format' target using a custom name, files, and include
# directories all being parameters.
#
# Do note that in order for sources to be inherited properly, the source paths
# must be reachable from where the macro is called, or otherwise require a full
# path for proper inheritance.
#
# ~~~
# Required:
# TARGET_NAME - The name of the target to create.
#
# Optional: ARGN - The list of targets OR files to format. Relative and absolute
# paths are accepted.
# ~~~
function(clang_format TARGET_NAME)
  if(CLANG_FORMAT_EXE)
    set(FORMAT_FILES)
    # Check through the ARGN's, determine existent files
    foreach(item IN LISTS ARGN)
      if(TARGET ${item})
        # If the item is a target, then we'll attempt to grab the associated
        # source files from it.
        get_target_property(_TARGET_TYPE ${item} TYPE)
        if(NOT
           _TARGET_TYPE
           STREQUAL
           "INTERFACE_LIBRARY")
          get_property(
            _TEMP
            TARGET ${item}
            PROPERTY SOURCES)
          foreach(iter IN LISTS _TEMP)
            if(EXISTS ${iter})
              set(FORMAT_FILES ${FORMAT_FILES} ${iter})
            endif()
          endforeach()
        endif()
      elseif(EXISTS ${item})
        # Check if it's a full file path
        set(FORMAT_FILES ${FORMAT_FILES} ${item})
      elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${item})
        # Check if it's based on the current source dir
        set(FORMAT_FILES ${FORMAT_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/${item})
      endif()
    endforeach()

    # Make the target
    if(FORMAT_FILES)
      if(TARGET ${TARGET_NAME})
        message(
          ERROR
          "Cannot create clang-format target '${TARGET_NAME}', already exists.")
      else()
        add_custom_target(${TARGET_NAME} COMMAND ${CLANG_FORMAT_EXE} -i -style=file ${FORMAT_FILES})

        if(NOT TARGET format)
          add_custom_target(format)
        endif()

        add_dependencies(format ${TARGET_NAME})
      endif()
    endif()

  endif()
endfunction()

#
# cmake-format
#
find_program(CMAKE_FORMAT_EXE "cmake-format")
mark_as_advanced(FORCE CMAKE_FORMAT_EXE)
if(CMAKE_FORMAT_EXE)
  message(STATUS "cmake-format found: ${CMAKE_FORMAT_EXE}")
else()
  message(STATUS "cmake-format not found!")
endif()

# When called, this function will call 'cmake-format' program on all listed
# files (if both the program and the files exist and are found)
# ~~~
# Required:
# TARGET_NAME - The name of the target to create.
#
# Optional:
# ARGN - Any  arguments passed in will be considered as 'files' to perform the
# formatting on. Any items that are not files will be ignored. Both relative and
# absolute paths are accepted.
# ~~~
function(cmake_format TARGET_NAME)
  if(CMAKE_FORMAT_EXE)
    set(FORMAT_FILES)
    # Determine files that exist
    foreach(iter IN LISTS ARGN)
      if(EXISTS ${iter})
        set(FORMAT_FILES ${FORMAT_FILES} ${iter})
      elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${iter})
        set(FORMAT_FILES ${FORMAT_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/${iter})
      endif()
    endforeach()

    # Generate target
    if(FORMAT_FILES)
      if(TARGET ${TARGET_NAME})
        message(
          ERROR
          "Cannot create cmake-format target '${TARGET_NAME}', already exists.")
      else()
        add_custom_target(${TARGET_NAME} COMMAND ${CMAKE_FORMAT_EXE} -i
                                                 ${FORMAT_FILES})

        if(NOT TARGET cmake-format)
          add_custom_target(cmake-format)
        endif()
        add_dependencies(cmake-format ${TARGET_NAME})
      endif()
    endif()
  endif()
endfunction()