diff --git a/.github/workflows/ci-meson.yml b/.github/workflows/ci-meson.yml new file mode 100644 index 0000000..48d0441 --- /dev/null +++ b/.github/workflows/ci-meson.yml @@ -0,0 +1,426 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Copyright (c) 2023-2024 Linaro Ltd. +# Author: Krzysztof Kozlowski +# +# Copyright (c) 2025 Krzysztof Kozlowski +# Loosely based on https://github.com/linux-test-project/ltp +# +name: "Builds (meson)" +on: + pull_request: + push: + schedule: + # Run at 1:01 AM, every Tuesday + - cron: '1 1 * * 2' + workflow_dispatch: + +jobs: + job: + name: Build + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + arch: [x86-64] + compiler: [gcc, clang] + container: + - alpine:latest + - archlinux:latest + - debian:testing + - debian:stable + - debian:forky + - debian:trixie + - debian:bookworm + # Fails on configure on GCC and clang (process restrictions?) + # - fedora:rawhide + - fedora:latest + - fedora:44 + - fedora:43 + - ubuntu:latest + - ubuntu:resolute + - ubuntu:noble + - ubuntu:jammy + cross_compile: [""] + mode: [maintainer, no-maintainer] + variant: [""] + include: + # Debian 32-bit builds + - container: "debian:testing" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "debian:testing" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "debian:stable" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "debian:stable" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "debian:trixie" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "debian:trixie" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "debian:forky" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "debian:forky" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "debian:bookworm" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "debian:bookworm" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + # Debian cross compilation builds + - container: "debian:stable" + arch: armhf + compiler: arm-linux-gnueabihf-gcc + cross_compile: arm-linux-gnueabihf + mode: maintainer + variant: cross-compile + + - container: "debian:stable" + arch: arm64 + compiler: aarch64-linux-gnu-gcc + cross_compile: aarch64-linux-gnu + mode: maintainer + variant: cross-compile + + - container: "debian:stable" + arch: ppc64el + compiler: powerpc64le-linux-gnu-gcc + cross_compile: powerpc64le-linux-gnu + mode: maintainer + variant: cross-compile + + - container: "debian:stable" + arch: s390x + compiler: s390x-linux-gnu-gcc + cross_compile: s390x-linux-gnu + mode: maintainer + variant: cross-compile + + - container: "debian:bookworm" + arch: armhf + compiler: arm-linux-gnueabihf-gcc + cross_compile: arm-linux-gnueabihf + mode: maintainer + variant: cross-compile + + - container: "debian:bookworm" + arch: arm64 + compiler: aarch64-linux-gnu-gcc + cross_compile: aarch64-linux-gnu + mode: maintainer + variant: cross-compile + + - container: "debian:bookworm" + arch: ppc64el + compiler: powerpc64le-linux-gnu-gcc + cross_compile: powerpc64le-linux-gnu + mode: maintainer + variant: cross-compile + + - container: "debian:bookworm" + arch: s390x + compiler: s390x-linux-gnu-gcc + cross_compile: s390x-linux-gnu + mode: maintainer + variant: cross-compile + + # Debian GCC sanitizer builds + - container: "debian:testing" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "debian:stable" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "debian:trixie" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "debian:forky" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + # Ubuntu 32-bit builds + - container: "ubuntu:latest" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "ubuntu:latest" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "ubuntu:resolute" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "ubuntu:resolute" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "ubuntu:noble" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "ubuntu:noble" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + - container: "ubuntu:jammy" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: maintainer + variant: i386 + + - container: "ubuntu:jammy" + arch: i386 + compiler: gcc -m32 + cross_compile: i686-linux-gnu + mode: no-maintainer + variant: i386 + + # Ubuntu GCC sanitizer builds + - container: "ubuntu:latest" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "ubuntu:resolute" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "ubuntu:noble" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + - container: "ubuntu:jammy" + arch: x86-64 + compiler: gcc + mode: maintainer + variant: sanitizers + + container: + image: ${{ matrix.container }} + env: + ARCH: ${{ matrix.arch }} + CC: ${{ matrix.compiler }} + CROSS_COMPILE: ${{ matrix.cross_compile }} + MODE: ${{ matrix.mode }} + VARIANT: ${{ matrix.variant }} + + steps: + - name: Show OS + run: cat /etc/os-release + + - name: Show env (matrix settings) + run: | + echo "ARCH: $ARCH" + echo "CC: $CC" + echo "CROSS_COMPILE: $CROSS_COMPILE" + echo "MODE: $MODE" + echo "VARIANT: $VARIANT" + + - name: Git checkout + uses: actions/checkout@v6 + + - name: Install additional packages + run: | + INSTALL=${{ matrix.container }} + INSTALL="${INSTALL%%:*}" + INSTALL="${INSTALL%%/*}" + echo "Running ./ci/$INSTALL.meson.sh" + ./ci/$INSTALL.meson.sh + if [ "$VARIANT" ]; then + echo "Running ./ci/$INSTALL.meson.$VARIANT.sh" + ./ci/$INSTALL.meson.$VARIANT.sh; + fi + + - name: Compiler version + run: $CC --version + + - name: Display environment and Linux version + run: | + test -f /etc/issue && cat /etc/issue + echo "############################################" + lsb_release -a || true + echo "############################################" + cat /usr/include/linux/version.h + echo "############################################" + uname -a + echo "############################################" + cat /proc/cmdline + echo "############################################" + printenv + + - name: Display nfc.h differences between local and Linux kernel headers + run: diff -uBb /usr/include/linux/nfc.h include/nfc_copy.h || true + + - name: Configure + id: configure + run: | + SETUP_ARGS="" + if [ "$VARIANT" = "sanitizers" ]; then + SETUP_ARGS="-Db_sanitize=address,undefined -Db_pie=true" + fi + if [ "$MODE" = "maintainer" ]; then + SETUP_ARGS="$SETUP_ARGS --werror" + fi + CROSS_FILE_ARGS="" + if [ "$CROSS_COMPILE" ]; then + case "$ARCH" in + i386) CPU_FAMILY=x86; CPU=i686; ENDIAN=little; MULTIARCH=i386-linux-gnu ;; + armhf) CPU_FAMILY=arm; CPU=armv7; ENDIAN=little; MULTIARCH=arm-linux-gnueabihf ;; + arm64) CPU_FAMILY=aarch64; CPU=aarch64; ENDIAN=little; MULTIARCH=aarch64-linux-gnu ;; + ppc64el) CPU_FAMILY=ppc64; CPU=powerpc64le; ENDIAN=little; MULTIARCH=powerpc64le-linux-gnu ;; + s390x) CPU_FAMILY=s390x; CPU=s390x; ENDIAN=big; MULTIARCH=s390x-linux-gnu ;; + esac + CC=$CC \ + PKG_CONFIG=pkg-config \ + PKG_CONFIG_LIBDIR="/usr/lib/${MULTIARCH}/pkgconfig:/usr/share/pkgconfig" \ + meson env2mfile --cross \ + --system linux \ + --subsystem linux \ + --kernel linux \ + --cpu-family $CPU_FAMILY \ + --cpu $CPU \ + --endian $ENDIAN \ + -o /tmp/cross.ini + CROSS_FILE_ARGS="--cross-file /tmp/cross.ini" + fi + CC=$CC meson setup build \ + --prefix=/usr \ + --sysconfdir=/etc \ + -Dese=true \ + -Dtools=true \ + -Dsystemd=disabled \ + $SETUP_ARGS \ + $CROSS_FILE_ARGS + + - name: Get configure logs + run: cat build/meson-logs/meson-log.txt + if: ${{ always() && ((steps.configure.outcome == 'failure') || + (steps.configure.outcome == 'success')) }} + + - name: Compile + run: meson compile -C build + + - name: Run unit tests + id: unit_tests + run: meson test -C build + if: ${{ (matrix.arch == 'x86-64') || (matrix.arch == 'i386') }} + + - name: Get unit tests logs + run: cat build/meson-logs/testlog.txt + if: ${{ always() && ((steps.unit_tests.outcome == 'failure') || + (steps.unit_tests.outcome == 'success')) }} + + - name: Check final binary + run: | + file build/src/neard + ARCH_CHECK="$ARCH" + case "$ARCH" in + armhf) ARCH_CHECK="ARM, EABI";; + arm64) ARCH_CHECK="aarch64";; + # Glibc 2.41 seems to use "Intel i386" + i386) ARCH_CHECK="Intel 80386|Intel i386";; + ppc64el) ARCH_CHECK="64-bit PowerPC";; + s390x) ARCH_CHECK="IBM S/390";; + *) ARCH_CHECK="x86-64";; + esac + echo "Checking for built matching architecture: $ARCH_CHECK" + file build/src/neard | grep -E "$ARCH_CHECK" + if [ "$VARIANT" = "sanitizers" ]; then + echo "Checking for linking against sanitizer libraries" + ldd build/src/neard | grep libasan.so + # liblsan won't appear if asan is used + ldd build/src/neard | grep libubsan.so + fi + + - name: Install + run: meson install -C build diff --git a/INSTALL b/INSTALL.autotools similarity index 100% rename from INSTALL rename to INSTALL.autotools diff --git a/README b/README index aca7476..3b8ded7 100644 --- a/README +++ b/README @@ -11,49 +11,49 @@ In order to compile neard you need following software packages: - GCC compiler - D-Bus library - GLib library - - Netlink (libnl) library, version 1 or 2. + - Netlink (libnl) library, version 3, 2, or 1. + +neard uses the Meson build system and requires at least version 1.1. To configure run: - ./configure --prefix=/usr + meson setup builddir --prefix=/usr -Configure automatically searches for all required components and packages. +Meson automatically searches for all required components and packages. To compile and install run: - make && make install + meson compile -C builddir + meson install -C builddir Configuration and options ========================= By default all neard plugins and features are built in. They can be -disabled with the following configuration options: - - --disable-nfctype1 +adjusted with the following configuration options, passed as +-Doption=value to meson setup (or changed later with meson configure): - Disable support for type 1 NFC tags. + -Dnfctypes=nfctype1,nfctype2,nfctype3,nfctype4,nfctype5 - --disable-nfctype2 + Select which NFC Forum tag types (1 to 5) to support. - Disable support for type 2 NFC tags. + -Dp2p=true|false - --disable-nfctype3 + Enable or disable support for peer to peer mode. - Disable support for type 3 NFC tags. + -Dese=true|false - --disable-nfctype4 + Enable or disable embedded Secure Element support. - Disable support for type 4 NFC tags. + -Dsystemd=auto|enabled|disabled - --disable-nfctype5 + Install the systemd service file. - Disable support for type 5 ISO 15693 tags. + -Dtools=true|false - --disable-p2p + Build testing tools (nfctool, nciattach). - Disable support for peer to peer mode. + -Dtest=true|false -Running ./bootstrap-configure will build the configure script and then -run it, with maintainer mode enabled. bootstrap-configure will configure -neard with all features enabled. + Install test/example scripts. Bugs and contributing ===================== diff --git a/ci/alpine.meson.sh b/ci/alpine.meson.sh new file mode 100755 index 0000000..46c6377 --- /dev/null +++ b/ci/alpine.meson.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2019-2021 Petr Vorel +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# Copyright (c) 2026 Krzysztof Kozlowski +# + +set -ex + +apk update + +PKGS_CC="gcc" +case $CC in + clang*) + # On Alpine v3.14 clang fails without gcc: + # cannot find crtbeginS.o: No such file or directory + PKGS_CC="clang gcc" + ;; +esac + +# Packages needed by CI +PKGS_MORE="file" + +apk add \ + binutils \ + dbus-dev \ + glib-dev \ + libnl3-dev \ + meson \ + musl-dev \ + ninja \ + pkgconfig \ + $PKGS_CC \ + $PKGS_MORE + +echo "Install finished: $0" diff --git a/ci/archlinux.meson.sh b/ci/archlinux.meson.sh new file mode 100755 index 0000000..94da489 --- /dev/null +++ b/ci/archlinux.meson.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# + +set -ex + +PKGS_CC="gcc" +case $CC in + clang*) + PKGS_CC="clang" + ;; +esac + +pacman -Syu --noconfirm \ + dbus \ + glib2 \ + libnl \ + meson \ + ninja \ + pkg-config \ + $PKGS_CC + +echo "Install finished: $0" diff --git a/ci/debian.meson.cross-compile.sh b/ci/debian.meson.cross-compile.sh new file mode 100755 index 0000000..c88f54f --- /dev/null +++ b/ci/debian.meson.cross-compile.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018-2020 Petr Vorel +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# Copyright (c) 2025 Krzysztof Kozlowski +# + +set -ex + +if [ -z "$ARCH" ]; then + echo "missing \$ARCH!" >&2 + exit 1 +fi + +dpkg --add-architecture $ARCH +apt update + +apt install -y --no-install-recommends \ + libc6-dev-${ARCH}-cross + +apt install -y --no-install-recommends \ + libdbus-1-dev:${ARCH} \ + libglib2.0-dev:${ARCH} \ + libnl-3-dev:${ARCH} \ + libnl-genl-3-dev:${ARCH} \ + gcc-`dpkg-architecture -a ${ARCH} -q DEB_TARGET_GNU_TYPE` + +echo "Install finished: $0" diff --git a/ci/debian.meson.i386.sh b/ci/debian.meson.i386.sh new file mode 100755 index 0000000..773da42 --- /dev/null +++ b/ci/debian.meson.i386.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# + +set -ex + +dpkg --add-architecture i386 +apt update + +# gcc-multilib are also needed for clang 32-bit builds +PKGS_CC="gcc-multilib" + +apt install -y --no-install-recommends \ + linux-libc-dev:i386 + +apt install -y --no-install-recommends \ + libdbus-1-dev:i386 \ + libglib2.0-dev:i386 \ + libnl-3-dev:i386 \ + libnl-genl-3-dev:i386 \ + $PKGS_CC + +echo "Install finished: $0" diff --git a/ci/debian.meson.sanitizers.sh b/ci/debian.meson.sanitizers.sh new file mode 100755 index 0000000..f165531 --- /dev/null +++ b/ci/debian.meson.sanitizers.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# Copyright (c) 2025 Krzysztof Kozlowski +# + +set -ex + +apt install -y --no-install-recommends \ + liblsan0 \ + libubsan1 + +apt install -y --no-install-recommends libasan8 || \ + apt install -y --no-install-recommends libasan6 || \ + apt install -y --no-install-recommends libasan5 + +echo "Install finished: $0" diff --git a/ci/debian.meson.sh b/ci/debian.meson.sh new file mode 100755 index 0000000..9595e01 --- /dev/null +++ b/ci/debian.meson.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# + +set -ex + +apt update + +# Some distros (e.g. Ubuntu Hirsute) might pull tzdata which asks questions +export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true + +# Choose some random place in Europe +echo "tzdata tzdata/Areas select Europe +tzdata tzdata/Zones/Europe select Berlin +" > /tmp/tzdata-preseed.txt +debconf-set-selections /tmp/tzdata-preseed.txt + +PKGS_CC="build-essential" +case $CC in + clang*) + PKGS_CC="clang" + ;; +esac + +apt install -y --no-install-recommends \ + file \ + libdbus-1-dev \ + libglib2.0-dev \ + libnl-3-dev \ + libnl-genl-3-dev \ + meson \ + ninja-build \ + pkg-config \ + python3-pip \ + $PKGS_CC + +# Meson >= 1.1 is required. If the packaged version is older, install via pip. +MIN_MESON="1.1.0" +MESON_VER=$(meson --version 2>/dev/null || echo "0.0.0") +if dpkg --compare-versions "$MESON_VER" lt "$MIN_MESON"; then + pip3 install "meson>=$MIN_MESON" 2>/dev/null || \ + pip3 install --break-system-packages "meson>=$MIN_MESON" +fi + +echo "Install finished: $0" diff --git a/ci/fedora.meson.sh b/ci/fedora.meson.sh new file mode 100755 index 0000000..d04f657 --- /dev/null +++ b/ci/fedora.meson.sh @@ -0,0 +1,31 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2021 Canonical Ltd. +# Author: Krzysztof Kozlowski +# +# + +set -ex + +PKGS_CC="gcc" +case $CC in + clang*) + PKGS_CC="clang" + ;; +esac + +# Packages needed by CI +PKGS_MORE="file" + +dnf -y install \ + dbus-devel \ + glib2-devel \ + libnl3-devel \ + meson \ + ninja-build \ + pkg-config \ + $PKGS_CC \ + $PKGS_MORE + +echo "Install finished: $0" diff --git a/ci/ubuntu.meson.cross-compile.sh b/ci/ubuntu.meson.cross-compile.sh new file mode 120000 index 0000000..30e87c2 --- /dev/null +++ b/ci/ubuntu.meson.cross-compile.sh @@ -0,0 +1 @@ +debian.meson.cross-compile.sh \ No newline at end of file diff --git a/ci/ubuntu.meson.i386.sh b/ci/ubuntu.meson.i386.sh new file mode 120000 index 0000000..c6f5422 --- /dev/null +++ b/ci/ubuntu.meson.i386.sh @@ -0,0 +1 @@ +debian.meson.i386.sh \ No newline at end of file diff --git a/ci/ubuntu.meson.sanitizers.sh b/ci/ubuntu.meson.sanitizers.sh new file mode 120000 index 0000000..95e8d8e --- /dev/null +++ b/ci/ubuntu.meson.sanitizers.sh @@ -0,0 +1 @@ +debian.meson.sanitizers.sh \ No newline at end of file diff --git a/ci/ubuntu.meson.sh b/ci/ubuntu.meson.sh new file mode 120000 index 0000000..bf14e8a --- /dev/null +++ b/ci/ubuntu.meson.sh @@ -0,0 +1 @@ +debian.meson.sh \ No newline at end of file diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 0000000..585f1ba --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,4 @@ +install_man('neard.8', 'neard.conf.5') +if opt_tools + install_man('nfctool.1') +endif \ No newline at end of file diff --git a/gdbus/meson.build b/gdbus/meson.build new file mode 100644 index 0000000..a632057 --- /dev/null +++ b/gdbus/meson.build @@ -0,0 +1,9 @@ +gdbus_inc = include_directories('.') + +gdbus_sources = files( + 'mainloop.c', + 'watch.c', + 'object.c', + 'client.c', + 'polkit.c', +) diff --git a/include/meson.build b/include/meson.build new file mode 100644 index 0000000..bf41280 --- /dev/null +++ b/include/meson.build @@ -0,0 +1,31 @@ +include_files = files( + 'adapter.h', + 'dbus.h', + 'device.h', + 'log.h', + 'ndef.h', + 'nfc_copy.h', + 'plugin.h', + 'setting.h', + 'snep.h', + 'tag.h', + 'tlv.h', + 'types.h', +) + +version_h_in = files('version.h.in') + +install_headers( + 'adapter.h', + 'device.h', + 'log.h', + 'ndef.h', + 'nfc_copy.h', + 'plugin.h', + 'setting.h', + 'snep.h', + 'tag.h', + 'tlv.h', + 'types.h', + subdir : 'near', +) diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..1055974 --- /dev/null +++ b/meson.build @@ -0,0 +1,112 @@ +project('neard', 'c', + version : '0.20', + license : 'GPL-2.0-only', + meson_version : '>= 1.1', + default_options : ['warning_level=1'], +) + +cc = meson.get_compiler('c') +pkgconfig = import('pkgconfig') + +prefix = get_option('prefix') +libexecdir = prefix / get_option('libexecdir') +pkglibexecdir = libexecdir / 'nfc' +libdir = prefix / get_option('libdir') +pkglibdir = libdir / meson.project_name() +plugindir = pkglibdir / 'plugins' +sysconfdir = get_option('sysconfdir') +configdir = sysconfdir / 'neard' +includedir = prefix / get_option('includedir') + +opt_nfctypes = get_option('nfctypes') +opt_p2p = get_option('p2p') +opt_ese = get_option('ese') +opt_systemd = get_option('systemd') +opt_tools = get_option('tools') +opt_test_scripts = get_option('test') + +glib_dep = dependency('glib-2.0', version : '>= 2.28') +dbus_dep = dependency('dbus-1', version : '>= 1.2') +dl_dep = cc.find_library('dl') +systemd_dep = dependency('systemd', required : opt_systemd) + +# Netlink: prefer libnl-3.0, fall back to libnl-2.0, then libnl-1 +libnl3_dep = dependency('libnl-3.0', required : false) +libnl_genl3_dep = dependency('libnl-genl-3.0', required : false) +if libnl3_dep.found() and libnl_genl3_dep.found() + netlink_dep = [libnl3_dep, libnl_genl3_dep] + netlink_deps_str = 'libnl-3.0 libnl-genl-3.0' + need_libnl_compat = false +else + libnl2_dep = dependency('libnl-2.0', required : false) + if libnl2_dep.found() + netlink_dep = [libnl2_dep] + netlink_deps_str = 'libnl-2.0' + need_libnl_compat = false + else + libnl1_dep = dependency('libnl-1', required : true) + netlink_dep = [libnl1_dep] + netlink_deps_str = 'libnl-1' + need_libnl_compat = true + endif +endif + +conf = configuration_data() +conf.set_quoted('VERSION', meson.project_version()) +conf.set_quoted('PACKAGE', meson.project_name()) +conf.set_quoted('PACKAGE_VERSION', meson.project_version()) +if need_libnl_compat + conf.set('NEED_LIBNL_COMPAT', 1) +endif +config_h = configure_file(output : 'config.h', configuration : conf) +config_dep = declare_dependency( + include_directories: include_directories(), + sources: config_h, + compile_args: ['-DHAVE_CONFIG_H'], +) + +top_inc = include_directories('.') + +subdir('include') +subdir('gdbus') + +builtin_modules = opt_nfctypes +builtin_sources = [] + +sources_per_type = { + 'nfctype1': files('plugins/nfctype1.c'), + 'nfctype2': files('plugins/nfctype2.c', 'plugins/mifare.c'), + 'nfctype3': files('plugins/nfctype3.c'), + 'nfctype4': files('plugins/nfctype4.c'), + 'nfctype5': files('plugins/nfctype5.c'), +} + +foreach nfctype : opt_nfctypes + builtin_sources += sources_per_type[nfctype] +endforeach + +if opt_p2p + builtin_modules += ['p2p'] + builtin_sources += files( + 'plugins/p2p.c', + 'plugins/npp.c', + 'plugins/snep.c', + 'plugins/snep-validation.c', + 'plugins/llcp-validation.c', + 'plugins/handover.c', + 'plugins/phdc.c', + ) +endif + +subdir('src') +subdir('doc') +subdir('unit') +if opt_tools + subdir('tools') +endif +if opt_test_scripts + subdir('test') +endif +if opt_ese + subdir('se') +endif diff --git a/meson.options b/meson.options new file mode 100644 index 0000000..78e6eaa --- /dev/null +++ b/meson.options @@ -0,0 +1,19 @@ +option('nfctypes', type : 'array', + choices : ['nfctype1', 'nfctype2', 'nfctype3', 'nfctype4', 'nfctype5'], + value : ['nfctype1', 'nfctype2', 'nfctype3', 'nfctype4', 'nfctype5'], + description: 'Enable NFC Forum Type 1, 2, 3, 4 or 5 tag support') + +option('p2p', type: 'boolean', value: true, + description: 'Enable NFC peer-to-peer support') + +option('ese', type: 'boolean', value: false, + description: 'Enable embedded Secure Element support') + +option('systemd', type: 'feature', value: 'auto', + description: 'Install systemd service file') + +option('tools', type: 'boolean', value: false, + description: 'Build testing tools (nfctool, nciattach)') + +option('test', type: 'boolean', value: false, + description: 'Install test/example scripts') diff --git a/se/meson.build b/se/meson.build new file mode 100644 index 0000000..91cb095 --- /dev/null +++ b/se/meson.build @@ -0,0 +1,54 @@ +# seeld - Secure Element daemon + +seeld_builtin_h = configure_file( + output : 'builtin.h', + command : [genbuiltin, 'nfc'], + capture : true, +) + +se_inc = include_directories('.') + +seeld_c_args = [ + '-DNEAR_PLUGIN_BUILTIN', + '-DPLUGINDIR="' + (prefix / get_option('libdir') / meson.project_name() / 'plugins-se') + '"', + '-DCONFIGDIR="' + configdir + '"', +] + +executable('seeld', + 'ace.c', + 'apdu.c', + 'channel.c', + 'driver.c', + 'main.c', + 'manager.c', + 'plugins/nfc.c', + 'se.c', + '../src/dbus.c', + '../src/error.c', + '../src/log.c', + '../src/plugin.c', + gdbus_sources, + seeld_builtin_h, + c_args : seeld_c_args, + include_directories : [se_inc, top_inc, src_inc, gdbus_inc], + dependencies : [glib_dep, dbus_dep, netlink_dep, dl_dep, config_dep], + link_args : ['-Wl,--export-dynamic'], + install : true, + install_dir : pkglibexecdir, +) + +install_data( + 'org.neard.se.conf', + install_dir : get_option('sysconfdir') / 'dbus-1' / 'system.d', +) + +pkgconfig.generate( + name : 'seeld', + description : 'Secure Element daemon', + version : meson.project_version(), + requires : [glib_dep, dbus_dep], + libraries : ['-module', '-avoid-version', '-export-symbols-regex', 'seeld_plugin_desc'], + variables : { + 'plugindir' : '${libdir}/seeld/plugins', + }, +) diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 0000000..f28b00c --- /dev/null +++ b/src/meson.build @@ -0,0 +1,85 @@ +subdir('near') + +src_inc = include_directories('.') + +genbuiltin = find_program('genbuiltin') +builtin_h = configure_file( + output : 'builtin.h', + command : [genbuiltin] + builtin_modules, + capture : true, +) + +neard_c_args = [ + '-DNEAR_PLUGIN_BUILTIN', + '-DPLUGINDIR="@0@"'.format(plugindir), + '-DCONFIGDIR="@0@"'.format(configdir), +] + +neard_deps = [ + glib_dep, + dbus_dep, + netlink_dep, + dl_dep, + config_dep, +] + +neard = executable('neard', + 'adapter.c', + 'agent.c', + 'bluetooth.c', + 'dbus.c', + 'device.c', + 'error.c', + 'log.c', + 'main.c', + 'manager.c', + 'ndef.c', + 'netlink.c', + 'plugin.c', + 'snep.c', + 'tag.c', + 'tlv.c', + builtin_h, + builtin_sources, + config_h, + gdbus_sources, + c_args : neard_c_args, + include_directories : [top_inc, gdbus_inc], + dependencies : neard_deps, + install : true, + install_dir : pkglibexecdir, +) + +pkgconfig.generate( + name : 'neard', + description : 'NFC daemon', + version : meson.project_version(), + requires : [glib_dep, dbus_dep, netlink_dep], + libraries : ['-module', '-avoid-version', '-export-symbols-regex', 'neard_plugin_desc'], + variables : { + 'pkglibdir' : '${libdir}/' + meson.project_name(), + 'plugindir' : '${libdir}/' + meson.project_name() + '/plugins', + }, +) + +if systemd_dep.found() + systemd_unitdir = systemd_dep.get_variable('systemdsystemunitdir') + service_conf = configuration_data() + service_conf.set('pkglibexecdir', pkglibexecdir) + service_file = configure_file( + input : 'neard.service.in', + output : 'neard.service', + configuration : service_conf, + ) + install_data(service_file, install_dir : systemd_unitdir) +endif + +install_data( + 'org.neard.conf', + install_dir : sysconfdir / 'dbus-1' / 'system.d', +) + +install_data( + 'main.conf', + install_dir : configdir, +) diff --git a/src/near/meson.build b/src/near/meson.build new file mode 100644 index 0000000..91fd81a --- /dev/null +++ b/src/near/meson.build @@ -0,0 +1,25 @@ +# Generate near/ headers in the build directory so that +# "#include " resolves at compile time. +# include_directories('src') in the root meson.build adds both +# /src and /src to the compiler search path, +# so files generated here (/src/near/*.h) are found as +# . + +foreach file : include_files + configure_file( + input : file, + output : '@PLAINNAME@', + copy : true, + ) +endforeach + +version_conf = configuration_data() +version_conf.set('VERSION', meson.project_version()) + +version_h = configure_file( + input : version_h_in, + output : '@BASENAME@', + configuration : version_conf, + install : true, + install_dir : get_option('includedir') / 'near', +) diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000..9b94141 --- /dev/null +++ b/test/meson.build @@ -0,0 +1,11 @@ +install_data( + 'bt-handover', + 'handover-agent', + 'monitor-near', + 'neardutils.py', + 'phdc-simple-manager', + 'test-adapter', + 'test-device', + 'test-tag', + install_dir : pkglibdir / 'test', +) diff --git a/tools/meson.build b/tools/meson.build new file mode 100644 index 0000000..7182c38 --- /dev/null +++ b/tools/meson.build @@ -0,0 +1,37 @@ +tool_c_args = [ + '-DNEAR_PLUGIN_BUILTIN', + '-DPLUGINDIR="@0@"'.format(plugindir), + '-DCONFIGDIR="@0@"'.format(configdir), +] + +# nciattach: only needs C stdlib at link time; glib/dbus headers are pulled +# in transitively through src/near.h but no glib/dbus symbols are used. +nciattach_deps = [] +foreach dep : [glib_dep, dbus_dep] + netlink_dep + nciattach_deps += dep.partial_dependency(compile_args : true, link_args : false) +endforeach + +executable('nciattach', + 'nciattach.c', + c_args : tool_c_args, + include_directories : [top_inc, src_inc], + dependencies : [nciattach_deps, config_dep], + install : true, +) + +# snep-send: internal test tool, not installed +executable('snep-send', + 'snep-send.c', + '../src/agent.c', + '../src/bluetooth.c', + '../src/dbus.c', + '../src/error.c', + '../src/log.c', + '../src/ndef.c', + gdbus_sources, + c_args : ['-DCONFIGDIR="@0@"'.format(configdir)], + include_directories : [top_inc, gdbus_inc, src_inc], + dependencies : [glib_dep, dbus_dep, config_dep], +) + +subdir('nfctool') diff --git a/tools/nfctool/meson.build b/tools/nfctool/meson.build new file mode 100644 index 0000000..7ead772 --- /dev/null +++ b/tools/nfctool/meson.build @@ -0,0 +1,14 @@ +executable('nfctool', + 'adapter.c', + 'display.c', + 'llcp-decode.c', + 'main.c', + 'ndef-decode.c', + 'netlink.c', + 'snep-decode.c', + 'sniffer.c', + c_args : tool_c_args, + include_directories : [top_inc, src_inc], + dependencies : [glib_dep, netlink_dep, config_dep], + install : true, +) diff --git a/unit/meson.build b/unit/meson.build new file mode 100644 index 0000000..d15c8c0 --- /dev/null +++ b/unit/meson.build @@ -0,0 +1,47 @@ +test_base_sources = [ + gdbus_sources, + files( + '../src/log.c', + '../src/dbus.c', + '../src/error.c', + '../src/agent.c', + '../src/bluetooth.c', + '../src/ndef.c', + ), +] + +test_c_args = ['-DCONFIGDIR="@0@"'.format(configdir)] +test_deps = [glib_dep, dbus_dep, config_dep] + +test_ndef_parse = executable('test-ndef-parse', + 'test-ndef-parse.c', + test_base_sources, + c_args : test_c_args, + include_directories : [top_inc, src_inc, gdbus_inc], + dependencies : test_deps, + build_by_default : false, +) + +test_ndef_build = executable('test-ndef-build', + 'test-ndef-build.c', + test_base_sources, + c_args : test_c_args, + include_directories : [top_inc, src_inc, gdbus_inc], + dependencies : test_deps, + build_by_default : false, +) + +test_snep_read = executable('test-snep-read', + 'test-snep-read.c', + 'test-utils.c', + '../src/snep.c', + test_base_sources, + c_args : test_c_args, + include_directories : [top_inc, src_inc, gdbus_inc], + dependencies : test_deps, + build_by_default : false, +) + +test('test-ndef-parse', test_ndef_parse) +test('test-ndef-build', test_ndef_build) +test('test-snep-read', test_snep_read)