如何获取Meson依赖项的库文件完整路径?
如何从Meson依赖对象中提取库文件的完整路径?
我之前也碰到过一模一样的问题,当依赖通过wrap子项目回退构建时,运行时找不到库确实头疼。下面给你几个可行的解决办法,对应你代码里??????的位置:
先回顾下问题场景
你的项目目录结构是这样的:
./ ./subprojects/ ./subprojects/mylib.wrap
src/meson.build里的依赖逻辑是先找系统的mylib,找不到就用wrap子项目:
mylib_dep = dependency('mylib') # 优先pkg-config查找,失败则回退到wrap myexec_exe = executable ('myexec', 'myexec.c', dependencies : mylib_dep)
现在要在测试脚本里通过设置LD_LIBRARY_PATH来解决运行时库找不到的问题,需要从mylib_dep里拿到库的完整路径。
解决方案1:直接用get_variable()取路径(简单直接)
Meson的依赖对象提供了get_variable()方法,可以直接读取依赖的配置变量,比如libdir(库的安装目录),然后拼接上库文件名就行:
conf_data = configuration_data () conf_data.set_quoted ('MYEXEC_PATH', myexec_exe.full_path ()) # 拼接库文件的完整路径 conf_data.set_quoted ('MYLIB_PATH', mylib_dep.get_variable('libdir') / 'libmylib.so') mytest_exe = configure_file (input : 'mytests.sh.in', output : 'mytests.sh', configuration : conf_data)
⚠️ 注意:这里需要你明确知道库的文件名(比如libmylib.so),如果要跨平台,可以用Meson的内置变量来自动适配后缀:
lib_suffix = meson.get_compiler('c').get_suffix('sharedlibrary') conf_data.set_quoted ('MYLIB_PATH', mylib_dep.get_variable('libdir') / 'libmylib@0@'.format(lib_suffix))
解决方案2:从链接参数中自动提取(更通用)
如果你不想硬编码库文件名,可以从依赖的链接参数里自动提取。依赖对象的link_args()会返回所有链接时用到的参数,我们可以过滤出库的路径:
conf_data = configuration_data () conf_data.set_quoted ('MYEXEC_PATH', myexec_exe.full_path ()) # 从依赖的链接参数中提取库路径 lib_path = '' foreach arg : mylib_dep.link_args() # 处理-lmylib这种形式的链接参数 if arg.startswith('-l') lib_name = arg.split('-l')[1] lib_suffix = meson.get_compiler('c').get_suffix('sharedlibrary') lib_path = mylib_dep.get_variable('libdir') / 'lib@0@@1@'.format(lib_name, lib_suffix) break # 处理直接给出的库文件路径(比如/usr/lib/libmylib.so) elif arg.endswith(meson.get_compiler('c').get_suffix('sharedlibrary')) lib_path = arg break endif endforeach conf_data.set_quoted ('MYLIB_PATH', lib_path) mytest_exe = configure_file (input : 'mytests.sh.in', output : 'mytests.sh', configuration : conf_data)
这个方法不管是系统安装的依赖还是wrap子项目的依赖都能适配,通用性更强。
解决方案3:直接获取子项目的库目标(针对wrap场景)
如果你的mylib确定是通过wrap作为子项目引入的,还可以直接获取子项目的库目标,然后取它的完整路径:
conf_data = configuration_data () conf_data.set_quoted ('MYEXEC_PATH', myexec_exe.full_path ()) # 获取子项目的库对象 mylib_subproj = subproject('mylib') mylib_lib = mylib_subproj.get_variable('mylib_dep').get_variable('libraries')[0] # 获取库文件的完整路径 conf_data.set_quoted ('MYLIB_PATH', mylib_lib.full_path()) mytest_exe = configure_file (input : 'mytests.sh.in', output : 'mytests.sh', configuration : conf_data)
这个方法的前提是子项目的meson.build里正确暴露了库变量(比如把库目标赋值给了mylib_dep)。
额外小提示
- 如果依赖可能是静态库,记得先判断类型,静态库不需要设置
LD_LIBRARY_PATH:if mylib_dep.type() == 'shared' # 这里才设置MYLIB_PATH和LD_LIBRARY_PATH endif - macOS下对应的环境变量是
DYLD_LIBRARY_PATH,Windows是PATH,可以结合host_system来判断设置对应的变量。
内容的提问来源于stack exchange,提问作者Michaël
相关产品推荐
相关产品推荐

