Skip to content

Commit bd9f980

Browse files
atfl: add new package (#2802)
Co-authored-by: Luke Ireland <luke.ireland@arm.com>
1 parent 78d2b43 commit bd9f980

File tree

5 files changed

+304
-0
lines changed

5 files changed

+304
-0
lines changed

repos/spack_repo/builtin/packages/acfl/detection_test.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,22 @@ paths:
8181
echo "InstalledDir: /usr/bin"
8282
platforms: [linux]
8383
results: []
84+
85+
- layout: # does not detect ATfL
86+
- executables:
87+
- "bin/armclang"
88+
- "bin/armclang++"
89+
script: |
90+
echo "Arm Toolchain for Linux 20.1 clang version 20.1.0"
91+
echo "Target: aarch64--linux-gnu"
92+
echo "Thread model: posix"
93+
echo "InstalledDir: /opt/arm/arm-toolchain-for-linux-20.1/bin"
94+
- executables:
95+
- "bin/armflang"
96+
script: |
97+
echo "Arm Toolchain for Linux 20.1 flang version 20.1.0"
98+
echo "Target: aarch64--linux-gnu"
99+
echo "Thread model: posix"
100+
echo "InstalledDir: /opt/arm/arm-toolchain-for-linux-20.1/bin"
101+
platforms: [linux]
102+
results: []
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
paths:
2+
- layout:
3+
- executables:
4+
- "bin/armclang"
5+
- "bin/armclang++"
6+
script: |
7+
echo "Arm Toolchain for Linux 20.1 clang version 20.1.0"
8+
echo "Target: aarch64--linux-gnu"
9+
echo "Thread model: posix"
10+
echo "InstalledDir: /opt/arm/arm-toolchain-for-linux-20.1/bin"
11+
- executables:
12+
- "bin/armflang"
13+
script: |
14+
echo "Arm Toolchain for Linux 20.1 flang version 20.1.0"
15+
echo "Target: aarch64--linux-gnu"
16+
echo "Thread model: posix"
17+
echo "InstalledDir: /opt/arm/arm-toolchain-for-linux-20.1/bin"
18+
platforms: [linux]
19+
results:
20+
- spec: atfl@20.1.0
21+
extra_attributes:
22+
compilers:
23+
c: ".*/bin/armclang$"
24+
cxx: ".*/bin/armclang[+][+]$"
25+
fortran: ".*/bin/armflang$"
26+
27+
# Negative tests: ensure ATfL does not detect other compilers
28+
- layout: # does not detect upstream clang/LLVM
29+
- executables:
30+
- "bin/clang"
31+
- "bin/clang++"
32+
script: |
33+
echo "clang version 20.1.0 (https://github.com/llvm/llvm-project abcdef)"
34+
echo "Target: x86_64-unknown-linux-gnu"
35+
echo "Thread model: posix"
36+
echo "InstalledDir: /usr/bin"
37+
platforms: [linux]
38+
results: []
39+
40+
- layout: # does not detect ACfL
41+
- executables:
42+
- "bin/armclang"
43+
- "bin/armclang++"
44+
- "bin/armflang"
45+
script: |
46+
echo "Arm C/C++/Fortran Compiler version 19.3.1 (build number 75) (based on LLVM 7.0.2)"
47+
echo "Target: aarch64--linux-gnu"
48+
echo "Thread model: posix"
49+
echo "InstalledDir:"
50+
echo "/opt/arm/arm-hpc-compiler-19.3.5_Generic-AArch64_RHEL-7_aarch64-linux/bin"
51+
platforms: [linux]
52+
results: []
53+
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# Copyright Spack Project Developers. See COPYRIGHT file.
2+
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
3+
4+
from pathlib import Path
5+
from typing import ClassVar, Dict
6+
7+
from spack_repo.builtin.build_systems.compiler import CompilerPackage
8+
from spack_repo.builtin.build_systems.generic import Package
9+
from spack_repo.builtin.packages.llvm.package import LlvmDetection
10+
11+
from spack.package import *
12+
13+
_VERSIONS = {
14+
"21.1.1": {
15+
"ubuntu22.04": (
16+
"8132ef95e4671c20a5f2b21dbe2d7ad8ae16137ea634e3e11096a8b87a3ffeee",
17+
"https://developer.arm.com/packages/arm-toolchains%3Aubuntu-22/jammy/arm64/arm-toolchain-for-linux_21.1-81_arm64.deb",
18+
),
19+
"ubuntu24.04": (
20+
"18f210fb04f27c50af932e1549deeda394a4ff351f9388957de0b096ab5f1db0",
21+
"https://developer.arm.com/packages/arm-toolchains%3Aubuntu-24/noble/arm64/arm-toolchain-for-linux_21.1-81_arm64.deb",
22+
),
23+
"rhel8": (
24+
"c5f0c3f7a25e269160aa3d684cb14edc57252bc38643929c67cda892f1c28dda",
25+
"https://developer.arm.com/packages/arm-toolchains%3Arhel-8/el8/aarch64/arm-toolchain-for-linux-21.1-81.aarch64.rpm",
26+
),
27+
"rhel9": (
28+
"3ead2888f8aa71b79a944270b1f7f723f56a7d161aeb2abaad14b3333f91f0e9",
29+
"https://developer.arm.com/packages/arm-toolchains%3Arhel-9/el9/aarch64/arm-toolchain-for-linux-21.1-81.aarch64.rpm",
30+
),
31+
"rhel10": (
32+
"a2fc22f18b7ee764ca11af48e6215b43ab47597cc67ba63fcccf0e40f9859a76",
33+
"https://developer.arm.com/packages/arm-toolchains%3Arhel-10/el10/aarch64/arm-toolchain-for-linux-21.1-81.aarch64.rpm",
34+
),
35+
"amzn2023": (
36+
"f7bc8c156aaa367dff1d6ced922e90581a04c8bac92e5675cc107eb3cd28428a",
37+
"https://developer.arm.com/packages/arm-toolchains%3Aamzn-2023/al2023/aarch64/arm-toolchain-for-linux-21.1-81.aarch64.rpm",
38+
),
39+
"sles15": (
40+
"8de2e35511d7f59a933c40e2e20ed2e01d018f51caba36dc5e9e0c6da71a3619",
41+
"https://developer.arm.com/packages/arm-toolchains%3Asles-15/sl15/aarch64/arm-toolchain-for-linux-21.1-81.aarch64.rpm",
42+
),
43+
},
44+
"20.1.0": {
45+
"ubuntu22.04": (
46+
"944cf6420fb7b49c52d6c3d6f139fbb4896073ad401204a0cdf609faea360e73",
47+
"https://developer.arm.com/packages/arm-toolchains%3Aubuntu-22/jammy/arm64/arm-toolchain-for-linux_20.1-65_arm64.deb",
48+
),
49+
"ubuntu24.04": (
50+
"b9f7db08da8d579daad06999a65136e6b449b79c870a16264fbef1a7ab0cbe6b",
51+
"https://developer.arm.com/packages/arm-toolchains%3Aubuntu-24/noble/arm64/arm-toolchain-for-linux_20.1-65_arm64.deb",
52+
),
53+
"rhel8": (
54+
"795e6b74b2b538cc8431ff164c145aa7920ad9394ccf1d544a06667663b70f01",
55+
"https://developer.arm.com/packages/arm-toolchains%3Arhel-8/el8/aarch64/arm-toolchain-for-linux-20.1-65.aarch64.rpm",
56+
),
57+
"rhel9": (
58+
"453fc0f4d62968a833499f40a3d04deddbf292c9ff40fd3d246e84ba5b9d7d7a",
59+
"https://developer.arm.com/packages/arm-toolchains%3Arhel-9/el9/aarch64/arm-toolchain-for-linux-20.1-65.aarch64.rpm",
60+
),
61+
"amzn2023": (
62+
"87b2031290b9a48b0f2c700aff5f38560f7d1cb7d7f0b0f537ce18965260a54a",
63+
"https://developer.arm.com/packages/arm-toolchains%3Aamzn-2023/al2023/aarch64/arm-toolchain-for-linux-20.1-65.aarch64.rpm",
64+
),
65+
"sles15": (
66+
"506a9ddff6d7daf60e1d5b8cfed95f6f25e70db3cc9545d8ea3e9745056740f9",
67+
"https://developer.arm.com/packages/arm-toolchains%3Asles-15/sl15/aarch64/arm-toolchain-for-linux-20.1-65.aarch64.rpm",
68+
),
69+
},
70+
}
71+
72+
73+
class Atfl(Package, LlvmDetection, CompilerPackage):
74+
"""Arm Toolchain for Linux (ATfL): LLVM-based AArch64 compilers.
75+
76+
Installs the distro package (RPM/DEB) from Arm's repos, without root.
77+
"""
78+
79+
maintainers("pawosm-arm")
80+
homepage = "https://developer.arm.com/documentation/110477"
81+
82+
_alias: ClassVar[Dict[str, str]] = {"rocky10": "rhel10", "rocky9": "rhel9", "rocky8": "rhel8"}
83+
for ver, per_os in _VERSIONS.items():
84+
pkg = per_os.get(_alias.get(host_platform().default_os, host_platform().default_os), None)
85+
if pkg:
86+
version(ver, sha256=pkg[0], url=pkg[1], expand=False)
87+
88+
# Linux AArch64 only
89+
requires("platform=linux", msg="ATfL is only available on Linux")
90+
requires("target=aarch64:", msg="ATfL provides AArch64-native compilers")
91+
92+
provides("c", "cxx")
93+
provides("fortran")
94+
95+
# Optional: allow opt-in to lld via the spec. Default is GNU ld for
96+
# maximum compatibility; packages that prefer lld can request `%atfl+lld`.
97+
variant("lld", default=False, description="Use lld linker (adds -fuse-ld=lld)")
98+
99+
# Arm Performance Libraries are required: ATfL's default configuration
100+
# links against ArmPL (e.g. -fveclib=ArmPL -> -lamath). Ensure it's
101+
# present and wired into the environment so linking always succeeds.
102+
depends_on("armpl-gcc~examples", type="run")
103+
104+
compiler_languages = ["c", "cxx", "fortran"]
105+
compiler_version_regex = r"Arm Toolchain for Linux [\d\.]+ [cf]lang version ([\d\.]+)"
106+
c_names = ["armclang"]
107+
cxx_names = ["armclang++"]
108+
fortran_names = ["armflang"]
109+
compiler_wrapper_link_paths = {
110+
"c": join_path("arm", "armclang"),
111+
"cxx": join_path("arm", "armclang++"),
112+
"fortran": join_path("arm", "armflang"),
113+
}
114+
implicit_rpath_libs = ["libclang"]
115+
stdcxx_libs = ("-lstdc++",)
116+
117+
debug_flags = [
118+
"-gcodeview",
119+
"-gdwarf-2",
120+
"-gdwarf-3",
121+
"-gdwarf-4",
122+
"-gdwarf-5",
123+
"-gline-tables-only",
124+
"-gmodules",
125+
"-g",
126+
]
127+
128+
opt_flags = ["-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os", "-Oz", "-Og", "-O", "-O4"]
129+
130+
def archspec_name(self) -> str:
131+
"""Return the compiler name to use for archspec queries."""
132+
return "clang"
133+
134+
def install(self, spec: Spec, prefix: Prefix) -> None:
135+
"""Install the package."""
136+
archive = self.stage.archive_file
137+
extract_dir = join_path(self.stage.path, "extract")
138+
mkdir(extract_dir)
139+
if archive.endswith(".rpm"):
140+
Executable("bsdtar")("-xf", archive, "-C", str(extract_dir))
141+
elif archive.endswith(".deb"):
142+
Executable("dpkg-deb")("-x", archive, str(extract_dir))
143+
else:
144+
raise InstallError(f"Unknown archive type: {archive}")
145+
src_root = join_path(extract_dir, "opt", "arm", "arm-toolchain-for-linux")
146+
147+
if not Path(src_root).is_dir():
148+
raise InstallError(f"Expected payload at {src_root}")
149+
150+
# We must remove all of the libamath.* symlinks as they reach /opt
151+
for cand in Path(src_root).rglob("libamath.*"):
152+
if cand.is_symlink():
153+
cand.unlink()
154+
155+
install_tree(str(src_root), prefix)
156+
157+
with open(join_path(prefix, "bin", "atfl-performance.cfg"), "a") as f:
158+
# Enable lld if requested. Some system builds (e.g. ncurses with
159+
# version scripts) are stricter under lld; make this opt-in to
160+
# maximize compatibility.
161+
if self.spec.satisfies("+lld"):
162+
print("-fuse-ld=lld", file=f)
163+
164+
# ArmPL's libamath must be visible to the compiler.
165+
# ArmPL directory layout: <prefix>/armpl_<version>_gcc/lib
166+
armpl_dir = join_path(
167+
self["armpl-gcc"].prefix, "armpl_" + str(self["armpl-gcc"].version) + "_gcc", "lib"
168+
)
169+
print(f"-L{armpl_dir} -Wl,-rpath={armpl_dir}", file=f)
170+
171+
# Ensure ATfL's own Fortran runtime is available to dependents.
172+
# At first, Flang was using libFortranRuntime and libFortranDecimal;
173+
# later toolchains use libflang_rt.runtime. This avoids per-package
174+
# tweaks.
175+
fortran_runtime = ""
176+
fortran_runtime_paths = set()
177+
for cand in Path(prefix).rglob("libFortranRuntime.*"):
178+
fortran_runtime = "-lFortranRuntime -lFortranDecimal"
179+
fortran_runtime_paths.add(str(cand.parent))
180+
for cand in Path(prefix).rglob("libflang_rt.runtime.*"):
181+
fortran_runtime = "-lflang_rt.runtime"
182+
fortran_runtime_paths.add(str(cand.parent))
183+
for rt_path in fortran_runtime_paths:
184+
print(f"-L{rt_path} -Wl,-rpath,{rt_path}", file=f)
185+
print(f"-Wl,--push-state -Wl,--as-needed {fortran_runtime} -Wl,--pop-state", file=f)
186+
187+
def _cc_path(self) -> str:
188+
return join_path(self.prefix, "bin", "armclang")
189+
190+
def _cxx_path(self) -> str:
191+
return join_path(self.prefix, "bin", "armclang++")
192+
193+
def _fortran_path(self) -> str:
194+
return join_path(self.prefix, "bin", "armflang")
195+
196+
def _standard_flag(self, *, language: str, standard: str) -> str:
197+
flags = {
198+
"cxx": {"11": "-std=c++11", "14": "-std=c++14", "17": "-std=c++17"},
199+
"c": {"99": "-std=c99", "11": "-std=c11"},
200+
}
201+
return flags[language][standard]
202+
203+
def setup_compiler_environment(self, env: EnvironmentModifications) -> None:
204+
"""Set up the build environment for this compiler package."""
205+
206+
# Prefer LLVM binutils (needed by LTO).
207+
env.set("AR", join_path(self.prefix, "bin", "llvm-ar"))
208+
env.set("NM", join_path(self.prefix, "bin", "llvm-nm"))
209+
env.set("RANLIB", join_path(self.prefix, "bin", "llvm-ranlib"))
210+
211+
def setup_run_environment(self, env: EnvironmentModifications) -> None:
212+
"""Set up the run environment for this package."""
213+
self.setup_compiler_environment(env)
214+
215+
def setup_dependent_build_environment(self, env: EnvironmentModifications, _: Spec) -> None:
216+
"""Set up the build environment for packages that depend on this one."""
217+
self.setup_run_environment(env)

repos/spack_repo/builtin/packages/llvm/detection_test.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,16 @@ paths:
182182
echo "InstalledDir: /Library/Developer/CommandLineTools/usr/bin"
183183
platforms: ["darwin"]
184184
results: []
185+
186+
# ATfL should not be detected as upstream LLVM
187+
- layout:
188+
- executables:
189+
- "bin/clang"
190+
- "bin/clang++"
191+
script: |
192+
echo "Arm Toolchain for Linux 20.1 clang version 20.1.0"
193+
echo "Target: aarch64--linux-gnu"
194+
echo "Thread model: posix"
195+
echo "InstalledDir: /opt/arm/arm-toolchain-for-linux-20.1/bin"
196+
platforms: ["linux"]
197+
results: []

repos/spack_repo/builtin/packages/llvm/package.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ def determine_version(cls, exe):
698698
return None
699699
if "AMD" in output:
700700
return None
701+
if "Arm Toolchain for Linux" in output:
702+
return None
701703
match = re.search(cls.compiler_version_regex, output)
702704
if match:
703705
return match.group(match.lastindex)

0 commit comments

Comments
 (0)