Skip to content

Commit d51f18f

Browse files
committed
Add support for hexagon-unknown-qurt target
1 parent ade8487 commit d51f18f

File tree

3 files changed

+216
-0
lines changed

3 files changed

+216
-0
lines changed

compiler/rustc_target/src/spec/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,7 @@ supported_targets! {
14871487
("mips64el-unknown-linux-muslabi64", mips64el_unknown_linux_muslabi64),
14881488
("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl),
14891489
("hexagon-unknown-none-elf", hexagon_unknown_none_elf),
1490+
("hexagon-unknown-qurt", hexagon_unknown_qurt),
14901491

14911492
("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
14921493
("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, TargetOptions, cvs};
2+
3+
pub(crate) fn target() -> Target {
4+
let mut pre_link_args = std::collections::BTreeMap::<LinkerFlavor, Vec<_>>::new();
5+
pre_link_args
6+
.entry(LinkerFlavor::Unix(Cc::Yes))
7+
.or_default()
8+
.extend(["-G0".into()].into_iter());
9+
10+
Target {
11+
llvm_target: "hexagon-unknown-elf".into(),
12+
metadata: TargetMetadata {
13+
description: Some("Hexagon QuRT (Qualcomm Real-Time OS)".into()),
14+
tier: Some(3),
15+
host_tools: Some(false),
16+
std: Some(true),
17+
},
18+
pointer_width: 32,
19+
data_layout: concat!(
20+
"e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32",
21+
":32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32",
22+
":32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048",
23+
":2048:2048"
24+
)
25+
.into(),
26+
arch: "hexagon".into(),
27+
options: TargetOptions {
28+
os: "qurt".into(),
29+
vendor: "unknown".into(),
30+
cpu: "hexagonv69".into(),
31+
linker: Some("rust-lld".into()),
32+
linker_flavor: LinkerFlavor::Unix(Cc::Yes),
33+
exe_suffix: ".elf".into(),
34+
dynamic_linking: true,
35+
executables: true,
36+
families: cvs!["unix"],
37+
has_thread_local: true,
38+
has_rpath: false,
39+
crt_static_default: false,
40+
crt_static_respected: true,
41+
crt_static_allows_dylibs: true,
42+
no_default_libraries: false,
43+
max_atomic_width: Some(32),
44+
features: "-small-data,+hvx-length128b".into(),
45+
c_enum_min_bits: Some(8),
46+
pre_link_args,
47+
..Default::default()
48+
},
49+
}
50+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# `hexagon-unknown-qurt`
2+
3+
**Tier: 3**
4+
5+
Rust for Hexagon QuRT (Qualcomm Real-Time OS).
6+
7+
| Target | Description |
8+
| -------------------- | -------------------------------------------- |
9+
| hexagon-unknown-qurt | Hexagon 32-bit QuRT (position independent) |
10+
11+
## Target maintainers
12+
13+
[@androm3da](https://github.com/androm3da)
14+
15+
## Requirements
16+
17+
This target is cross-compiled. There is support for `std`. The target uses
18+
QuRT's standard library and runtime.
19+
20+
By default, code generated with this target should run on Hexagon DSP hardware
21+
running the QuRT real-time operating system.
22+
23+
- `-Ctarget-cpu=hexagonv69` targets Hexagon V69 architecture (default)
24+
- `-Ctarget-cpu=hexagonv73` adds support for instructions defined up to Hexagon V73
25+
26+
Functions marked `extern "C"` use the [Hexagon architecture calling convention](https://lists.llvm.org/pipermail/llvm-dev/attachments/20190916/21516a52/attachment-0001.pdf).
27+
28+
This target generates position-independent ELF binaries by default, making it
29+
suitable for both static images and dynamic shared objects.
30+
31+
## Building the target
32+
33+
You can build Rust with support for the target by adding it to the `target`
34+
list in `bootstrap.toml`:
35+
36+
```toml
37+
[build]
38+
build-stage = 1
39+
host = ["<target for your host>"]
40+
target = ["<target for your host>", "hexagon-unknown-qurt"]
41+
42+
[target.hexagon-unknown-qurt]
43+
cc = "hexagon-clang"
44+
cxx = "hexagon-clang++"
45+
ranlib = "hexagon-ranlib"
46+
ar = "hexagon-ar"
47+
llvm-libunwind = 'in-tree'
48+
```
49+
50+
Replace `<target for your host>` with `x86_64-unknown-linux-gnu` or whatever
51+
else is appropriate for your host machine.
52+
53+
## Building Rust programs
54+
55+
Rust does not yet ship pre-compiled artifacts for this target. To compile for
56+
this target, you will either need to build Rust with the target enabled (see
57+
"Building the target" above), or build your own copy of `core` by using
58+
`build-std` or similar.
59+
60+
## Static Image Targeting
61+
62+
For static executables that run directly on QuRT, use the default target
63+
configuration with additional linker flags:
64+
65+
```sh
66+
# Build a static executable for QuRT
67+
cargo build --target hexagon-unknown-qurt \
68+
-C link-args="-static -nostdlib" \
69+
-C link-args="-L/opt/Hexagon_SDK/6.3.0.0/rtos/qurt/computev69/lib" \
70+
-C link-args="-lqurt -lc"
71+
```
72+
73+
This approach is suitable for:
74+
- Standalone QuRT applications
75+
- System-level services
76+
- Boot-time initialization code
77+
- Applications that need deterministic memory layout
78+
79+
## User-Loadable Shared Object Targeting
80+
81+
For shared libraries that can be dynamically loaded by QuRT applications:
82+
83+
```sh
84+
# Build a shared object for QuRT
85+
cargo build --target hexagon-unknown-qurt \
86+
--crate-type=cdylib \
87+
-C link-args="-shared -fPIC" \
88+
-C link-args="-L/opt/Hexagon_SDK/6.3.0.0/rtos/qurt/computev69/lib"
89+
```
90+
91+
This approach is suitable for:
92+
- Plugin architectures
93+
- Runtime-loadable modules
94+
- Libraries shared between multiple applications
95+
- Code that needs to be updated without system restart
96+
97+
## Configuration Options
98+
99+
The target can be customized for different use cases:
100+
101+
### For Static Images
102+
```toml
103+
# In .cargo/config.toml
104+
[target.hexagon-unknown-qurt]
105+
rustflags = [
106+
"-C", "link-args=-static",
107+
"-C", "link-args=-nostdlib",
108+
"-C", "target-feature=-small-data"
109+
]
110+
```
111+
112+
### For Shared Objects
113+
```toml
114+
# In .cargo/config.toml
115+
[target.hexagon-unknown-qurt]
116+
rustflags = [
117+
"-C", "link-args=-shared",
118+
"-C", "link-args=-fPIC",
119+
"-C", "relocation-model=pic"
120+
]
121+
```
122+
123+
## Testing
124+
125+
Since `hexagon-unknown-qurt` requires the QuRT runtime environment, testing requires
126+
either:
127+
- Hexagon hardware with QuRT
128+
- `hexagon-sim`
129+
- QEMU (`qemu-system-hexagon`)
130+
131+
## Cross-compilation toolchains and C code
132+
133+
This target requires the [Hexagon SDK toolchain for C interoperability](https://softwarecenter.qualcomm.com/api/download/software/sdks/Hexagon_SDK/Linux/Debian/6.3.0.0/Hexagon_SDK.zip):
134+
135+
- **SDK Path**: `/opt/Hexagon_SDK/6.3.0.0/`
136+
- **Toolchain**: Use `hexagon-clang` from the Hexagon SDK
137+
- **Headers**: QuRT and POSIX headers are automatically included
138+
- **Libraries**: Link against QuRT system libraries as needed
139+
140+
### C Interoperability Example
141+
142+
```rust
143+
// lib.rs
144+
#![no_std]
145+
extern crate std;
146+
147+
#[no_mangle]
148+
pub extern "C" fn rust_function() -> i32 {
149+
// Your Rust code here
150+
42
151+
}
152+
```
153+
154+
```c
155+
// wrapper.c
156+
extern int rust_function(void);
157+
158+
int main() {
159+
return rust_function();
160+
}
161+
```
162+
163+
The target supports both static linking for standalone applications and dynamic
164+
linking for modular architectures, making it flexible for various QuRT
165+
deployment scenarios.

0 commit comments

Comments
 (0)