You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不编译systemd交叉编译libudev?Meson构建遇阻求助

问题描述

我正在为MilkV Duo交叉编译avrdude用于给ATtiny烧录程序。现有Buildroot只提供musl编译器,但avrdude依赖glibc,所以我自行交叉编译了很多依赖,熟悉cmake和autotools,但卡在了用Meson构建hidapi的libudev依赖环节。

我想不编译整个systemd单独构建libudev,尝试直接在systemd源码的src/libudev/目录下构建,但Meson配置依赖整个systemd的构建流程,而且systemd本身不支持musl构建。我已经配好交叉编译工具链,Meson能识别交叉环境,但修改meson.build后遇到未定义的includes、userspace等变量,找不到单独交叉编译libudev的指南,libudev也没有单独源码包,现在卡壳了。

当前修改后的src/libudev/meson.build如下:

# SPDX-License-Identifier: LGPL-2.1-or-later
project('libudev', 'cpp', 'c')
libudev_sources = files(
        'libudev-device.c',
        'libudev-enumerate.c',
        'libudev-hwdb.c',
        'libudev-list.c',
        'libudev-monitor.c',
        'libudev-queue.c',
        'libudev-util.c',
        'libudev.c',
)

############################################################

libudev_includes = [includes, include_directories('.')]

libudev_dir_path = meson.current_source_dir()

libudev_sym = files('libudev.sym')
libudev_sym_path = libudev_dir_path / 'libudev.sym'

install_headers('libudev.h')
libudev_h_path = libudev_dir_path / 'libudev.h'

libudev_basic = static_library(
        'udev-basic',
        libudev_sources,
        include_directories : includes,
        dependencies : userspace,
        c_args : ['-fvisibility=default'],
        build_by_default : false)

static_libudev = get_option('static-libudev')
static_libudev_pic = static_libudev == 'true' or static_libudev == 'pic'

libudev_pc = custom_target(
        'libudev.pc',
        input : 'libudev.pc.in',
        output : 'libudev.pc',
        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
        install : pkgconfiglibdir != 'no',
        install_tag : 'devel',
        install_dir : pkgconfiglibdir)  

执行meson setup --cross-file riscv64-toolchain-file的报错:

The Meson build system
Version: 1.3.1
Source dir: /home/tmoney/Development/AtTiny/riscv-build/systemd/src/libudev
Build dir: /home/tmoney/Development/AtTiny/riscv-build/systemd/src/libudev/build
Build type: cross build
Project name: libudev
Project version: undefined
C compiler for the host machine: riscv64-unknown-linux-musl-gcc (gcc 10.2.0 "riscv64-unknown-linux-musl-gcc (Xuantie-900 linux-5.10.4 musl gcc Toolchain V2.6.1 B-20220906) 10.2.0")
C linker for the host machine: riscv64-unknown-linux-musl-gcc ld.bfd 2.35
C++ compiler for the host machine: riscv64-unknown-linux-musl-g++ (gcc 10.2.0 "riscv64-unknown-linux-musl-g++ (Xuantie-900 linux-5.10.4 musl gcc Toolchain V2.6.1 B-20220906) 10.2.0")
C++ linker for the host machine: riscv64-unknown-linux-musl-g++ ld.bfd 2.35
C compiler for the build machine: cc (gcc 13.2.0 "cc (Debian 13.2.0-13) 13.2.0")
C linker for the build machine: cc ld.bfd 2.42
C++ compiler for the build machine: c++ (gcc 13.2.0 "c++ (Debian 13.2.0-13) 13.2.0")
C++ linker for the build machine: c++ ld.bfd 2.42
Build machine cpu family: x86_64
Build machine cpu: x86_64
Host machine cpu family: riscv64
Host machine cpu: riscv64
Target machine cpu family: riscv64
Target machine cpu: riscv64

meson.build:16:20: ERROR: Unknown variable "includes".

我的交叉编译工具链文件:

[binaries]
c = 'riscv64-unknown-linux-musl-gcc'
cpp = 'riscv64-unknown-linux-musl-g++'

[properties]
root = '/home/tmoney/Development/Milk.V/Duo/duo-sdk/riscv64-linux-musl-x86_64/sysroot'

[host_machine]
system = 'linux'
cpu_family = 'riscv64'
cpu= 'riscv64'
endian= 'little'

解决方案1:修复Meson配置,补全缺失变量

systemd源码里的src/libudev/meson.build依赖顶层定义的全局变量,单独拿出来用必须手动补全这些变量:

  1. 添加版本信息
    解决Project version: undefined的报错,给project语句加上对应systemd版本号:
project('libudev', 'cpp', 'c', version: '255.4') # 替换为你下载的systemd版本
  1. 定义基础包含目录
    includes是systemd顶层定义的全局包含目录,替换为当前目录和systemd的shared工具函数目录:
# 在project语句后添加
includes = include_directories('.', '../../src/shared') # 根据实际源码路径调整
  1. 替换userspace依赖
    userspace是systemd顶层的依赖集合,libudev实际只依赖基础C库和线程库,直接替换:
# 修改static_library的dependencies项
dependencies : [dependency('c'), dependency('threads')]
  1. 补全模板生成和pkgconfig变量
    手动定义jinja2_cmdline(需主机安装jinja2)和pkgconfiglibdir:
# 在project语句后添加
jinja2_cmdline = ['jinja2']
pkgconfiglibdir = join_paths(get_option('prefix'), 'lib', 'pkgconfig')
  1. 补充动态库构建逻辑
    原代码只定义了静态库,需要添加动态库构建,适配avrdude的依赖需求:
# 在static_library定义后添加
libudev = shared_library(
        'udev',
        libudev_sources,
        include_directories : includes,
        dependencies : [dependency('c'), dependency('threads')],
        c_args : ['-fvisibility=default'],
        link_args : ['-Wl,--version-script=' + libudev_sym_path],
        install : true
)

修改后的完整meson.build可直接用于构建,执行以下命令完成交叉编译:

meson setup --cross-file riscv64-toolchain-file build --prefix=$PREFIX
ninja -C build install

解决方案2:改用eudev替代systemd的libudev

如果不想折腾systemd的Meson依赖,推荐用eudev——这是独立于systemd的udev实现,原生支持musl,用autotools构建,流程更简单:

  1. 下载并编译eudev
git clone https://github.com/eudev-project/eudev.git
cd eudev
./autogen.sh
./configure --host=riscv64-unknown-linux-musl --prefix=$PREFIX --disable-introspection --disable-gudev --disable-systemd
make -j$(nproc)
make install
  1. 验证安装
    安装完成后,$PREFIX/lib下会生成libudev.so,$PREFIX/lib/pkgconfig下会生成libudev.pc,直接供hidapi和avrdude交叉编译使用。

注意事项

  • 方案1需确保systemd源码的src/shared目录路径正确,libudev依赖该目录下的工具函数头文件;
  • 可在交叉工具链文件中添加pkgconfig路径,方便Meson识别已交叉编译的依赖:
    [properties]
    pkg_config_path = '/home/tmoney/Development/AtTiny/riscv-build/prefix/lib/pkgconfig'
    
  • avrdude对libudev的需求仅为基础设备枚举,eudev完全满足需求,且构建流程更简洁,优先推荐。

内容的提问来源于stack exchange,提问作者Taspen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 00:36:02