如何不编译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依赖顶层定义的全局变量,单独拿出来用必须手动补全这些变量:
- 添加版本信息
解决Project version: undefined的报错,给project语句加上对应systemd版本号:
project('libudev', 'cpp', 'c', version: '255.4') # 替换为你下载的systemd版本
- 定义基础包含目录
includes是systemd顶层定义的全局包含目录,替换为当前目录和systemd的shared工具函数目录:
# 在project语句后添加 includes = include_directories('.', '../../src/shared') # 根据实际源码路径调整
- 替换userspace依赖
userspace是systemd顶层的依赖集合,libudev实际只依赖基础C库和线程库,直接替换:
# 修改static_library的dependencies项 dependencies : [dependency('c'), dependency('threads')]
- 补全模板生成和pkgconfig变量
手动定义jinja2_cmdline(需主机安装jinja2)和pkgconfiglibdir:
# 在project语句后添加 jinja2_cmdline = ['jinja2'] pkgconfiglibdir = join_paths(get_option('prefix'), 'lib', 'pkgconfig')
- 补充动态库构建逻辑
原代码只定义了静态库,需要添加动态库构建,适配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构建,流程更简单:
- 下载并编译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
- 验证安装
安装完成后,$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
相关产品推荐
相关产品推荐

