summaryrefslogtreecommitdiffstats
path: root/Tests/RunCMake/LinkWarningAsError/WarnError.cmake
blob: 6e336ddf619700b3cf8d526c270a930cce42f189 (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

set(linkWarning "${link_warning_as_error}")
if (DEFINED CMAKE_LINK_WARNING_AS_ERROR)
  set(linkWarning "${CMAKE_LINK_WARNING_AS_ERROR}")
endif()
if (linkWarning STREQUAL "ON")
  set (linkWarning DRIVER LINKER)
endif()

if((linkWarning STREQUAL "DRIVER;LINKER" AND NOT CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR
      AND NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR)
    OR (linkWarning STREQUAL "DRIVER" AND NOT CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR)
    OR (linkWarning STREQUAL "LINKER" AND NOT CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR))
  set(WarnErrorFlags "UNDEFINED")
else()
  set(cfg_dir)
  get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
  if(_isMultiConfig)
    set(cfg_dir /Debug)
  endif()
  set(DUMP_EXE "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/dump${CMAKE_EXECUTABLE_SUFFIX}")

  add_executable(dump dump.c)
  set_property(TARGET dump PROPERTY LINK_WARNING_AS_ERROR OFF)

  # ensure no temp file nor response file will be used
  set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
  string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")
  string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE}")

  add_executable(main main.c)
  if(CMAKE_GENERATOR MATCHES "FASTBuild")
    # FASTBuild needs output to exist.
    file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}/main${CMAKE_EXECUTABLE_SUFFIX}")
  endif()
  if (NOT DEFINED CMAKE_LINK_WARNING_AS_ERROR)
    set_property(TARGET main PROPERTY LINK_WARNING_AS_ERROR ${link_warning_as_error})
  endif()
  # use LAUNCH facility to dump linker command
  set_property(TARGET main PROPERTY RULE_LAUNCH_LINK "\"${DUMP_EXE}\"")

  add_dependencies(main dump)

  # generate reference for WARNING_AS_ERROR flag
  unset(compiler_WarnError)
  unset(linker_WarnError)
  unset(WarnErrorFlags)
  ## DRIVER
  if (CMAKE_C_LINK_MODE STREQUAL "DRIVER")
    list(JOIN CMAKE_C_COMPILE_OPTIONS_WARNING_AS_ERROR " " compiler_WarnError)
  endif()
  ## LINKER
  string(REPLACE "LINKER:" "" linker_WarnError "${CMAKE_C_LINK_OPTIONS_WARNING_AS_ERROR}")
  if (CMAKE_C_LINKER_WRAPPER_FLAG)
    set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
    list(GET linker_flag -1 linker_space)
    if (linker_space STREQUAL " ")
      list(REMOVE_AT linker_flag -1)
    else()
      set(linker_space)
    endif()
    list(JOIN linker_flag " " linker_flag)
    if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
      string(REPLACE "," "${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}" linker_WarnError "${linker_WarnError}")
      set(linker_WarnError "${linker_flag}${linker_space}${linker_WarnError}")
    else()
      set(linker_prefix "${linker_flag}${linker_space}")
      string(REPLACE "," ";" linker_WarnError "${linker_WarnError}")
      list(TRANSFORM linker_WarnError PREPEND "${linker_prefix}")
      list(JOIN linker_WarnError " " linker_WarnError)
    endif()
  else()
    string(REPLACE "," " " linker_WarnError "${linker_WarnError}")
  endif()

  # Add regex [^-] to avoid matching of MSVC compiler flag -WX-
  if(linkWarning STREQUAL "DRIVER;LINKER")
    set(WarnErrorFlags "${compiler_WarnError}")
    if (WarnErrorFlags)
      string(APPEND WarnErrorFlags " ${linker_WarnError}[^-]")
    else()
      set(WarnErrorFlags "${linker_WarnError}[^-]")
    endif()
  elseif(linkWarning STREQUAL "DRIVER")
    set(WarnErrorFlags "${compiler_WarnError}[^-]")
  elseif(linkWarning STREQUAL "LINKER")
    set(WarnErrorFlags "${linker_WarnError}[^-]")
  else()
    # OFF value
    if(compiler_WarnError AND linker_WarnError)
        set(WarnErrorFlags "(${compiler_WarnError}[^-]|${linker_WarnError}[^-])+")
    elseif(compiler_WarnError)
      set(WarnErrorFlags "${compiler_WarnError}[^-]")
    elseif(linker_WarnError)
      set(WarnErrorFlags "${linker_WarnError}[^-]")
    endif()
    if(NOT WarnErrorFlags)
      set(WarnErrorFlags "UNDEFINED")
    endif()
  endif()
endif()
if(CMAKE_GENERATOR MATCHES "Visual Studio")
  # replace '-' with '/' for options
  string(REGEX REPLACE "-([A-Z]+)" "[-/]\\1" WarnErrorFlags "${WarnErrorFlags}")
endif()

file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/WARNING_AS_ERROR.txt" "${WarnErrorFlags}")