File nodejs-vscode-tree-sitter-wasm.spec of Package nodejs-vscode-tree-sitter-wasm

Name:           nodejs-vscode-tree-sitter-wasm
Version:        0.1.4
%define emscripten_version 3.1.64
%global tree_sitter_version 0.25.2
%global toolchain clang
Release:        0
Summary:        Tree-Sitter for Visual Studio Code
License:        MIT and (MIT or NCSA)
Group:          Development/Languages/NodeJS
Url:            https://github.com/microsoft/vscode-tree-sitter-wasm
# Created by create-tarball.sh
Source0:        https://github.com/microsoft/vscode-tree-sitter-wasm/archive/refs/tags/v%{version}.tar.gz
Source1000:     vendor.tar.zst
Patch0: compileTreeSitterWasm-local.patch
Patch1: tree-sitter-cflags.patch
Patch3: compileGrammarWasm-no-build.patch
Patch4: tree-sitter-no-cc.patch
Patch1000: system-esbuild.patch



Source1:        https://github.com/emscripten-core/emscripten/archive/refs/tags/%{emscripten_version}/emscripten-%{emscripten_version}.tar.gz
Source2:        emscripten-vendor.tar.zst
Source10001:    emscripten-cflags.patch
Source10400:    llvm19-no-shlib-sigcheck.patch

#ref build/main.ts
#TODO: find some way to automate this list
%define tspaths ( tree-sitter-css tree-sitter-c-sharp tree-sitter-cpp tree-sitter-go tree-sitter-java tree-sitter-javascript tree-sitter-python tree-sitter-regex tree-sitter-ruby tree-sitter-rust tree-sitter-typescript/tsx tree-sitter-typescript/typescript tree-sitter-ini )
%define tsnames ( css c_sharp  cpp go java javascript python regex ruby rust tsx typescript ini)

BuildArch:      noarch
BuildRequires:  binaryen
#rust is only for internal tools, not for final artifacts. Thus no proper rustflags required.
BuildRequires:  cargo
BuildRequires:  esbuild
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150700 || 0%{?fedora}
BuildRequires:  clang >= 18
BuildRequires:  lld >= 18
BuildRequires:  llvm >= 18
%else
BuildRequires:  clang18
BuildRequires:  lld18
BuildRequires:  llvm18
%endif
BuildRequires: jq
%if 0%{?suse_version}
BuildRequires:  ninja
%else
BuildRequires:  ninja-build
%endif
BuildRequires:  nodejs-packaging
BuildRequires:  nodejs-electron-devel
%if 0%{?fedora} >= 37
BuildRequires: nodejs-npm
%else
BuildRequires:  npm
%endif
%if 0%{?suse_version}
BuildRequires:  python3-base
%else
BuildRequires:  python3
%endif
BuildRequires:  zstd
Provides: bundled(tree-sitter) = %tree_sitter_version
Provides: bundled(emscripten) = %emscripten_version

# this is to be used by electron, not node
%global __nodejs_requires  %nil

%description
Tree-Sitter and Tree-Sitter grammar WebAssembly files used by Visual Studio Code.

%package devel
Summary:        Tree-Sitter for Visual Studio Code – development files
Requires:       nodejs-vscode-tree-sitter-wasm = %version

%description devel
Tree-Sitter and Tree-Sitter grammar WebAssembly files used by Visual Studio Code.
This package provides the typescript declarations needed to develop software using nodejs-vscode-tree-sitter-wasm.


%prep
%setup  -a1000 -n vscode-tree-sitter-wasm-%{version}
test $(grep -F 'emsdk activate' build/setup-emsdk.sh|sed 's/^.*activate //') = %emscripten_version
test $(grep -F 'const tag' build/main.ts|sed 's/^.* = '\''v// ; s/'\'';.*//') = %tree_sitter_version
%autopatch -p1
#Provide the alias
cat tree-sitter/.cargo/config.toml >> tree-sitter/.cargo/config
#Remove prebuilt binary. It's not used anyway, but better be safe.
rm -v tree-sitter/lib/src/wasm/wasm-stdlib.h

# https://blogs.gnome.org/mcatanzaro/2020/05/18/patching-vendored-rust-dependencies/
pushd tree-sitter/vendor/libloading
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd tree-sitter/vendor/vcpkg
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd tree-sitter/vendor/ring
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd


cd %_builddir
tar -xf %SOURCE1
cd emscripten-%{emscripten_version}
tar -xf %SOURCE2
patch -p1 --verbose < %SOURCE10001
patch -p1 --verbose -R < %SOURCE10400
rm -rvf third_party/{ply,websockify,jni/jni.h,*.h,*.c}
cd %_builddir


%build
export MAKEFLAGS="%{_smp_mflags}"

#remove arch-specific options
export CFLAGS="$(echo "-flto=auto -fvisibility=hidden %{optflags} "|sed 's/ -m\S*//g')"
#remove fedora spec which does not work on clang
export CFLAGS="$(echo "$CFLAGS"|sed 's/ --config \S*//g')"
#does not work with wasm and is useless anyway
export CFLAGS="$(echo "$CFLAGS"|sed 's/ -ffat-lto-objects\S*//g')"
#error: option 'cf-protection=return' cannot be specified on this target
export CFLAGS="$(echo "$CFLAGS"|sed 's/ -fcf-protection\S*//g')"
#debuginfo does not really work with wasm, but -g options have different meaning
export CFLAGS="$(echo "$CFLAGS"|sed 's/ -g\S*//g') -g0 "
export EMCC_VERBOSE=1
export EMCC_USE_NINJA=2

#This may be a noarch package, but we still care about the target “hardware”
#The reason is that the compiler (clang) and VM (chromium/V8) are unrelated projects, and clang by default targets an ancient VM version.
#Enable instruction sets that our actual target (Chromium 124 atm) supports.
#See https://webassembly.org/features/ (note: for Electron only the Chromium version is relevant, not the Node version)
HWFLAGS='-matomics -mbulk-memory -mexception-handling -mextended-const -mmultivalue -mmutable-globals -mnontrapping-fptoint -mreference-types -msign-ext -mtail-call'
# HWFLAGS="$HWFLAGS -mrelaxed-simd -msimd128" not supported on all hardware, see https://source.chromium.org/chromium/chromium/src/+/main:v8/src/wasm/function-body-decoder-impl.h;l=373
HWFLAGS="$HWFLAGS -mmultimemory"
HWFLAGS="$HWFLAGS -sMIN_FIREFOX_VERSION=-1 -sMIN_SAFARI_VERSION=-1 -sMIN_CHROME_VERSION=124 -sMIN_NODE_VERSION=200000"
export CFLAGS="$CFLAGS $HWFLAGS"

export CXXFLAGS="$CFLAGS"
export LDFLAGS="%{?build_ldflags} $HWFLAGS -s -g0 -Wl,-O2 -Wl,--lto-O2 -Wl,--gc-sections "
export LDFLAGS="$(echo "$LDFLAGS"|sed 's/ --config \S*//g')"
export LDFLAGS="$(echo "$LDFLAGS"| sed 's/ -Wl,--as-needed//')"
export LDFLAGS="$(echo "$LDFLAGS"| sed 's/ -Wl,--build-id=\S*//')"
export LDFLAGS="$(echo "$LDFLAGS"|sed 's/ -ffat-lto-objects\S*//g')"

export ESBUILD_BINARY_PATH=%{_bindir}/esbuild

#extra verbose. Only use for debugging linker problems
#export LDFLAGS="$LDFLAGS -Wl,--print-gc-sections -Wl,-M -Wl,--verbose"

export PATH="%{_builddir}/emscripten-%{emscripten_version}:%{_libexecdir}/electron-node:$PATH"

# /usr/bin/wasm-opt: error while loading shared libraries: libbinaryen.so: cannot open shared object file: No such file or directory
%if 0%{?sle_version} || 0%{?sle_version} < 150500
export LD_LIBRARY_PATH=%{_libdir}/binaryen
%endif
export BINARYEN="%{_prefix}"
export EM_BINARYEN_ROOT="%{_prefix}"
export EM_IGNORE_SANITY=1
rm -vf %{_builddir}/emscripten-%{emscripten_version}/.emscripten && emcc --generate-config



paths=%tspaths
names=%tsnames
for i in "${!paths[@]}" ; do
#parsing rust with sed, yay
TREE_SITTER_FLAGS=$(sed '0,/let output_name/d; 0,/command\.args/d; /;/Q' tree-sitter/cli/loader/src/lib.rs  | grep -Fv -- '"-Os"' | grep -Fv -- '"-o"' | grep -F -- '"' | sed 's/^[^"]*"//; s/"[^"]*$//; s/\\//g; s/{language_name}/'"${names[i]}"/)
pushd node_modules/"${paths[i]}"/src/
#TODO: possibly regenerate parser.c here?
sed -i '/#pragma.*optimize/d' parser.c #We want optimized code ffs
touch -a scanner.c #Not all parsers have this
emcc $TREE_SITTER_FLAGS $CFLAGS -c parser.c
emcc $TREE_SITTER_FLAGS $CFLAGS -c scanner.c
emar -Trcs libscanner.a scanner.o
emcc $TREE_SITTER_FLAGS $LDFLAGS parser.o libscanner.a -o output.wasm
popd
done

npm run build-wasm


%install
mkdir -pv %{buildroot}%{nodejs_sitelib}/@vscode/tree-sitter-wasm
cp -lv package.json -t %{buildroot}%{nodejs_sitelib}/@vscode/tree-sitter-wasm
cp -lrv wasm -t %{buildroot}%{nodejs_sitelib}/@vscode/tree-sitter-wasm
paths=%tspaths
names=%tsnames
for i in "${!paths[@]}" ; do
cp -Tlv node_modules/"${paths[i]}"/src/output.wasm %{buildroot}%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-"${names[i]}".wasm
done
mv -v %{buildroot}%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-c{_,-}sharp.wasm #HACK


%files
%defattr(-,root,root)
%license LICENSE
%doc CHANGELOG.md
%dir %{nodejs_sitelib}
%dir %{nodejs_sitelib}/@vscode
%dir %{nodejs_sitelib}/@vscode/tree-sitter-wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/package.json
%dir %{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter.js
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-typescript.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-tsx.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-rust.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-ruby.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-regex.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-python.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-javascript.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-java.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-go.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-cpp.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-c-sharp.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-css.wasm
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/tree-sitter-ini.wasm
%files devel
%{nodejs_sitelib}/@vscode/tree-sitter-wasm/wasm/web-tree-sitter.d.ts

%changelog
openSUSE Build Service is sponsored by