Skip to content

Commit eb788b3

Browse files
Support wasm-wasip1 target
Co-authored-by: Cetin Sert <[email protected]> Signed-off-by: Master-Hash <[email protected]>
1 parent cc06434 commit eb788b3

File tree

6 files changed

+88
-12
lines changed

6 files changed

+88
-12
lines changed

.cargo/config.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[target.wasm32-wasip1]
2+
rustflags = [
3+
"-L/opt/wasi-sdk/share/wasi-sysroot/lib/wasm32-wasi",
4+
"-Clink-arg=-lc++",
5+
"-Clink-arg=-lc++abi"
6+
]

.github/workflows/release.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ jobs:
3737
# detects that they need cross).
3838
- target: x86_64-unknown-linux-musl
3939
os: ubuntu-22.04
40+
- target: wasm32-wasip1
41+
os: ubuntu-24.04
4042
- target: aarch64-unknown-linux-gnu
4143
os: ubuntu-22.04
4244
- target: aarch64-pc-windows-msvc
@@ -46,6 +48,13 @@ jobs:
4648
runs-on: ${{ matrix.os }}
4749
steps:
4850
# v4.2.2
51+
- run: |
52+
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/wasi-sdk-29.0-x86_64-linux.deb
53+
sudo apt-get install ./wasi-sdk-29.0-x86_64-linux.deb
54+
rm ./wasi-sdk-29.0-x86_64-linux.deb
55+
rustup override set stable
56+
rustup target add wasm32-wasip1
57+
if: ${{ matrix.target == 'wasm32-wasip1' }}
4958
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
5059
- uses: taiki-e/upload-rust-binary-action@v1
5160
with:
@@ -59,6 +68,11 @@ jobs:
5968
env:
6069
# (required)
6170
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
71+
WASI_SDK_PATH: /opt/wasi-sdk
72+
WASI_SYSROOT: /opt/wasi-sdk/share/wasi-sysroot
73+
CC_wasm32_wasip1: /opt/wasi-sdk/bin/clang
74+
AR_wasm32_wasip1: /opt/wasi-sdk/bin/llvm-ar
75+
CFLAGS_wasm32_wasip1: "--sysroot=/opt/wasi-sdk/share/wasi-sysroot"
6276

6377
push_crates_io:
6478
runs-on: ubuntu-22.04

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ tree_magic_mini = "3.1.6"
5959

6060
bumpalo = "3.16.0"
6161
unicode-width = "0.1.9"
62-
crossterm = { version = "0.28.0", features = ["windows"] }
6362
glob = "0.3.1"
6463
strum = { version = "0.26", features = ["derive"] }
6564
hashbrown = "0.14.0"
@@ -128,7 +127,10 @@ tree-sitter-xml = "0.7.0"
128127
tree-sitter-yaml = "0.7.0"
129128
tree-sitter-zig = "1.1.2"
130129

131-
[target.'cfg(not(any(target_env = "msvc", target_os = "illumos", target_os = "freebsd")))'.dependencies]
130+
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
131+
crossterm = { version = "0.28.0", features = ["windows"] }
132+
133+
[target.'cfg(not(any(target_env = "msvc", target_os = "illumos", target_os = "freebsd", target_arch = "wasm32")))'.dependencies]
132134
tikv-jemallocator = "0.6"
133135

134136
[dev-dependencies]

src/files.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ fn read_file_arg(file_arg: &FileArgument) -> std::io::Result<Vec<u8>> {
7878
}
7979

8080
/// Write a human-friendly description of `e` to stderr.
81+
#[cfg(not(target_arch = "wasm32"))]
8182
fn eprint_read_error(file_arg: &FileArgument, e: &std::io::Error) {
8283
match e.kind() {
8384
std::io::ErrorKind::NotFound => {
@@ -95,12 +96,27 @@ fn eprint_read_error(file_arg: &FileArgument, e: &std::io::Error) {
9596
};
9697
}
9798

99+
100+
#[cfg(target_arch = "wasm32")]
101+
fn eprint_read_error(file_arg: &FileArgument, e: &std::io::Error) {
102+
// For the browser/WASM demo, fail softly so we can keep running.
103+
println!("WASM read error on {} ({:?})", file_arg, e.kind());
104+
}
105+
98106
pub(crate) fn read_or_die(path: &Path) -> Vec<u8> {
99107
match fs::read(path) {
100108
Ok(src) => src,
101109
Err(e) => {
102110
eprint_read_error(&FileArgument::NamedPath(path.to_path_buf()), &e);
103-
std::process::exit(EXIT_BAD_ARGUMENTS);
111+
#[cfg(target_arch = "wasm32")]
112+
{
113+
// Return empty content in WASM to avoid aborting the demo.
114+
return Vec::new();
115+
}
116+
#[cfg(not(target_arch = "wasm32"))]
117+
{
118+
std::process::exit(EXIT_BAD_ARGUMENTS);
119+
}
104120
}
105121
}
106122
}

src/main.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,20 @@ use crate::parse::syntax;
9898
///
9999
/// For reference, Jemalloc uses 10-20% more time (although up to 33%
100100
/// more instructions) when testing on sample files.
101-
#[cfg(not(any(target_env = "msvc", target_os = "illumos", target_os = "freebsd")))]
101+
#[cfg(not(any(
102+
target_env = "msvc",
103+
target_os = "illumos",
104+
target_os = "freebsd",
105+
target_arch = "wasm32"
106+
)))]
102107
use tikv_jemallocator::Jemalloc;
103108

104-
#[cfg(not(any(target_env = "msvc", target_os = "illumos", target_os = "freebsd")))]
109+
#[cfg(not(any(
110+
target_env = "msvc",
111+
target_os = "illumos",
112+
target_os = "freebsd",
113+
target_arch = "wasm32"
114+
)))]
105115
#[global_allocator]
106116
static GLOBAL: Jemalloc = Jemalloc;
107117

src/options.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use std::{
88
};
99

1010
use clap::{crate_authors, crate_description, value_parser, Arg, ArgAction, Command};
11-
use crossterm::tty::IsTty;
1211
use owo_colors::OwoColorize as _;
1312

1413
use crate::{
@@ -51,6 +50,30 @@ pub(crate) struct DisplayOptions {
5150

5251
pub(crate) const DEFAULT_TERMINAL_WIDTH: usize = 80;
5352

53+
#[cfg(not(target_arch = "wasm32"))]
54+
fn stdout_is_tty() -> bool {
55+
use crossterm::tty::IsTty;
56+
std::io::stdout().is_tty()
57+
}
58+
59+
#[cfg(target_arch = "wasm32")]
60+
fn stdout_is_tty() -> bool {
61+
false
62+
}
63+
64+
#[cfg(not(target_arch = "wasm32"))]
65+
fn terminal_columns() -> Option<usize> {
66+
crossterm::terminal::size()
67+
.ok()
68+
.map(|(cols, _rows)| cols as usize)
69+
.filter(|cols| *cols > 0)
70+
}
71+
72+
#[cfg(target_arch = "wasm32")]
73+
fn terminal_columns() -> Option<usize> {
74+
None
75+
}
76+
5477
impl Default for DisplayOptions {
5578
fn default() -> Self {
5679
Self {
@@ -125,7 +148,7 @@ fn app() -> clap::Command {
125148
));
126149

127150
after_help.push_str("\n\nSee the full manual at ");
128-
if std::io::stdout().is_tty() {
151+
if stdout_is_tty() {
129152
// Make the link to the manual clickable in terminals that
130153
// support OSC 8, the ANSI escape code for hyperlinks.
131154
//
@@ -596,6 +619,7 @@ fn common_path_suffix(lhs_path: &Path, rhs_path: &Path) -> Option<String> {
596619
}
597620

598621
/// Does `path` look like "/tmp/git-blob-abcdef/modified_field.txt"?
622+
#[cfg(not(target_arch = "wasm32"))]
599623
fn is_git_tmpfile(path: &Path) -> bool {
600624
let Ok(rel_path) = path.strip_prefix(std::env::temp_dir()) else {
601625
return false;
@@ -612,6 +636,12 @@ fn is_git_tmpfile(path: &Path) -> bool {
612636
.starts_with("git-blob-")
613637
}
614638

639+
#[cfg(target_arch = "wasm32")]
640+
fn is_git_tmpfile(_path: &Path) -> bool {
641+
// WASI environments may not have a writable /tmp; skip special-casing.
642+
false
643+
}
644+
615645
fn build_display_path(lhs_path: &FileArgument, rhs_path: &FileArgument) -> String {
616646
match (lhs_path, rhs_path) {
617647
(FileArgument::NamedPath(lhs), FileArgument::NamedPath(rhs)) => {
@@ -1002,10 +1032,8 @@ pub(crate) fn parse_args() -> Mode {
10021032
/// Try to work out the width of the terminal we're on, or fall back
10031033
/// to a sensible default value.
10041034
fn detect_terminal_width() -> usize {
1005-
if let Ok((columns, _rows)) = crossterm::terminal::size() {
1006-
if columns > 0 {
1007-
return columns.into();
1008-
}
1035+
if let Some(columns) = terminal_columns() {
1036+
return columns;
10091037
}
10101038

10111039
// If crossterm couldn't detect the terminal width, use the
@@ -1036,7 +1064,7 @@ pub(crate) fn should_use_color(color_output: ColorOutput) -> bool {
10361064
fn detect_color_support() -> bool {
10371065
// TODO: consider following the env parsing logic in git_config_bool
10381066
// in config.c.
1039-
std::io::stdout().is_tty() || env::var("GIT_PAGER_IN_USE").is_ok()
1067+
stdout_is_tty() || env::var("GIT_PAGER_IN_USE").is_ok()
10401068
}
10411069

10421070
#[cfg(test)]

0 commit comments

Comments
 (0)