Skip to content

Commit f5dc324

Browse files
committed
scripts: Add initial Zephyr SDK LLVM build script
This commit adds the Zephyr SDK LLVM build script that builds the Clang/LLVM toolchain as well as the compiler runtime and C/C++ standard libraries for Arm architecture. The build script is based on the LLVM Embedded Toolchain for Arm [1] build script. [1] https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm Signed-off-by: Stephanos Ioannidis <[email protected]>
1 parent 2af738c commit f5dc324

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3926
-0
lines changed

scripts/llvm/CMakeLists.txt

Lines changed: 2038 additions & 0 deletions
Large diffs are not rendered by default.

scripts/llvm/Omax.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--sysroot <CFGDIR>/../lib/clang-runtimes/newlib

scripts/llvm/OmaxLTO.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-flto=full \
2+
-fvirtual-function-elimination \
3+
-fwhole-program-vtables
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
This product embeds and uses the following pieces of software which have
2+
additional or alternate licenses:
3+
- LLVM: third-party-licenses/LLVM-LICENSE.txt
4+
- Clang: third-party-licenses/CLANG-LICENSE.txt
5+
- lld: third-party-licenses/LLD-LICENSE.txt
6+
- compiler-rt: third-party-licenses/COMPILER-RT-LICENSE.txt
7+
- libc++: third-party-licenses/LIBCXX-LICENSE.txt
8+
- libc++abi: third-party-licenses/LIBCXXABI-LICENSE.txt
9+
- libunwind: third-party-licenses/LIBUNWIND-LICENSE.txt
10+
- Picolibc: third-party-licenses/COPYING.NEWLIB, third-party-licenses/COPYING.picolibc${mingw_runtime_dlls}
11+
12+
Picolibc licenses refer to its source files. Sources are identified in VERSION.txt.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# Exit immediately if a command exits with a non-zero status.
4+
set -e
5+
6+
# Handle symlinks such as clang++ when cross-building to Windows.
7+
# CPack supports putting symlinks in zip files but to Windows they
8+
# just look like a file containing text like "clang".
9+
10+
# 1. Convert required symlinks to regular files.
11+
for name in \
12+
clang++ \
13+
clang-cpp \
14+
ld.lld \
15+
llvm-ranlib \
16+
llvm-readelf \
17+
llvm-strip
18+
do
19+
ln -f $(realpath -m "bin/${name}.exe") bin/${name}.exe
20+
done
21+
22+
# 2. Remove remaining symlinks
23+
find -type l -exec rm {} +
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[binaries]
2+
c = [@meson_c_args@, '-nostdlib']
3+
ar = '@LLVM_BINARY_DIR@/bin/llvm-ar@CMAKE_EXECUTABLE_SUFFIX@'
4+
strip = '@LLVM_BINARY_DIR@/bin/llvm-strip@CMAKE_EXECUTABLE_SUFFIX@'
5+
# only needed to run tests
6+
# setting stdin to /dev/null prevents qemu from fiddling with the echo bit of
7+
# the parent terminal
8+
exe_wrapper = [
9+
'sh',
10+
'-c',
11+
'test -z "$PICOLIBC_TEST" || @test_executor_bin@ "$@" < /dev/null',
12+
'@test_executor_bin@',
13+
@test_executor_params@]
14+
15+
[host_machine]
16+
system = 'none'
17+
cpu_family = '@cpu_family@'
18+
cpu = '@cpu_family@'
19+
endian = 'little'
20+
21+
[properties]
22+
skip_sanity_check = true
23+
libgcc ='-lclang_rt.builtins'
24+
separate_boot_flash = true
25+
default_boot_flash_addr = '@default_boot_flash_addr@'
26+
default_boot_flash_size = '@default_boot_flash_size@'
27+
default_flash_addr = '@default_flash_addr@'
28+
default_flash_size = '@default_flash_size@'
29+
default_ram_addr = '@default_ram_addr@'
30+
default_ram_size = '@default_ram_size@'
31+
default_stack_size = '@default_stack_size@'
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#
2+
# Copyright (c) 2023, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# If you're reading this file under the name 'multilib.yaml.in' in the
19+
# Zephyr SDK source tree, then it's not valid YAML in its own right: it's a
20+
# template that CMakeLists.txt will expand into a real 'multilib.yaml'
21+
# containing a list of library variants and the flags that will select them.
22+
#
23+
# If you're reading it under the name 'multilib.yaml' in the build or
24+
# install directory, then that substitution has been done.
25+
#
26+
# Comments in this file mostly make more sense from the
27+
# multilib.yaml.in point of view.
28+
29+
MultilibVersion: '1.0'
30+
31+
# Make an exclusive group for library variants, to make sure we don't
32+
# accidentally include two or more variants at once.
33+
#
34+
# Even if they all match the command-line options, putting two sets of
35+
# include directories on the include path can cause build failure,
36+
# because of the #include_next used in the libc++ headers. The first
37+
# libc++ stdio.h (for example) will #include_next <stdio.h>, which
38+
# will find the second libc++ version. That won't do anything at all,
39+
# because it has the same include-guard macro as the first, and so
40+
# nothing will ever include the _libc_ stdio.h, which was what the
41+
# #include_next was really looking for.
42+
Groups:
43+
- Name: stdlibs
44+
Type: Exclusive
45+
46+
# The list of library variants is substituted in by CMakeLists.txt, so
47+
# that it can respect the LLVM_TOOLCHAIN_LIBRARY_VARIANTS setting and
48+
# only include the set of libraries actually included in this build.
49+
50+
Variants:
51+
@multilib_yaml_content@
52+
53+
Mappings:
54+
55+
# Map higher architecture versions to subsets of them, so that a
56+
# compatible library can be found even for architectures we don't have
57+
# specific variants for.
58+
59+
# v8-M Baseline is a superset of v6-M
60+
- Match: --target=thumbv8m\.base-unknown-none-eabi
61+
Flags:
62+
- --target=thumbv6m-unknown-none-eabi
63+
64+
# v8.2-M Mainline is a superset of v8.1-M Mainline, in both hard and
65+
# soft float variants.
66+
#
67+
# Also, v8.1-M Mainline is also a superset of v8-M Mainline, which in
68+
# turn is a superset of v7E-M, and then of plain v7-M. We have
69+
# libraries for all those architecture versions, but not for every
70+
# combination of them with FPUs, so in some cases it might be
71+
# necessary to fall back to a lower architecture in order to provide
72+
# the needed FPU support.
73+
- Match: --target=thumbv8\.[2-9]m\.main-unknown-none-eabi
74+
Flags:
75+
- --target=thumbv8.1m.main-unknown-none-eabi
76+
- --target=thumbv8m.main-unknown-none-eabi
77+
- --target=thumbv7em-unknown-none-eabi
78+
- --target=thumbv7m-unknown-none-eabi
79+
- Match: --target=thumbv8\.[2-9]m\.main-unknown-none-eabihf
80+
Flags:
81+
- --target=thumbv8.1m.main-unknown-none-eabihf
82+
- --target=thumbv8m.main-unknown-none-eabihf
83+
- --target=thumbv7em-unknown-none-eabihf
84+
- --target=thumbv7m-unknown-none-eabihf
85+
- Match: --target=thumbv8\.1m\.main-unknown-none-eabi
86+
Flags:
87+
- --target=thumbv8m.main-unknown-none-eabi
88+
- --target=thumbv7em-unknown-none-eabi
89+
- --target=thumbv7m-unknown-none-eabi
90+
- Match: --target=thumbv8\.1m\.main-unknown-none-eabihf
91+
Flags:
92+
- --target=thumbv8m.main-unknown-none-eabihf
93+
- --target=thumbv7em-unknown-none-eabihf
94+
- --target=thumbv7m-unknown-none-eabihf
95+
- Match: --target=thumbv8m\.main-unknown-none-eabi
96+
Flags:
97+
- --target=thumbv7em-unknown-none-eabi
98+
- --target=thumbv7m-unknown-none-eabi
99+
- Match: --target=thumbv8m\.main-unknown-none-eabihf
100+
Flags:
101+
- --target=thumbv7em-unknown-none-eabihf
102+
- --target=thumbv7m-unknown-none-eabihf
103+
- Match: --target=thumbv7em-unknown-none-eabi
104+
Flags:
105+
- --target=thumbv7m-unknown-none-eabi
106+
- Match: --target=thumbv7em-unknown-none-eabihf
107+
Flags:
108+
- --target=thumbv7m-unknown-none-eabihf
109+
110+
# v7-A and v7-R include the ISA in the triple, but that doesn't matter for
111+
# library selection, so canonicalise Thumb triples to ARM ones.
112+
- Match: --target=thumbv7r-unknown-none-eabi
113+
Flags:
114+
- --target=armv7r-unknown-none-eabi
115+
- Match: --target=thumbv7r-unknown-none-eabihf
116+
Flags:
117+
- --target=armv7r-unknown-none-eabihf
118+
- Match: --target=thumbv7-unknown-none-eabi
119+
Flags:
120+
- --target=armv7-unknown-none-eabi
121+
- Match: --target=thumbv7-unknown-none-eabihf
122+
Flags:
123+
- --target=armv7-unknown-none-eabihf
124+
- Match: --target=thumbv4t-unknown-none-eabi
125+
Flags:
126+
- --target=armv4t-unknown-none-eabi
127+
- Match: --target=thumbv4t-unknown-none-eabihf
128+
Flags:
129+
- --target=armv4t-unknown-none-eabihf
130+
- Match: --target=thumbv5e-unknown-none-eabi
131+
Flags:
132+
- --target=armv5e-unknown-none-eabi
133+
- Match: --target=thumbv5e-unknown-none-eabihf
134+
Flags:
135+
- --target=armv5e-unknown-none-eabihf
136+
137+
# armv7ve is a GCC name for v7-A with the virtualisation extension, for library
138+
# selection we treat it the same as v7-A.
139+
- Match: --target=(arm|thumb)v7ve-unknown-none-eabi
140+
Flags:
141+
- --target=armv7-unknown-none-eabi
142+
- Match: --target=(arm|thumb)v7ve-unknown-none-eabihf
143+
Flags:
144+
- --target=armv7-unknown-none-eabihf
145+
146+
# Higher versions of the architecture such as v8-A and v9-A are a superset of
147+
# v7-A.
148+
- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])a-unknown-none-eabi
149+
Flags:
150+
- --target=armv7-unknown-none-eabi
151+
- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])a-unknown-none-eabihf
152+
Flags:
153+
- --target=armv7-unknown-none-eabihf
154+
- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])r-unknown-none-eabi
155+
Flags:
156+
- --target=armv7r-unknown-none-eabi
157+
- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])r-unknown-none-eabihf
158+
Flags:
159+
- --target=armv7r-unknown-none-eabihf
160+
161+
# -march extensions
162+
- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+fp16(\+[^\+]+)*
163+
Flags:
164+
- -march=thumbv8.1m.main+fp16
165+
- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+mve(\+[^\+]+)*
166+
Flags:
167+
- -march=thumbv8.1m.main+mve
168+
- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+mve\.fp(\+[^\+]+)*
169+
Flags:
170+
- -march=thumbv8.1m.main+mve.fp
171+
- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+lob(\+[^\+]+)*
172+
Flags:
173+
- -march=thumbv8.1m.main+lob
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Converts a cmake list to a string, which can be interpreted as list content in
2+
# meson configuration file.
3+
# The delimiting brackets are not included.
4+
# Example output: "'foo', 'bar', 'baz'"
5+
6+
function(to_meson_list input_list out_var)
7+
list(JOIN input_list "', '" input_list)
8+
set(${out_var} "'${input_list}'" PARENT_SCOPE)
9+
endfunction()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#
2+
# Copyright (c) 2022, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# This directory builds two additional library files to go with llvm-libc:
19+
#
20+
# libcrt0.a contains an implementation of the _start() default entry point,
21+
# which sets up the stack and does any necessary initialization before
22+
# calling main().
23+
#
24+
# libsemihost.a implements llvm-libc's porting function API such as
25+
# __llvm_libc_stdio_write, in terms of the Arm semihosting system.
26+
#
27+
# To use LLVM libc in a semihosting context, include both of these
28+
# libraries. To use it in a different context, you will need to
29+
# reimplement the same functions that libsemihost.a provides, but
30+
# libcrt0.a might still be useful.
31+
32+
cmake_minimum_required(VERSION 3.20.0)
33+
project(llvmlibc-support LANGUAGES C ASM)
34+
35+
add_library(semihost STATIC
36+
init.c
37+
exit.c
38+
stdio_read.c
39+
stdio_write.c
40+
)
41+
42+
add_library(crt0 STATIC
43+
crt0.c
44+
)
45+
46+
install(TARGETS semihost crt0)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) 2022, Arm Limited and affiliates.
3+
// SPDX-License-Identifier: Apache-2.0
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
//
17+
18+
#include <stddef.h>
19+
#include <stdlib.h>
20+
21+
#include "platform.h"
22+
23+
int main(int, char **);
24+
25+
__attribute__((used)) static void c_startup(void) {
26+
_platform_init();
27+
_Exit(main(0, NULL));
28+
}
29+
30+
extern long __stack[];
31+
__attribute__((naked)) void _start(void) {
32+
__asm__("mov sp, %0" : : "r"(__stack));
33+
__asm__("b c_startup");
34+
}

0 commit comments

Comments
 (0)