summaryrefslogtreecommitdiffstats
path: root/Modules/Compiler/ARMClang.cmake
blob: f100af8435086f0baf409dd777a7e5236f730453 (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
if(_ARMClang_CMAKE_LOADED)
  return()
endif()
set(_ARMClang_CMAKE_LOADED TRUE)

cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST

get_filename_component(_CMAKE_C_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
get_filename_component(_CMAKE_CXX_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)

set(CMAKE_EXECUTABLE_SUFFIX ".elf")

find_program(CMAKE_ARMClang_LINKER armlink HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )
find_program(CMAKE_ARMClang_AR     armar   HINTS "${_CMAKE_C_TOOLCHAIN_LOCATION}" "${_CMAKE_CXX_TOOLCHAIN_LOCATION}" )

set(CMAKE_LINKER "${CMAKE_ARMClang_LINKER}" CACHE FILEPATH "The ARMClang linker" FORCE)
mark_as_advanced(CMAKE_ARMClang_LINKER)
set(CMAKE_AR "${CMAKE_ARMClang_AR}" CACHE FILEPATH "The ARMClang archiver" FORCE)
mark_as_advanced(CMAKE_ARMClang_AR)

if (CMAKE_LINKER MATCHES "armlink")
  set(__CMAKE_ARMClang_USING_armlink TRUE)
  set(CMAKE_LIBRARY_PATH_FLAG "--userlibpath=")
else()
  set(__CMAKE_ARMClang_USING_armlink FALSE)
endif()

# get compiler supported cpu list
function(__armclang_set_processor_list lang out_var)
  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" --target=${CMAKE_${lang}_COMPILER_TARGET} -mcpu=list
    OUTPUT_VARIABLE processor_list
    ERROR_VARIABLE processor_list)
  string(REGEX MATCHALL "-mcpu=([^ \n]*)" processor_list "${processor_list}")
  string(REGEX REPLACE "-mcpu=" "" processor_list "${processor_list}")
  set(${out_var} "${processor_list}" PARENT_SCOPE)
endfunction()

# check processor is in list
function(__armclang_check_processor processor list out_var)
  string(TOLOWER "${processor}" processor)
  if(processor IN_LIST list)
    set(${out_var} TRUE PARENT_SCOPE)
  else()
    set(${out_var} FALSE PARENT_SCOPE)
  endif()
endfunction()

# get compiler supported arch list
function(__armclang_set_arch_list lang out_var)
  execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" --target=${CMAKE_${lang}_COMPILER_TARGET} -march=list
    OUTPUT_VARIABLE arch_list
    ERROR_VARIABLE arch_list)
  string(REGEX MATCHALL "-march=([^ \n]*)" arch_list "${arch_list}")
  string(REGEX REPLACE "-march=" "" arch_list "${arch_list}")
  set(${out_var} "${arch_list}" PARENT_SCOPE)
endfunction()

# get linker supported cpu list
function(__armlink_set_cpu_list lang out_var)
  if(__CMAKE_ARMClang_USING_armlink)
    set(__linker_wrapper_flags "")
  else()
    set(__linker_wrapper_flags --target=${CMAKE_${lang}_COMPILER_TARGET} -Xlinker)
  endif()

  execute_process(COMMAND "${CMAKE_LINKER}" ${__linker_wrapper_flags} --cpu=list
    OUTPUT_VARIABLE cpu_list
    ERROR_VARIABLE cpu_list)
  string(REGEX MATCHALL "--cpu=([^ \n]*)" cpu_list "${cpu_list}")
  string(REGEX REPLACE "--cpu=" "" cpu_list "${cpu_list}")
  set(${out_var} "${cpu_list}" PARENT_SCOPE)
endfunction()

macro(__compiler_armclang lang)
  if(NOT CMAKE_${lang}_COMPILER_TARGET)
    set(CMAKE_${lang}_COMPILER_TARGET arm-arm-none-eabi)
  endif()
  if(NOT CMAKE_${lang}_COMPILER_PROCESSOR_LIST)
    __armclang_set_processor_list(${lang} CMAKE_${lang}_COMPILER_PROCESSOR_LIST)
  endif()
  if(NOT CMAKE_${lang}_COMPILER_ARCH_LIST)
    __armclang_set_arch_list(${lang} CMAKE_${lang}_COMPILER_ARCH_LIST)
  endif()
  if(NOT CMAKE_SYSTEM_PROCESSOR AND NOT CMAKE_SYSTEM_ARCH)
    message(FATAL_ERROR "  CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
      "  Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n"
      "  Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}")
  else()
    __armclang_check_processor("${CMAKE_SYSTEM_ARCH}" "${CMAKE_${lang}_COMPILER_ARCH_LIST}" _CMAKE_${lang}_CHECK_ARCH_RESULT)
    if( _CMAKE_${lang}_CHECK_ARCH_RESULT)
      string(APPEND CMAKE_${lang}_FLAGS_INIT "-march=${CMAKE_SYSTEM_ARCH}")
      set(__march_flag_set TRUE)
    endif()
    __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}" _CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
    if(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
      string(APPEND CMAKE_${lang}_FLAGS_INIT "-mcpu=${CMAKE_SYSTEM_PROCESSOR}")
      set(__mcpu_flag_set TRUE)
    endif()
    if(NOT __march_flag_set AND NOT __mcpu_flag_set)
      message(FATAL_ERROR "Atleast one of the variables CMAKE_SYSTEM_PROCESSOR or CMAKE_SYSTEM_ARCH must be set for ARMClang\n"
                          "Supported processor: ${CMAKE_${lang}_COMPILER_PROCESSOR_LIST}\n"
                          "  Supported Architecture: ${CMAKE_${lang}_COMPILER_ARCH_LIST}")
    endif()
    unset(_CMAKE_${lang}_CHECK_PROCESSOR_RESULT)
    unset(_CMAKE_${lang}_CHECK_ARCH_RESULT)
  endif()

  #check if CMAKE_SYSTEM_PROCESSOR belongs to supported cpu list for armlink
  __armlink_set_cpu_list( ${lang} CMAKE_LINKER_CPU_LIST)
  list(TRANSFORM CMAKE_LINKER_CPU_LIST TOLOWER)
  __armclang_check_processor("${CMAKE_SYSTEM_PROCESSOR}" "${CMAKE_LINKER_CPU_LIST}" _CMAKE_CHECK_LINK_CPU_RESULT)
  if(_CMAKE_CHECK_LINK_CPU_RESULT)
    string(APPEND CMAKE_${lang}_LINK_FLAGS "--cpu=${CMAKE_SYSTEM_PROCESSOR}")
  endif()

  if(__CMAKE_ARMClang_USING_armlink)
    unset(CMAKE_${lang}_LINKER_WRAPPER_FLAG)
    set(__CMAKE_ARMClang_USING_armlink_WRAPPER "")
  else()
    set(__CMAKE_ARMClang_USING_armlink_WRAPPER "-Xlinker")
  endif()
  set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> <OBJECTS> -o <TARGET> ${__CMAKE_ARMClang_USING_armlink_WRAPPER} --list=<TARGET_BASE>.map")
  set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
  set(CMAKE_${lang}_ARCHIVE_CREATE         "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
  set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "${__CMAKE_ARMClang_USING_armlink_WRAPPER} --via=")
  set(CMAKE_${lang}_OUTPUT_EXTENSION ".o")
  set(CMAKE_${lang}_OUTPUT_EXTENSION_REPLACE 1)
endmacro()

cmake_policy(POP)