מבוא

בסדרה קודמת של פוסטים בבלוג

כתבתי על ההתקנה של Raspbian על מודול מחשוב פטל והגדרת הידור צולב עבור QtCreator על אובונטו 20.

פוסט בלוג זה הוא עדכון לגרסה - בשלב זה - החדשה ביותר 6.8 של Qt, raspi OS Bookworm ו- Ubuntu 22.04 LTS.

דרישות מוקדמות

השתמשתי בתוכנות הקשיחות הבאות:

  • Raspberry Pi 4
  • raspi OS Bookworm, ללא תוכנה מומלצת
  • Ubuntu 22.04 LTS
  • Qt 6.8
  • QtCreator 14.02

הערות

אם יש לך מחשב נייד או שולחני עם מספיק RAM וליבות CPU, אתה יכול לעשות את ההידור הצלב במחשב וירטואלי. אבל עשיתי את החוויה, שמחשב נייטיב הוא הרבה יותר מהיר ומייצר פחות שגיאות.

עיין בנתיבי הקבצים ובכתובות ה- IP בדוגמאות הקוד שלי והתאם אותם לצרכים שלך.

התקנה Raspberry Pi

  • הורד raspiOS מ https://www.raspberrypi.com/software/operating-systems
  • 2024-07-04-raspios-bookworm-arm64.img.xz: 64bit עם מערכת ההפעלה Raspberry Pi עם שולחן העבודה (לא עם תוכנה מומלצת)
  • תמונת פלאש לכרטיס SD עם Balena Etcher
  • עקוב אחר ההתקנה ואל תשכח את ההגדרה לחיבור מרחוק (ssh)
  • התחבר RPi עם ssh -> במקרה שלי לכתובת IP 192.168.2.167 ומשתמש pi -> ממארח אובונטו שלך
ssh pi@192.168.2.167
  • התקן את התוכנה הדרושה:
sudo apt-get install libboost-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev libxkbcommon-dev libegl1-mesa-dev libgbm-dev libgles2-mesa-dev mesa-common-dev libasound2-dev libpulse-dev gstreamer1.0-omx libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev  gstreamer1.0-alsa libvpx-dev libsrtp2-dev libsnappy-dev libnss3-dev "^libxcb.*" flex bison libxslt-dev ruby gperf libbz2-dev libcups2-dev libatkmm-1.6-dev libxi6 libxcomposite1 libfreetype6-dev libicu-dev libsqlite3-dev libxslt1-dev 
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libx11-dev freetds-dev libsqlite3-dev libpq-dev libiodbc2-dev firebird-dev libxext-dev libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev libatspi2.0-dev libxcursor-dev libxcomposite-dev libxdamage-dev libxss-dev libxtst-dev libpci-dev libcap-dev libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev gdbserver
  • צור תיקייה להתקנת Qt 6:
sudo mkdir /usr/local/qt6
  • גלה גרסאות של gcc, ld ו- ldd. יש להוריד קוד מקור של אותה גרסה כדי לבנות מהדר צולב מאוחר יותר.
pi@raspberrypi:~ $ gcc --version
gcc (Debian 12.2.0-14) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

pi@raspberrypi:~ $ ld --version
GNU ld (GNU Binutils for Debian) 2.40
Copyright (C) 2023 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

pi@raspberrypi:~ $ ldd --version
ldd (Debian GLIBC 2.36-9+rpt2+deb12u8) 2.36
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
  • צרף את קטע הקוד הבא לסוף ~/.bashrc ועדכן שינויים:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib/
source ~/.bashrc

התקנה אובונטו 22.04 LTS

  • עדכון לגרסאות העדכניות ביותר של חבילות התוכנה:
sudo apt update
sudo apt upgrade
  • התקן את החבילות הבאות:
sudo apt-get install make build-essential libclang-dev ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev build-essential gawk git texinfo bison file wget libssl-dev gdbserver gdb-multiarch libxcb-cursor-dev

בנה את גרסת cmake העדכנית ביותר מהמקור:

cd ~
wget https://github.com/Kitware/CMake/releases/download/v3.30.5/cmake-3.30.5.tar.gz
tar -xzvf cmake-3.30.5.tar.gz
cd cmake-3.30.5
./bootstrap
make -j$(nproc)
sudo make install
# Update PATH Environment Variable
which cmake
/usr/local/bin/cmake
export PATH=/usr/local/bin/cmake:$PATH
source ~/.bashrc
cmake --version

בניית gcc כמהדר צולב

הורד את קוד המקור הדרוש. עליך לשנות את הפקודות הבאות בהתאם לצרכיך. בזמן שאני עושה את הדף הזה, הם:

  • GCC 12.2.0
  • Binutils 2.40 (גרסת LD)
  • glibc 2.36 (גרסת LDD)
cd ~
mkdir gcc_all && cd gcc_all
wget https://ftpmirror.gnu.org/binutils/binutils-2.40.tar.bz2
wget https://ftpmirror.gnu.org/glibc/glibc-2.36.tar.bz2
wget https://ftpmirror.gnu.org/gcc/gcc-12.2.0/gcc-12.2.0.tar.gz
git clone --depth=1 https://github.com/raspberrypi/linux
tar xf binutils-2.40.tar.bz2
tar xf glibc-2.36.tar.bz2
tar xf gcc-12.2.0.tar.gz
rm *.tar.*
cd gcc-12.2.0
contrib/download_prerequisites
  • צור תיקייה להתקנת המהדר.
sudo mkdir -p /opt/cross-pi-gcc
sudo chown $USER /opt/cross-pi-gcc
export PATH=/opt/cross-pi-gcc/bin:$PATH
  • העתק את כותרות הליבה בתיקייה לעיל.
cd ~/gcc_all
cd linux
KERNEL=kernel7
make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross-pi-gcc/aarch64-linux-gnu headers_install
  • בניית Binutils.
cd ~/gcc_all
mkdir build-binutils && cd build-binutils
../binutils-2.40/configure --prefix=/opt/cross-pi-gcc --target=aarch64-linux-gnu --with-arch=armv8 --disable-multilib
make -j 8
make install
  • ערוך gcc-12.2.0/libsanitizer/asan/asan_linux.cpp. הוסף את קטע הקוד הבא.
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
  • לעשות בנייה חלקית של GCC.
cd ~/gcc_all
mkdir build-gcc && cd build-gcc
../gcc-12.2.0/configure --prefix=/opt/cross-pi-gcc --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-multilib
make -j8 all-gcc
make install-gcc
  • בנייה חלקית של גליבק.
cd ~/gcc_all
mkdir build-glibc && cd build-glibc
../glibc-2.36/configure --prefix=/opt/cross-pi-gcc/aarch64-linux-gnu --build=$MACHTYPE --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-headers=/opt/cross-pi-gcc/aarch64-linux-gnu/include --disable-multilib libc_cv_forced_unwind=yes
make install-bootstrap-headers=yes install-headers
make -j8 csu/subdir_lib
install csu/crt1.o csu/crti.o csu/crtn.o /opt/cross-pi-gcc/aarch64-linux-gnu/lib
aarch64-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /opt/cross-pi-gcc/aarch64-linux-gnu/lib/libc.so
touch /opt/cross-pi-gcc/aarch64-linux-gnu/include/gnu/stubs.h
  • חזרה ל-gcc.
cd ~/gcc_all/build-gcc
make -j8 all-target-libgcc
make install-target-libgcc
  • גימור בניית glibc.
cd ~/gcc_all/build-glibc
make -j8
make install
  • סיום בניית gcc.
cd ~/gcc_all/build-gcc
make -j8
make install

בשלב זה, יש לנו שרשרת כלים מלאה של מהדר צולב עם gcc. gcc_all תיקיה אינו נחוץ עוד. אתה יכול למחוק אותו.</:code19:></:code18:></:code17:></:code16:></:code15:></:code14:></:code13:></:code12:></:code11:></:code10:></:code9:></:code8:></:code7:>

בניין Qt6

ישנן שתי אפשרויות לבנות Qt6. יש גרסת "single" (https://download.qt.io/official_releases/qt/6.8/6.8.0/single/qt-everywhere-src-6.8.0.tar.xz) להורדה, המכילה qtbase ואת כל תת המודולים. זה חומר כבד מאוד וצריך הרבה כוח וזמן כדי להרכיב אותו.

ההמלצה שלי היא, לקמפל qtbase כבסיס ולאחר מכן לקמפל רק כל תת מודול שאתה צריך בנפרד.

  • צור תיקיות עבור sysroot ו qt6. אני יוצר תיקיות אלה בספריית סביבת העבודה/qt-rpi-cross-compilation שלי.
cd ~/workspace/qt-rpi-cross-compilation
mkdir rpi-sysroot rpi-sysroot/usr rpi-sysroot/opt
mkdir qt6 qt6/host qt6/pi qt6/host-build qt6/pi-build qt6/src
  • הורד קוד מקור QtBase
cd ~/workspace/qt-rpi-cross-compilation/qt6/src
wget https://download.qt.io/official_releases/qt/6.8/6.8.0/submodules/qtbase-everywhere-src-6.8.0.tar.xz
tar xf qtbase-everywhere-src-6.8.0.tar.xz

בניית Qt6 עבור מארח

cd ~/workspace/qt-rpi-cross-compilation/qt6/host-build/
cmake ../src/qtbase-everywhere-src-6.8.0/ -GNinja -DCMAKE_BUILD_TYPE=Release -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/qt6/host
cmake --build . --parallel 8
cmake --install .

הקבצים הבינאריים יהיו ב~/workspace/qt-rpi-cross-compilation/qt6/host

בניית Qt6 עבור rpi

העתק והדבק כמה תיקיות מ- rpi באמצעות rsync עד SSH.

cd ~
rsync -avz --rsync-path="sudo rsync" pi@192.168.2.167:/usr/include workspace/qt-rpi-cross-compilation/rpi-sysroot/usr
rsync -avz --rsync-path="sudo rsync" pi@192.168.2.167:/lib workspace/qt-rpi-cross-compilation/rpi-sysroot
rsync -avz --rsync-path="sudo rsync" pi@192.168.2.167:/usr/lib workspace/qt-rpi-cross-compilation/rpi-sysroot/usr 
rsync -avz --rsync-path="sudo rsync" pi@192.168.2.167:/opt/vc workspace/qt-rpi-cross-compilation/rpi-sysroot/opt
  • צור קובץ בשם toolchain.cmake ב~/workspace/qt-rpi-cross-compilation/qt6. עליך להתאים את השורה "set(TARGET_SYSROOT /home/factory/workspace/qt-rpi-cross-compilation/rpi-sysroot)" לסביבה שלך.
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

# You should change location of sysroot to your needs.
set(TARGET_SYSROOT /home/factory/workspace/qt-rpi-cross-compilation/rpi-sysroot)
set(TARGET_ARCHITECTURE aarch64-linux-gnu)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})

set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${CMAKE_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

set(CMAKE_C_COMPILER /opt/cross-pi-gcc/bin/${TARGET_ARCHITECTURE}-gcc)
set(CMAKE_CXX_COMPILER /opt/cross-pi-gcc/bin/${TARGET_ARCHITECTURE}-g++)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -isystem=/usr/include -isystem=/usr/local/include -isystem=/usr/include/${TARGET_ARCHITECTURE}")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")

set(QT_COMPILER_FLAGS "-march=armv8-a")
set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-rpath-link=${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE} -Wl,-rpath-link=$HOME/qt6/pi/lib")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})

include(CMakeInitializeConfigs)

function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
  if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
    set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
        
    foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
      if (DEFINED QT_COMPILER_FLAGS_${config})
        set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
      endif()
    endforeach()
  endif()


  if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
    foreach (config SHARED MODULE EXE)
      set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
    endforeach()
  endif()

  _cmake_initialize_per_config_variable(${ARGV})
endfunction()

set(XCB_PATH_VARIABLE ${TARGET_SYSROOT})

set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include)
set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE}/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib)

set(EGL_INCLUDE_DIR ${GL_INC_DIR})
set(EGL_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libEGL.so)

set(OPENGL_INCLUDE_DIR ${GL_INC_DIR})
set(OPENGL_opengl_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libOpenGL.so)

set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})
set(GLIB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libGLESv2.so)

set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})
set(GLESv2_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libGLESv2.so)

set(gbm_INCLUDE_DIR ${GL_INC_DIR})
set(gbm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libgbm.so)

set(Libdrm_INCLUDE_DIR ${GL_INC_DIR})
set(Libdrm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libdrm.so)

set(XCB_XCB_INCLUDE_DIR ${GL_INC_DIR})
set(XCB_XCB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/${TARGET_ARCHITECTURE}/libxcb.so)

list(APPEND CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/usr/lib/${TARGET_ARCHITECTURE})
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/${TARGET_ARCHITECTURE}/cmake")
  • תיקון קישורים סמליים מוחלטים
cd ~/workspace/qt-rpi-cross-compilation
wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py 
python3 sysroot-relativelinks.py rpi-sysroot
  • הידור קוד מקור עבור rpi.
cd $HOME/workspace/qt-rpi-cross-compilation/qt6/pi-build
cmake ../src/qtbase-everywhere-src-6.8.0/ -GNinja -DCMAKE_BUILD_TYPE=Release -DINPUT_opengl=es2 -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DQT_HOST_PATH=$HOME/workspace/qt-rpi-cross-compilation/qt6/host -DCMAKE_STAGING_PREFIX=$HOME/workspace/qt-rpi-cross-compilation/qt6/pi -DCMAKE_INSTALL_PREFIX=/usr/local/qt6 -DCMAKE_TOOLCHAIN_FILE=$HOME/workspace/qt-rpi-cross-compilation/qt6/toolchain.cmake -DQT_QMAKE_TARGET_MKSPEC=devices/linux-rasp-pi4-aarch64 -DQT_FEATURE_xcb=ON -DFEATURE_xcb_xlib=ON -DQT_FEATURE_xlib=ON
cmake --build . --parallel 8
cmake --install .
  • שלח את הקבצים הבינאריים ל- rpi.
rsync -avz --rsync-path="sudo rsync" $HOME/workspace/qt-rpi-cross-compilation/qt6/pi/* pi@192.168.2.167:/usr/local/qt6

קביעת תצורה של QtCreator

  • הגדרת מהדרים

    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב
    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב
  • הגדרת מאתר באגים

    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב
  • הגדרת מכשירים

    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב בדוק את החיבור עם כפתור "בדיקה"
  • הגדרת גרסאות Qt

    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב
  • הגדרת ערכות

    Qt 6.8 הידור צולב עבור Raspberry Pi צילום מסך של מחשב
  • על "תצורת CMake" לחץ על שנה והוסף פקודות מעקב.

-DCMAKE_TOOLCHAIN_FILE:UNINITIALIZED=/home/pmy/qt6/pi/lib/cmake/Qt6/qt.toolchain.cmake

הגדרות פרויקטים של QtCreator

אם אתה יוצר פרויקט ב- QtCreator, עליך להתאים את תצורת "Run". ב "Environment" אתה צריך להוסיף:

-LD_LIBRARY_PATH=:/usr/local/qt6/lib/

הוספת תת-מודולים של Qt

הוסף מודול QML

  • הורד קודי מקור:
cd ~/workspace/qt-rpi-cross-compilation/qt6/src
wget https://download.qt.io/official_releases/qt/6.8/6.8.0/submodules/qtshadertools-everywhere-src-6.8.0.tar.xz
tar xf qtshadertools-everywhere-src-6.8.0.tar.xz
wget https://download.qt.io/official_releases/qt/6.8/6.8.0/submodules/qtdeclarative-everywhere-src-6.8.0.tar.xz
tar xf qtdeclarative-everywhere-src-6.8.0.tar.xz

אתה צריך לבדוק תלות ב ~/workspace/qt-rpi-cross-compilation/qt6/src/qtdeclarative-everywhere-src-6.8.0/dependencies.yaml ו ~/workspace/qt-rpi-cross-compilation/qt6/src/qtshadertools-everywhere-src-6.8.0/dependencies.yaml.

ודא שיש לבנות ולהתקין תחילה את המודולים הדרושים.

  • בניית המודולים עבור המארח.
cd ~/workspace/qt-rpi-cross-compilation/qt6/host-build
rm -rf *
$HOME/workspace/qt-rpi-cross-compilation/qt6/host/bin/qt-configure-module ../src/qtshadertools-everywhere-src-6.8.0
cmake --build . --parallel 8
cmake --install .
rm -rf *
$HOME/workspace/qt-rpi-cross-compilation/qt6/host/bin/qt-configure-module ../src/qtdeclarative-everywhere-src-6.8.0
cmake --build . --parallel 8
cmake --install .
  • בניית מודולים עבור rpi
cd ~/workspace/qt-rpi-cross-compilation/qt6/pi-build
rm -rf *
$HOME/workspace/qt-rpi-cross-compilation/qt6/pi/bin/qt-configure-module ../src/qtshadertools-everywhere-src-6.8.0
cmake --build . --parallel 8
cmake --install .
rm -rf *
$HOME/workspace/qt-rpi-cross-compilation/qt6/pi/bin/qt-configure-module ../src/qtdeclarative-everywhere-src-6.8.0
cmake --build . --parallel 8
cmake --install .
  • שלח את הקבצים הבינאריים ל- rpi.
rsync -avz --rsync-path="sudo rsync" $HOME/workspace/qt-rpi-cross-compilation/qt6/pi/* pi@192.168.2.167:/usr/local/qt6

תודות

המקורות המשמשים ליצירת הוראות אלה:

תודה לכולם.

admin

עודכן ב-: 16. October 2024
זמן קריאה: 6 דקות