Johdanto

Edellisessä blogikirjoitussarjassa

Kirjoitin Raspbianin asentamisesta Raspberry Compute Moduleen ja QtCreatorin ristiinkääntämisen määrittämisestä Ubuntu 20:ssä.

Tämä blogikirjoitus on päivitys - tällä hetkellä - uusimpaan versioon 6.8 Qt:stä, raspi OS Bookworm ja Ubuntu 22.04 LTS.

Edellytykset

Käytin seuraavia laitteita ja ohjelmistoja:

  • Raspberry Pi 4
  • raspi OS Bookworm, ilman suositeltua ohjelmistoa
  • Ubuntu 22.04 LTS
  • Qt 6.8
  • QtCreator 14.02

Huomautukset

Jos sinulla on kannettava tietokone tai pöytätietokone, jossa on riittävästi RAM-muistia ja prosessoriytimiä, voit tehdä ristiinkäännön virtuaalikoneessa. Olen kuitenkin kokenut, että natiivikone on paljon nopeampi ja tuottaa vähemmän virheitä.

Tutustu koodiesimerkkieni tiedostopolkuihin ja ip-osoitteisiin ja säädä ne omiin tarpeisiisi.

Raspberry Pi:n asennus

  • Lataa raspiOS osoitteesta https://www.raspberrypi.com/software/operating-systems
  • 2024-07-04-raspios-bookworm-arm64.img.xz: 64-bittinen Raspberry Pi OS työpöydällä (ei suositellun ohjelmiston kanssa).
  • Flash-kuva SD-kortille Balena Etcherillä.
  • Seuraa asennusta äläkä unohda etäyhteyden (ssh) asetuksia.
  • Yhdistä RPi:hen ssh:llä -> minun tapauksessani IP-osoitteeseen 192.168.2.167 ja käyttäjäksi pi -> Ubuntu hostista.
ssh [email protected]
  • Asenna tarvittavat ohjelmistot:
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
  • Tee kansio Qt 6:n asennusta varten:
sudo mkdir /usr/local/qt6
  • Löydä gcc:n, ld:n ja ldd:n versiot. Saman version lähdekoodi on ladattava, jotta myöhemmin voidaan rakentaa ristiinkääntäjä.
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.
  • Liitä seuraava koodinpätkä ~/.bashrc-tiedoston loppuun ja päivitä muutokset:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib/
source ~/.bashrc

Ubuntu 22.04 LTS:n asennus

  • Päivitä ohjelmistopakettien uusimmat versiot:
sudo apt update
sudo apt upgrade
  • Asenna seuraavat paketit:
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

Rakenna uusin cmake-versio lähdekoodista:

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

Rakenna gcc ristiinkääntäjäksi.

Lataa tarvittava lähdekoodi. Seuraavat komennot kannattaa muokata tarpeidesi mukaan. Sillä aikaa kun teen tämän sivun, ne ovat:

  • gcc 12.2.0
  • binutils 2.40(ld-versio)
  • glibc 2.36(ldd-versio)
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
  • Tee kansio kääntäjän asennusta varten.
sudo mkdir -p /opt/cross-pi-gcc
sudo chown $USER /opt/cross-pi-gcc
export PATH=/opt/cross-pi-gcc/bin:$PATH
  • Kopioi ytimen otsikot edellä mainittuun kansioon.
cd ~/gcc_all
cd linux
KERNEL=kernel7
make ARCH=arm64 INSTALL_HDR_PATH=/opt/cross-pi-gcc/aarch64-linux-gnu headers_install
  • Rakenna 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
  • Muokkaa gcc-12.2.0/libsanitizer/asan/asanan_linux.cpp. Lisää seuraava koodinpätkä.
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
  • Tee gcc:n osittainen build.
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
  • Rakenna osittain Glibc.
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
  • Palaa takaisin gcc:hen.
cd ~/gcc_all/build-gcc
make -j8 all-target-libgcc
make install-target-libgcc
  • Viimeistele glibc:n rakentaminen.
cd ~/gcc_all/build-glibc
make -j8
make install
  • Viimeistele gcc:n rakentaminen.
cd ~/gcc_all/build-gcc
make -j8
make install

Tässä vaiheessa meillä on täysi ristiinkääntäjätyökaluketju gcc:n kanssa. Kansiota gcc_all ei enää tarvita. Voit poistaa sen.

Qt6:n rakentaminen

Qt6:n rakentamiseen on kaksi vaihtoehtoa. On ladattavissa "single" (https://download.qt.io/official_releases/qt/6.8/6.8.0/single/qt-everywhere-src-6.8.0.tar.xz) versio, joka sisältää qtbase ja kaikki alamoduulit. Tämä on hyvin raskasta tavaraa ja sen kääntäminen vaatii paljon tehoa ja aikaa.

Suosittelen, että käännät qtbase perustaksi ja sen jälkeen käännät vain jokaisen tarvitsemasi alamoduulin erikseen.

  • Tee kansiot sysrootille ja qt6:lle. Luon nämä kansiot workspace/qt-rpi-cross-compilation -hakemistoon.
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
  • Lataa QtBasen lähdekoodi
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

Rakenna Qt6 isännälle

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 .

Binäärit ovat osoitteessa ~/workspace/qt-rpi-cross-compilation/qt6/host.

Rakenna Qt6 rpi:lle

Kopioi ja liitä muutama kansio rpi:stä rsync:llä SSH:n kautta.

cd ~
rsync -avz --rsync-path="sudo rsync" [email protected]:/usr/include workspace/qt-rpi-cross-compilation/rpi-sysroot/usr
rsync -avz --rsync-path="sudo rsync" [email protected]:/lib workspace/qt-rpi-cross-compilation/rpi-sysroot
rsync -avz --rsync-path="sudo rsync" [email protected]:/usr/lib workspace/qt-rpi-cross-compilation/rpi-sysroot/usr 
rsync -avz --rsync-path="sudo rsync" [email protected]:/opt/vc workspace/qt-rpi-cross-compilation/rpi-sysroot/opt
  • Luo tiedosto nimeltä toolchain.cmake osoitteeseen ~/workspace/qt-rpi-cross-compilation/qt6. Sinun on mukautettava rivi "set(TARGET_SYSROOT /home/factory/workspace/qt-rpi-cross-compilation/rpi-sysroot)" ympäristösi mukaiseksi.
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")
  • Korjaa absoluuttiset symboliset linkit
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
  • Käännä lähdekoodi rpi:lle.
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 .
  • Lähetä binäärit rpi:lle.
rsync -avz --rsync-path="sudo rsync" $HOME/workspace/qt-rpi-cross-compilation/qt6/pi/* [email protected]:/usr/local/qt6

QtCreatorin määrittäminen

  • Aseta kääntäjät

    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta
    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta
  • Virheenkorjaajien määrittäminen

    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta
  • Laitteiden määrittäminen

    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta Testaa yhteys painikkeella "Test"
  • Määritä Qt-versiot

    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta
  • Aseta sarjat

    Qt 6.8 Cross-Compilation for Raspberry Pi kuvakaappaus tietokoneesta
  • Valitse "CMake Configuration" -kohdassa Change ja lisää seuraavat komennot.

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

QtCreator-projektien asetukset

Jos luot projektin QtCreatorissa, sinun on säädettävä "Run" -asetuksia. Kohtaan "Environment" on lisättävä:

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

Qt-alimoduulien lisääminen

Lisää QML-moduuli

  • Lataa lähdekoodit:
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

Sinun on tarkistettava riippuvuudet osoitteista ~/workspace/qt-rpi-cross-compilation/qt6/src/qtdeclarative-everywhere-src-6.8.0/dependencies.yaml ja ~/workspace/qt-rpi-cross-compilation/qt6/src/qtshadertools-everywhere-src-6.8.0/dependencies.yaml.

Varmista, että tarvittavat moduulit on ensin rakennettava ja asennettava.

  • Rakenna moduulit isäntäkoneelle.
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 .
  • Rakenna moduulit rpi:tä varten.
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 .
  • Lähetä binäärit rpi:lle.
rsync -avz --rsync-path="sudo rsync" $HOME/workspace/qt-rpi-cross-compilation/qt6/pi/* [email protected]:/usr/local/qt6

Kiitokset

admin

Päivitetty osoitteessa: 16. October 2024
Lukuaika: 6 minuuttia