[libc][NFC] Move aligned access implementations to separate header
[llvm-project.git] / libc / cmake / modules / LLVMLibCArchitectures.cmake
blob1e53e1a2b60bf84c4ec1eb6488ccafac5290122b
1 # ------------------------------------------------------------------------------
2 # Architecture and OS definitions.
4 # The correct target OS and architecture to build the libc for is deduced here.
5 # When possible, we also setup appropriate compile options for the target
6 # platform.
7 # ------------------------------------------------------------------------------
9 if(LIBC_GPU_BUILD OR LIBC_GPU_ARCHITECTURES)
10   # We set the generic target and OS to "gpu" here. More specific defintions
11   # for the exact target GPU are set up in prepare_libc_gpu_build.cmake.
12   set(LIBC_TARGET_OS "gpu")
13   set(LIBC_TARGET_ARCHITECTURE_IS_GPU TRUE)
14   set(LIBC_TARGET_ARCHITECTURE "gpu")
15   if(LIBC_TARGET_TRIPLE)
16     message(WARNING "LIBC_TARGET_TRIPLE is ignored as LIBC_GPU_BUILD is on. ")
17   endif()
18   return()
19 endif()
21 if(MSVC)
22   # If the compiler is visual c++ or equivalent, we will assume a host build.
23   set(LIBC_TARGET_OS ${CMAKE_HOST_SYSTEM_NAME})
24   string(TOLOWER ${LIBC_TARGET_OS} LIBC_TARGET_OS)
25   set(LIBC_TARGET_ARCHITECTURE ${CMAKE_HOST_SYSTEM_PROCESSOR})
26   if(LIBC_TARGET_TRIPLE)
27     message(WARNING "libc build: Detected MSVC or equivalent compiler; "
28                     "LIBC_TARGET_TRIPLE is ignored and a host build is assumed.")
29   endif()
30   return()
31 endif()
33 # A helper function to get the architecture and system components from a target
34 # triple.
35 function(get_arch_and_system_from_triple triple arch_var sys_var)
36   string(REPLACE "-" ";" triple_comps ${triple})
37   list(LENGTH triple_comps triple_size)
38   if(triple_size LESS "3")
39     return()
40   endif()
41   math(EXPR system_index "${triple_size} - 2")
42   list(GET triple_comps 0 target_arch)
43   # The target_arch string can have sub-architecture suffixes which we want to
44   # remove. So, we regex-match the string and set target_arch to a cleaner
45   # value.
46   if(target_arch MATCHES "^mips")
47     set(target_arch "mips")
48   elseif(target_arch MATCHES "^arm")
49     # TODO(lntue): Shall we separate `arm64`?  It is currently recognized as
50     # `arm` here.
51     set(target_arch "arm")
52   elseif(target_arch MATCHES "^aarch64")
53     set(target_arch "aarch64")
54   elseif(target_arch MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
55     set(target_arch "x86_64")
56   elseif(target_arch MATCHES "^(powerpc|ppc)")
57     set(target_arch "power")
58   elseif(target_arch MATCHES "^riscv32")
59     set(target_arch "riscv32")
60   elseif(target_arch MATCHES "^riscv64")
61     set(target_arch "riscv64")
62   else()
63     return()
64   endif()
66   set(${arch_var} ${target_arch} PARENT_SCOPE)
67   list(GET triple_comps ${system_index} target_sys)
69   # Correcting OS name for Apple's systems.
70   if(target_sys STREQUAL "apple")
71     list(GET triple_comps 2 target_sys)
72   endif()
73   # Strip version from `darwin###`
74   if(target_sys MATCHES "^darwin")
75     set(target_sys "darwin")
76   endif()
78   set(${sys_var} ${target_sys} PARENT_SCOPE)
79 endfunction(get_arch_and_system_from_triple)
81 execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version -v
82                 RESULT_VARIABLE libc_compiler_info_result
83                 OUTPUT_VARIABLE libc_compiler_info
84                 ERROR_VARIABLE libc_compiler_info)
85 if(NOT (libc_compiler_info_result EQUAL "0"))
86   message(FATAL_ERROR "libc build: error querying compiler info from the "
87                       "compiler: ${libc_compiler_info}")
88 endif()
89 string(REGEX MATCH "Target: [-_a-z0-9.]+[ \r\n]+"
90        libc_compiler_target_info ${libc_compiler_info})
91 if(NOT libc_compiler_target_info)
92   message(FATAL_ERROR "libc build: could not read compiler target info from:\n"
93                       "${libc_compiler_info}")
94 endif()
95 string(STRIP ${libc_compiler_target_info} libc_compiler_target_info)
96 string(SUBSTRING ${libc_compiler_target_info} 8 -1 libc_compiler_triple)
97 get_arch_and_system_from_triple(${libc_compiler_triple}
98                                 compiler_arch compiler_sys)
99 if(NOT compiler_arch)
100   message(FATAL_ERROR
101           "libc build: Invalid or unknown libc compiler target triple: "
102           "${libc_compiler_triple}")
103 endif()
105 set(LIBC_TARGET_ARCHITECTURE ${compiler_arch})
106 set(LIBC_TARGET_OS ${compiler_sys})
107 set(LIBC_CROSSBUILD FALSE)
109 # One should not set LLVM_RUNTIMES_TARGET and LIBC_TARGET_TRIPLE
110 if(LLVM_RUNTIMES_TARGET AND LIBC_TARGET_TRIPLE)
111   message(FATAL_ERROR
112           "libc build: Specify only LLVM_RUNTIMES_TARGET if you are doing a "
113           "runtimes/bootstrap build. If you are doing a standalone build, "
114           "specify only LIBC_TARGET_TRIPLE.")
115 endif()
117 set(explicit_target_triple)
118 if(LLVM_RUNTIMES_TARGET)
119   set(explicit_target_triple ${LLVM_RUNTIMES_TARGET})
120 elseif(LIBC_TARGET_TRIPLE)
121   set(explicit_target_triple ${LIBC_TARGET_TRIPLE})
122 endif()
124 # The libc's target architecture and OS are set to match the compiler's default
125 # target triple above. However, one can explicitly set LIBC_TARGET_TRIPLE or
126 # LLVM_RUNTIMES_TARGET (for runtimes/bootstrap build). If one of them is set,
127 # then we will use that target triple to deduce libc's target OS and
128 # architecture.
129 if(explicit_target_triple)
130   get_arch_and_system_from_triple(${explicit_target_triple} libc_arch libc_sys)
131   if(NOT libc_arch)
132     message(FATAL_ERROR
133             "libc build: Invalid or unknown triple: ${explicit_target_triple}")
134   endif()
135   set(LIBC_TARGET_ARCHITECTURE ${libc_arch})
136   set(LIBC_TARGET_OS ${libc_sys})
137 endif()
139 if((LIBC_TARGET_OS STREQUAL "unknown") OR (LIBC_TARGET_OS STREQUAL "none"))
140   # We treat "unknown" and "none" systems as baremetal targets.
141   set(LIBC_TARGET_OS "baremetal")
142 endif()
144 # Set up some convenient vars to make conditionals easy to use in other parts of
145 # the libc CMake infrastructure. Also, this is where we also check if the target
146 # architecture is currently supported.
147 if(LIBC_TARGET_ARCHITECTURE STREQUAL "arm")
148   set(LIBC_TARGET_ARCHITECTURE_IS_ARM TRUE)
149 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "aarch64")
150   set(LIBC_TARGET_ARCHITECTURE_IS_AARCH64 TRUE)
151 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
152   set(LIBC_TARGET_ARCHITECTURE_IS_X86 TRUE)
153 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv32")
154   set(LIBC_TARGET_ARCHITECTURE_IS_RISCV32 TRUE)
155 elseif(LIBC_TARGET_ARCHITECTURE STREQUAL "riscv64")
156   set(LIBC_TARGET_ARCHITECTURE_IS_RISCV64 TRUE)
157 else()
158   message(FATAL_ERROR
159           "Unsupported libc target architecture ${LIBC_TARGET_ARCHITECTURE}")
160 endif()
162 if(LIBC_TARGET_OS STREQUAL "baremetal")
163   set(LIBC_TARGET_OS_IS_BAREMETAL TRUE)
164 elseif(LIBC_TARGET_OS STREQUAL "linux")
165   set(LIBC_TARGET_OS_IS_LINUX TRUE)
166 elseif(LIBC_TARGET_OS STREQUAL "darwin")
167   set(LIBC_TARGET_OS_IS_DARWIN TRUE)
168 elseif(LIBC_TARGET_OS STREQUAL "windows")
169   set(LIBC_TARGET_OS_IS_WINDOWS TRUE)
170 else()
171   message(FATAL_ERROR
172           "Unsupported libc target operating system ${LIBC_TARGET_OS}")
173 endif()
176 # If the compiler target triple is not the same as the triple specified by
177 # LIBC_TARGET_TRIPLE or LLVM_RUNTIMES_TARGET, we will add a --target option
178 # if the compiler is clang. If the compiler is GCC we just error out as there
179 # is no equivalent of an option like --target.
180 if(explicit_target_triple AND
181    (NOT (libc_compiler_triple STREQUAL explicit_target_triple)))
182   set(LIBC_CROSSBUILD TRUE)
183   if(CMAKE_COMPILER_IS_GNUCXX)
184     message(FATAL_ERROR
185             "GCC target triple (${libc_compiler_triple}) and the explicity "
186             "specified target triple (${explicit_target_triple}) do not match.")
187   else()
188     list(APPEND
189          LIBC_COMPILE_OPTIONS_DEFAULT "--target=${explicit_target_triple}")
190   endif()
191 endif()
193 message(STATUS
194         "Building libc for ${LIBC_TARGET_ARCHITECTURE} on ${LIBC_TARGET_OS}")