File nodejs-signal-ringrtc.spec of Package nodejs-signal-ringrtc

#
# spec file for package signal-ringrtc
#
# Copyright (c) 2020 SUSE LLC
# Copyright (c) 2019 Andreas Schneider <asn@cryptomilk.org>.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.

# Please submit bugfixes or comments via https://bugs.opensuse.org/
#

%global __provides_exclude ^lib.*\\.so.*$


#Both electron and webrtc require SSE2 on the x86 port. So we can require SSE2 on all other code, too.
%ifarch %ix86
ExclusiveArch:  i586 i686
BuildArch:      i686
%{expand:%%global optflags %(echo "%optflags") -march=pentium4 -mtune=generic}
%{expand:%%global build_rustflags %(echo "%build_rustflags") -C target-cpu=pentium4 -Z tune-cpu=generic}
%endif

# needs C++17 abseil as some code assumes absl::string_view is an alias for std::string_view. Leap does not have it.
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150700 || 0%{?fedora_version} >= 39
%bcond_without system_abseil
%else
%bcond_with system_abseil
%endif


%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150600 || 0%{?fedora} >= 41
%bcond_without system_libyuv
%else
%bcond_with system_libyuv
%endif


%global pkg_name ringrtc

%global rpm_name signal-libringrtc

%define webrtc_req_version 6834g


Name:           nodejs-signal-ringrtc
Version:        2.50.4
Release:        0
Summary:        Video and voice calling services for Signal Messenger
License:        AGPL-3.0-only and Apache-2.0 and BSD-3-Clause and dtoa and ISC and MIT and OpenSSL and SUSE-Public-Domain and Unicode-DFS-2016
Group:          Development/Languages/Rust

URL:            https://github.com/signalapp/ringrtc/
#
# Created with create_tarball.sh
Source0:        webrtc-%{webrtc_req_version}.tar.zst
Source1:        https://github.com/signalapp/%{pkg_name}/archive/v%{version}/%{pkg_name}-%{version}.tar.gz
# Created by prepare-vendor.sh
Source2:        vendor.tar.zst
Source3:        cargo_config

# PATCHES for openSUSE-specific things
Patch1:         signal-webrtc-disable-compiler-configs.patch
Patch8:         gcc-asmflags.patch
Patch11:        ringrtc-rust-hidden-visibility.patch
Patch12:        cubeb-no-static.patch
Patch13:        cubeb-core-visibility-hidden.patch
Patch14:        cc-link-lib-no-static.patch
Patch15:        cubeb-wrap-internal-cargo.patch
Patch16:        cubeb-sys-debug.patch

# PATCHES to use system libs
Patch1005:      system-opus.patch
Patch1006:      system-absl_algorithm.patch
Patch1009:      system-protobuf.patch
Patch1010:      cr130-abseil-remove-unused-deps.patch

#PATCHES to fix compatibility with other software
Patch2000:      scoped_refptr-abseil-2401.patch
Patch2001:      macros-abseil-2401.patch

#PATCHES that should be upstreamed verbatim or near-verbatim
Patch3000:      boringssl-internal-addc-cxx.patch
Patch3001:      matched_filter_lag_aggregator-missing-unique_ptr.patch
Patch3002:      ssl_stream_adapter-missing-optional.patch

BuildRequires:  cargo >= 1.52.0
BuildRequires:  nodejs

BuildRequires:  cmake
BuildRequires:  gn
BuildRequires:  jq
%if 0%{?suse_version}
BuildRequires:  ninja
%else
BuildRequires:  ninja-build
%endif
%if %{with system_abseil}
BuildRequires:  pkgconfig(absl_algorithm)
BuildRequires:  pkgconfig(absl_algorithm_container) >= 20211000
BuildRequires:  pkgconfig(absl_any_invocable)
BuildRequires:  pkgconfig(absl_base)
BuildRequires:  pkgconfig(absl_bind_front)
BuildRequires:  pkgconfig(absl_bits)
BuildRequires:  pkgconfig(absl_btree)
BuildRequires:  pkgconfig(absl_cleanup)
BuildRequires:  pkgconfig(absl_config)
BuildRequires:  pkgconfig(absl_cord)
BuildRequires:  pkgconfig(absl_core_headers)
BuildRequires:  pkgconfig(absl_failure_signal_handler)
BuildRequires:  pkgconfig(absl_fixed_array)
BuildRequires:  pkgconfig(absl_flags)
BuildRequires:  pkgconfig(absl_flags_parse)
BuildRequires:  pkgconfig(absl_flags_usage)
BuildRequires:  pkgconfig(absl_flat_hash_map)
BuildRequires:  pkgconfig(absl_flat_hash_set)
BuildRequires:  pkgconfig(absl_hash)
BuildRequires:  pkgconfig(absl_inlined_vector)
BuildRequires:  pkgconfig(absl_int128)
BuildRequires:  pkgconfig(absl_memory)
BuildRequires:  pkgconfig(absl_node_hash_map)
BuildRequires:  pkgconfig(absl_node_hash_set)
BuildRequires:  pkgconfig(absl_nullability)
BuildRequires:  pkgconfig(absl_optional)
BuildRequires:  pkgconfig(absl_random_random)
BuildRequires:  pkgconfig(absl_span)
BuildRequires:  pkgconfig(absl_stacktrace)
BuildRequires:  pkgconfig(absl_status)
BuildRequires:  pkgconfig(absl_statusor)
BuildRequires:  pkgconfig(absl_strings)
BuildRequires:  pkgconfig(absl_str_format)
BuildRequires:  pkgconfig(absl_symbolize)
BuildRequires:  pkgconfig(absl_synchronization)
BuildRequires:  pkgconfig(absl_time)
BuildRequires:  pkgconfig(absl_type_traits)
BuildRequires:  pkgconfig(absl_variant)
%endif
BuildRequires:  pkgconfig(alsa)
BuildRequires:  pkgconfig(gio-2.0)
BuildRequires:  pkgconfig(gio-unix-2.0)
BuildRequires:  pkgconfig(libevent)
BuildRequires:  pkgconfig(libpulse)
%if %{with system_libyuv}
# Needs I410Rotate
%if 0%{?suse_version}
BuildRequires:  pkgconfig(libyuv) >= 1855
%endif
# Fedora does not provide meaningful versioning, sorry
BuildRequires:  pkgconfig(libyuv)
%else
BuildRequires:  pkgconfig(libjpeg) >= 1.5
%endif
BuildRequires:  pkgconfig(opus) >= 1.3.1
%if %{with system_abseil}
#any re2 will do
BuildRequires:  pkgconfig(re2)
%else
#needs to be old version so as not to collide with bundled abseil headers
BuildRequires:  pkgconfig(re2) < 11
%endif

BuildRequires:  pkgconfig(vpx) >= 1.8.2
%if 0%{?fedora}
BuildRequires:  libatomic
%endif
%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150700 || 0%{?fedora}
%define PYVER 3
%else
%define PYVER 311
BuildRequires:  python311-base
%endif
BuildRequires:  protobuf-devel
%if 0%{?fedora}
BuildRequires:  rust-srpm-macros
%else
BuildRequires:  cargo-packaging >= 1.2.0+3
BuildRequires:  cargo-auditable
%endif
BuildRequires:  zstd

%if 0%{?suse_version} > 1500 || 0%{?fedora_version}
BuildRequires:  gcc >= 11
BuildRequires:  gcc-c++ >= 11
%else
#It actually needs to be the same version as used by Rust.
BuildRequires:  gcc13-PIE
BuildRequires:  gcc13-c++
%endif

#For cubeb-sys
BuildRequires: pkgconfig(speexdsp)
BuildRequires: pkgconfig(libpulse)
BuildRequires: pkgconfig(alsa)
BuildRequires: pkgconfig(jack)
%if 0%{?suse_version}
BuildRequires: sndio-devel
%endif
BuildRequires: doxygen
BuildRequires: graphviz


# Fedora thinks this is a native node module and adds an unwanted dependency on nodejs(abiXX)
%global __nodejs_native_requires %nil

%description
RingRTC is a middleware library providing Signal Messenger applications with
video and voice calling services built on top of WebRTC.

%package -n %rpm_name
Summary: Video and voice calling services for Signal Messenger
Group: System/Libraries
Provides: bundled(signal-webrtc) = %webrtc_req_version

%description -n %rpm_name
RingRTC is a middleware library providing Signal Messenger applications with
video and voice calling services built on top of WebRTC.

%prep
%setup -q -T -b 2 -n src
%setup -q -n webrtc-%{webrtc_req_version} -a1


ln -srv %{pkg_name}-%{version}/src/rust -t ringrtc
mv -v ../src/rust/vendor -t ringrtc/rust/

%autopatch -p1


install -d -m 0755 ringrtc/rust/.cargo
cp -p %{SOURCE3} ringrtc/rust/.cargo/config

# Sanity check if we have the correct webrtc version
test $(grep ^webrtc.version= %{pkg_name}-%{version}/config/version.properties | sed 's/.*=//') = %{webrtc_req_version}

# https://blogs.gnome.org/mcatanzaro/2020/05/18/patching-vendored-rust-dependencies/
pushd ringrtc/rust/vendor/libloading
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/prost-build
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/aes-gcm-siv
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/rustix
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/cubeb-core
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/cubeb-sys
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/cc
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/blake2
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd
pushd ringrtc/rust/vendor/cubeb-sys/libcubeb/src/cubeb-pulse-rs/vendor/cubeb-sys
jq -cj '.files={}' .cargo-checksum.json >tmp && mv tmp .cargo-checksum.json && popd

cat >/home/abuild/rpmbuild/BUILD/cargo-wrapper <<"EOF"
cargo -vv $auditable rustc --lib --offline --release --features=gecko-in-tree --crate-type staticlib
EOF

chmod -v +x /home/abuild/rpmbuild/BUILD/cargo-wrapper

gn_system_libraries=(
    libevent
    libjpeg
    libvpx
    opus
    re2
    zlib
)

%if %{with system_abseil}
find third_party/abseil-cpp -type f ! -name "*.gn" -a ! -name "*.gni" -delete
gn_system_libraries+=(
   absl_algorithm
   absl_base
   absl_cleanup
   absl_container
   absl_debugging
   absl_flags
   absl_functional
   absl_hash
   absl_log
   absl_log_internal
   absl_memory
   absl_meta
   absl_numeric
   absl_random
   absl_status
   absl_strings
   absl_synchronization
   absl_time
   absl_types
   absl_utility
)
%endif

%if %{with system_libyuv}
find third_party/libyuv -type f ! -name "*.gn" -a ! -name "*.gni" -delete
gn_system_libraries+=( libyuv )
%endif

build/linux/unbundle/replace_gn_files.py --system-libraries ${gn_system_libraries[@]}

%if %{with system_cubeb}
rm -rf ringrtc/rust/vendor/cubeb-sys/libcubeb
%endif


%build
export CFLAGS="%{optflags} -fpic -fno-semantic-interposition -fno-fat-lto-objects -fvisibility=hidden"
# Google has a bad coding style, using a macro `RTC_DCHECK_NOTREACHED()` that is not properly detected by GCC
# multiple times throughout the codebase. It is not possible to redefine the macro to __builtin_unreachable,
# as it has an astonishing syntax, behaving like an ostream (in debug builds it is supposed to trap and print an error message)
export CXXFLAGS="$CFLAGS -Wno-error=return-type"
export LDFLAGS="%{?build_ldflags} -Wl,--gc-sections -Wl,-O2"
# Chromium build system seems to rely on protobuf's transitive dependency on abseil if protozero_plugin uses abseil code. Work around this.
export LDFLAGS="$LDFLAGS -Wl,--copy-dt-needed-entries"
export MAKEFLAGS="%{_smp_mflags}"

export CC=gcc
export CXX=g++
export AR=gcc-ar
export NM=gcc-nm
export RANLIB=gcc-ranlib


mkdir -p "%{_builddir}/bin/"
%if 0%{?suse_version} && 0%{?suse_version} <= 1500
export CC=gcc-13
export CXX=g++-13
export AR=gcc-ar-13
export NM=gcc-nm-13
export RANLIB=gcc-ranlib-13
# some still call gcc/g++
ln -sfn %{_bindir}/$CC %{_builddir}/bin/gcc
ln -sfn %{_bindir}/$CXX %{_builddir}/bin/g++

#/suse_version <= 1500
%endif

%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150700 || 0%{?fedora}
ln -sfn %{_bindir}/python3 %{_builddir}/bin/vpython3
%else
ln -sfn %{_bindir}/python3.11 %{_builddir}/bin/vpython3
%endif

#AWFUL HACK: Custom cmake wrapper to override CFLAGS because -g -O2 seems to get stripped by Rust no matter what i do otherwise
#Compare openSUSE macros.cmake
cat <<"EOF" > %{_builddir}/bin/cmake
#!/bin/bash
if [[ "$1" = --build ]]; then
exec %{_bindir}/cmake "$@"
fi
exec %{_bindir}/cmake "$@" -DCMAKE_C_FLAGS="${CFLAGS}" \
        -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
        -DCMAKE_EXE_LINKER_FLAGS="$LDFLAGS -Wl,--as-needed -Wl,--no-undefined -Wl,-z,now" \
        -DCMAKE_MODULE_LINKER_FLAGS="$LDFLAGS -Wl,--as-needed" \
        -DCMAKE_SHARED_LINKER_FLAGS="$LDFLAGS -Wl,--as-needed -Wl,--no-undefined -Wl,-z,now"
EOF

cat %{_builddir}/bin/cmake

chmod +x %{_builddir}/bin/cmake

export PATH="%{_builddir}/bin/:$PATH"

# Create the configuration for GN
# Available options: gn args --list out/Release/
WEBRTC_ARGS=$(grep -F 'WEBRTC_ARGS="target' ringrtc-%{version}/bin/build-electron | sed 's/.*\}\\\"//' | sed 's/\"\s*$//' )
myconf_gn="$WEBRTC_ARGS"
myconf_gn+=' rtc_include_tests=false rtc_enable_protobuf=false'
myconf_gn+=" custom_toolchain=\"//build/toolchain/linux/unbundle:default\""
myconf_gn+=" host_toolchain=\"//build/toolchain/linux/unbundle:default\""
myconf_gn+=" use_custom_libcxx=false"
myconf_gn+=' use_safe_libstdcxx=false'
myconf_gn+=" is_debug=false"
myconf_gn+=" use_lld=false"
myconf_gn+=" use_sysroot=false"
myconf_gn+=" is_clang=false"
myconf_gn+=" treat_warnings_as_errors=false"
myconf_gn+=' perfetto_use_system_protobuf=true'

%ifarch %arm
#openSUSE only supports armhf
%ifarch armv7hl armv7hnl
myconf_gn+=" arm_version=7"
%endif
%ifarch armv6hl
myconf_gn+=" arm_version=6"
%endif
myconf_gn+=" arm_float_abi=\"hard\""
myconf_gn+=' arm_use_thumb=false'
# Disable requirement of neon instructions
%ifarch armv7hnl armv8hnl armv8hcnl
myconf_gn+=" arm_use_neon=true"
%else
myconf_gn+=" arm_use_neon=false"
myconf_gn+=" arm_optionally_use_neon=true"
%endif

%endif #ifarch arm


myconf_gn+=' rtc_link_pipewire=true'

#it is set by default to is_clang but should be enabled also on gcc
myconf_gn+=' rtc_enable_avx2=true'


gn gen --testonly=false --args="${myconf_gn}" out/release

# Pass the libs only to the linker, otherwise linking abseil will take 5+ hours
LIBS_WRAPPED=$(gn desc out/release :webrtc libs|sed  's/^/ -Clink-arg=-l/')


%ninja_build -C out/release webrtc




export OUTPUT_DIR="$(pwd)/out"
export RUSTC_BOOTSTRAP=1
export RUSTFLAGS="%{build_rustflags} ${LIBS_WRAPPED}  --verbose -Cstrip=none"
export RUSTC_LOG='rustc_codegen_ssa::back::link=info'
export CARGO_TERM_VERBOSE=true
# https://github.com/Firstyear/cargo-packaging/pull/10
export CARGO_INCREMENTAL=0

# The `cc` crate tries to be too clever and passes some default cflags to cmake.
# Disable these and use only the ones from CFLAGS env. variable
export CRATE_CC_NO_DEFAULTS=1
# Ensure cmake gets the RelWithDebInfo profile
export CARGO_PROFILE_RELEASE_DEBUG=2
# make cmake louder?
export VERBOSE=1
export V=1
# make cc crate output build log
export CC_ENABLE_DEBUG_OUTPUT=1




%if 0%{?suse_version}
export auditable='auditable -vv'
%endif

cd ringrtc/rust
cargo -vv $auditable rustc --package ringrtc --lib --offline --release --features electron --crate-type cdylib -- -lcubeb


%install
install -pvDm755 ringrtc-*/target/release/libringrtc.so \
%{buildroot}%{_libexecdir}/signal-desktop/node_modules/@signalapp/ringrtc/build/linux/libringrtc-$(echo -n 'console.log(require("node:process").arch)'|node).node

%check
# Sanity check that we don't have unresolved symbols. It does not fail the build in the case
# of a shared library, and that problem already happened twice in the history of this package.
# All unresolved symbols should start with napi, they are exported by electron itself and don't depend on the node API version.
pushd %{buildroot}%{_libexecdir}
find . -name '*.node' -print0 | xargs -0 -t -IXXX sh -c '! ldd -d -r XXX | \
grep    '\''^undefined symbol'\'' | \
grep -v '\''^undefined symbol: napi_'\'' '
popd

export CFLAGS="%{optflags} -fpic -fno-semantic-interposition -fno-fat-lto-objects -fvisibility=hidden"
export CXXFLAGS="$CFLAGS -Wno-error=return-type"
export LDFLAGS="%{?build_ldflags} -Wl,--gc-sections -Wl,-O2"
export LDFLAGS="$LDFLAGS -Wl,--copy-dt-needed-entries"
export MAKEFLAGS="%{_smp_mflags}"
export CC=gcc
export CXX=g++
export AR=gcc-ar
export NM=gcc-nm
export RANLIB=gcc-ranlib
%if 0%{?suse_version} && 0%{?suse_version} <= 1500
export CC=gcc-13
export CXX=g++-13
export AR=gcc-ar-13
export NM=gcc-nm-13
export RANLIB=gcc-ranlib-13
%endif
export PATH="%{_builddir}/bin/:$PATH"
LIBS_WRAPPED=$(gn desc out/release :webrtc libs|sed  's/^/ -Clink-arg=-l/')
export OUTPUT_DIR="$(pwd)/out"
export RUSTC_BOOTSTRAP=1
export RUSTFLAGS="%{build_rustflags} ${LIBS_WRAPPED}  --verbose -Cstrip=none"
export RUSTC_LOG='rustc_codegen_ssa::back::link=info'
export CARGO_TERM_VERBOSE=true
export CARGO_INCREMENTAL=0
export CRATE_CC_NO_DEFAULTS=1
export CARGO_PROFILE_RELEASE_DEBUG=2
export VERBOSE=1
export V=1
export CC_ENABLE_DEBUG_OUTPUT=1

%if 0%{?suse_version}
export auditable='auditable -vv'
%endif

cd ringrtc/rust
# `sim` must be used for tests, and `native` (which is implied by `electron`) cannot be used together with `sim`
RUN_TESTS="cargo -vv $auditable test --release --no-fail-fast --package ringrtc --package protobuf --package regex-aot --features neon,sim"
# Several of the tests are flaky. Sigh.
$RUN_TESTS || $RUN_TESTS || $RUN_TESTS
#We should test all first-party dependencies of `ringrtc` crate.
#Thus since 2.44.0, we should also be running tests for `--package mrp`
#but they sometimes hang for tens of minutes. This cannot be worked around with the above hack,
#thus we don't run them currently.

%files -n %rpm_name
%defattr(-,root,root)
%license ringrtc-*/LICENSE ringrtc-*/acknowledgments/acknowledgments.html
%doc ringrtc-*/README.md ringrtc-*/CHANGELOG.md
%{_libexecdir}/signal-desktop/

%changelog
openSUSE Build Service is sponsored by