Недавно для популярного пакета для работы с мультимедиа устройствами (в основном, с камерами) появилась возможность сборки через meson. В данной статье мы рассмотрим как это осуществить. Собирать будем в Ubuntu 22, но подойдёт и любой другой популярный современный дистрибутив.

Создадим базовый каталог v4l-utilsFromGit, который будет содержать в себе три подкаталога: каталог v4l-utils с исходными кодами, каталог build с промежуточными результатами сборки и каталог build_artifacts с результатами сборки (исполняемыми файлами).

mkdir ~/v4l-utilsFromGit && cd ~/v4l-utilsFromGit 
mkdir build build_artifacts 
git clone https://git.linuxtv.org/v4l-utils.git v4l-utils


Проведем инициализацию. Во время этого шага meson проверит конфигурацию нашей системы, удостоверится что для сборки есть необходимые средства (компилятор и т.п.)
meson setup build/ v4l-utils/

Вывод meson setup на Ubuntu 22 server

$ meson setup build/ v4l-utils/
The Meson build system
Version: 0.63.2
Source dir: /home/q/v4l-utilsFromGit/v4l-utils
Build dir: /home/q/v4l-utilsFromGit/build
Build type: native build
Project name: v4l-utils
Project version: 1.25.0
C compiler for the host machine: cc (gcc 12.2.0 "cc (Ubuntu 12.2.0-3ubuntu1) 12.2.0")
C linker for the host machine: cc ld.bfd 2.39
C++ compiler for the host machine: c++ (gcc 12.2.0 "c++ (Ubuntu 12.2.0-3ubuntu1) 12.2.0")
C++ linker for the host machine: c++ ld.bfd 2.39
Host machine cpu family: x86_64
Host machine cpu: x86_64
Compiler for C supports link arguments -m32: NO
Compiler for C supports arguments -fvisibility=hidden: YES
Compiler for C supports function attribute visibility:default: YES
Program bash found: YES (/usr/bin/bash)
Program clang found: NO
Program doxygen found: NO
Program grep found: YES (/usr/bin/grep)
Program perl found: YES (/usr/bin/perl)
Did not find pkg-config by name 'pkg-config'
Found Pkg-config: NO
Did not find CMake 'cmake'
Found CMake: NO
Run-time dependency alsa found: NO (tried pkgconfig and cmake)
Run-time dependency gl found: NO (tried pkgconfig and system)
Run-time dependency glu found: NO (tried pkgconfig and cmake)
Run-time dependency json-c found: NO (tried pkgconfig and cmake)
Library dl found: YES
Library elf found: NO
Library m found: YES
Library rt found: YES
qmake found: NO need ['>= 5', '< 6']
Run-time dependency qt5 (modules: Core, Gui, OpenGL, Widgets) found: NO (tried pkgconfig and config-tool)
Run-time dependency libbpf found: NO (tried pkgconfig and cmake)
sdl2-config found: NO
Run-time dependency sdl2 found: NO (tried pkgconfig and config-tool)
Has header "SDL2/SDL.h" : NO
Run-time dependency sdl2_image found: NO (tried pkgconfig and cmake)
Has header "SDL2/SDL_image.h" : NO
Run-time dependency threads found: YES
Run-time dependency x11 found: NO (tried pkgconfig and cmake)
Run-time dependency xmlrpc found: NO (tried pkgconfig and cmake)
Checking for function "fork" : YES
Has header "linux/i2c-dev.h" : YES
Checking for function "klogctl" : YES
Checking for function "secure_getenv" : YES
Checking for function "__secure_getenv" : NO
Has header "sys/klog.h" : YES
Header "execinfo.h" has symbol "backtrace" : YES
Checking for function "argp_parse" : YES
Checking for function "strerrorname_np" : YES
Run-time dependency iconv found: YES
Has header "gconv.h" : YES
Library JIS found: YES
Library JISX0213 found: YES
Run-time dependency libjpeg found: NO (tried pkgconfig and cmake)
Run-time dependency systemd found: NO (tried pkgconfig and cmake)
Run-time dependency libudev found: NO (tried pkgconfig and cmake)
Run-time dependency udev found: NO (tried pkgconfig and cmake)
Program git found: YES (/usr/bin/git)
Program msgfmt found: NO
v4l-utils/libdvbv5-po/meson.build:2: WARNING: Gettext not found, all translation (po) targets will be ignored.
v4l-utils/v4l-utils-po/meson.build:2: WARNING: Gettext not found, all translation (po) targets will be ignored.
Configuring cec-gen-dummy.stamp with command
Configuring config.h using configuration
Configuring cec-ctl.1 using configuration
Configuring cec-follower.1 using configuration
Configuring ir-ctl.1 using configuration
Configuring ir-keytable.1 using configuration
Configuring rc_keymap.5 using configuration
Configuring v4l2-ctl.1 using configuration
Configuring cec-compliance.1 using configuration
Configuring v4l2-compliance.1 using configuration
Configuring v4l-utils.spec using configuration
Build targets in project: 42
NOTICE: Future-deprecated features used:

  • 0.60.0: {'install_subdir with empty directory'}

v4l-utils 1.25.0

Dependencies
ALSA : NO
GL : NO
GLU : NO
JSON-C : NO
Qt5 : NO
without QtGL
SDL : NO
X11 : NO
gconv : YES
iconv : YES
libjpeg : NO
libudev : NO
threads : YES

Directories
udevdir : /lib/udev

Libraries
libdvbv5 : NO
v4l-plugins : YES
v4l-wrappers : YES

Applications
BPF IR decoders : NO
qv4l2 : NO
qvidcap : NO
v4l-utils : YES
v4l2-compliance : YES
with libv4l
v4l2-compliance-32: NO
v4l2-ctl : YES
with libv4l
v4l2-ctl-32 : NO
v4l2-tracer : NO

Found ninja-1.11.0 at /usr/bin/ninja

Посмотрим на текущую конфигурацию (какие настройки доступны и какие из них применены)
meson configure build/

Далее зададим некоторые опции. Если оставить shared как подразумевает оригинальный INSTALL.md, то при попытке запуска собранного приложения вылетит ошибка
v4l2-ctl: error while loading shared libraries: libv4l2.so.0: cannot open shared object file: No such file or directory
Напишите в комментариях как собрать работающее приложение с опцией shared.

А пока что переключим на static чтобы всё работало.
meson configure build/ -Ddefault_library=static

Вновь посмотрим на текущую конфигурацию, проверим изменение shared на static.
meson configure build/

Далее запустим сборку. Результат сборки будет помещён по пути destdir.
meson install --destdir ../build_artifacts/ -C build/

Можно проверить, что утилита запускается
~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl --help

Результат вывода
Результат вывода

Комментарии (2)


  1. truthseeker
    00.00.0000 00:00
    +1

    У меня запустилось, но только из-за уже установленной в системе версии либы

    ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl --version
    v4l2-ctl 1.25.0-5034

    ldd ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl | grep libv4l2.so.0
    libv4l2.so.0 => /usr/lib/libv4l2.so.0 (0x00007fe306d34000)

    Если убрать /usr/lib/libv4l2.so.0, та же ошибка возникает.

    ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl --version
    /home/andrei/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl: error while loading shared libraries: libv4l2.so.0: cannot open shared object file: No such file or directory

    Но, если добавить

    LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./build_artifacts/usr/local/lib/LD_LIBRARY_PATH

    export LD_LIBRARY_PATH

    то приложение запустится без системной версии этой либы, с только что нами собранной

    ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl --version
    v4l2-ctl 1.25.0-5034

    Проверяем, откуда либа подгрузилась

    ldd ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl | grep libv4l2.so.0
    libv4l2.so.0 => ./build_artifacts/usr/local/lib/libv4l2.so.0 (0x00007f4d7c1c2000)

    Как видно, Meson собрал приложение и либу корректно, они рабочие. Но, вы не установили собранное приложение, а потому в каталоге со структурой собранных артефактов у вас

    tree ~/v4l-utilsFromGit/build_artifacts/ -L 3
    tree ~/v4l-utilsFromGit/build_artifacts/ -L 3

    И, естественно, по умолчанию в вашей системе каталог ./build_artifacts/usr/local/lib/ не значится в списке каталогов, откуда загрузчик приложений подгружает shared libs при запуске приложения. Если его добавить ручками в переменную LD_LIBRARY_PATH, приложение запустится. Также можно либы нужные добавить в ldconfig, загрузчик ld.so будет знать где в кэше ldconfig прописан путь к нужной либе, и загрузит приложение нормально. Третий вариант запуска — это шаманство с погрузкой нужных либ через LD_PRELOAD. Есть ещё вариант с параметрами ld.so.

    Вывод: мало уметь корректно собирать приложение Linux, нужно ещё знать про то, в какие файлы и каталоги раскидать нужные артефакты на другой тачке, или воткнуть на той, где собирали, с помощью того же Meson. Ну, или про то, как работает ld.so и идёт процесс загрузки бинарника ELF в Linux, и где он ищет нужные ему либы. Настоятельно рекомендую почитать маны ld.so и ldconfig, ссылки на которые кидал выше.


    1. DungeonLords Автор
      00.00.0000 00:00

      Позвольте уточнить, вы собрали по предложенной мной методе (со static) и у вас не запускается? Я проверяю на Ubuntu 22 server

      q@q:~$ v4l2-ctl --help
      Command 'v4l2-ctl' not found, but can be installed with:
      sudo apt install v4l-utils

      То есть в моей системе приложение точно не установлено.

      А вот если запустить свежесобранное приложение, то я вижу его вывод.
      q@q:~$ ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl --help

      General/Common options: блаблабла

      Посмотрим какие shared libraries использовались при static сборке
      q@q:~/v4l-utilsFromGit/build_artifacts/usr/local/bin$ ldd ./v4l2-ctl
      linux-vdso.so.1 (0x00007ffeebbe4000)
      libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f0a91e00000)
      libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f0a91d17000)
      libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f0a92042000)
      libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a91a00000)
      /lib64/ld-linux-x86-64.so.2 (0x00007f0a9216f000)

      Если вы о том, что мною не указан шаг установки в систему (чтобы запускать без указания полного пути к приложению ~/v4l-utilsFromGit/build_artifacts/usr/local/bin/v4l2-ctl), то так и есть.
      Или вы о том, как собрать не static, а shared?

      P.S. Люблю хабр за то, что в комментариях сидят толковые люди с которыми интересно подискутировать и узнать много нового. Спасибо вам за интерес к моей публикации.