内省构建步骤#
当你对特定的Python扩展模块或其他构建目标有疑问时,有多种方法可以弄清楚构建系统到底在做什么。除了查看感兴趣目标的``meson.build``内容外,还包括:
阅读生成在构建目录中的
build.ninja
文件,使用
meson introspect
来了解更多关于构建选项、依赖关系和用于目标的标志的信息,阅读
<build-dir>/meson-info/*.json
以获取有关已发现的依赖项、Meson计划安装文件的位置等的详细信息。
这些内容在构建的配置阶段(即 meson setup
)运行后都可以获取。通常,查看这些信息比运行构建并阅读完整的构建日志更为有效。
ninja.build
文件#
作为一个例子,假设我们对 scipy.linalg._decomp_update
感兴趣。从 scipy/linalg/meson.build
中我们了解到这个扩展是用模板化的 Cython 代码编写的,并且没有使用特殊的编译标志,也没有超出 numpy
的包含目录。所以下一步是查看 build.ninja
。在编辑器中打开该文件并搜索 _decomp_update
。你将找到这一组通用的和目标特定的规则(注意,此代码块中的注释在 build.ninja
中不存在,仅在此文档部分添加以解释正在发生的事情):
# These rules are usually not needed to understand the problem, but can be looked up at the top of the file:
rule c_COMPILER
command = /home/username/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc $ARGS -MD -MQ $out -MF $DEPFILE -o $out -c $in
deps = gcc
depfile = $DEPFILE_UNQUOTED
description = Compiling C object $out
rule c_LINKER
command = /home/username/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc $ARGS -o $out $in $LINK_ARGS
description = Linking target $out
# step 1: `.pyx.in` to `.pyx` code generation with Tempita
build scipy/linalg/_decomp_update.pyx: CUSTOM_COMMAND ../scipy/linalg/_decomp_update.pyx.in | ../scipy/_build_utils/tempita.py /home/username/anaconda3/envs/scipy-dev/bin/python3.10
COMMAND = /home/username/anaconda3/envs/scipy-dev/bin/python3.10 ../scipy/_build_utils/tempita.py ../scipy/linalg/_decomp_update.pyx.in -o scipy/linalg
description = Generating$ scipy/linalg/_decomp_update$ with$ a$ custom$ command
# step 2: `.pyx` to `.c` compilation with Cython
build scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.c: CUSTOM_COMMAND scipy/linalg/_decomp_update.pyx | /home/username/code/scipy/scipy/_build_utils/cythoner.py scipy/__init__.py scipy/linalg/__init__.py scipy/linalg/cython_blas.pyx
DESC = Generating$ 'scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.c'.
COMMAND = /home/username/anaconda3/envs/scipy-dev/bin/python3.10 /home/username/code/scipy/scipy/_build_utils/cythoner.py scipy/linalg/_decomp_update.pyx scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.c
# step 3: use C compiler to go from `.c` to object file (`.o`)
build scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/meson-generated__decomp_update.c.o: c_COMPILER scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.c
DEPFILE = scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/meson-generated__decomp_update.c.o.d
DEPFILE_UNQUOTED = scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/meson-generated__decomp_update.c.o.d
ARGS = -Iscipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p -Iscipy/linalg -I../scipy/linalg -I/home/username/anaconda3/envs/scipy-dev/lib/python3.10/site-packages/numpy/core/include -I/home/username/anaconda3/envs/scipy-dev/include/python3.10 -fvisibility=hidden -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c99 -O2 -g -Wno-unused-but-set-variable -Wno-unused-function -Wno-conversion -Wno-misleading-indentation -fPIC -Wno-cpp
# step 4: generate a symbol file (uses `meson --internal symbolextractor`); you can safely ignore this step
build scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.cpython-310-x86_64-linux-gnu.so.symbols: SHSYM scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so
IMPLIB = scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so
# step 5: link the `.o` file to obtain the file extension module (`.so`)
build scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so: c_LINKER scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/meson-generated__decomp_update.c.o | /home/username/anaconda3/envs/scipy-dev/x86_64-conda-linux-gnu/sysroot/lib64/libm-2.12.so /home/username/anaconda3/envs/scipy-dev/x86_64-conda-linux-gnu/sysroot/usr/lib64/libm.a
LINK_ARGS = -L/home/username/anaconda3/envs/scipy-dev/lib -Wl,--as-needed -Wl,--allow-shlib-undefined -shared -fPIC -Wl,--start-group -lm -Wl,--end-group -Wl,-O2 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,--disable-new-dtags -Wl,--gc-sections -Wl,--allow-shlib-undefined -Wl,-rpath,/home/username/anaconda3/envs/scipy-dev/lib -Wl,-rpath-link,/home/username/anaconda3/envs/scipy-dev/lib
使用 meson introspect
#
如果我们想从另一个角度来看 _decomp_update
,我们可以使用(例如) meson introspect --targets -i <build-dir> > targets.json
来生成可读的 JSON。在生成的文件中搜索我们感兴趣的目标显示:
{
"name": "_decomp_update",
"id": "b4ac6f0@@_decomp_update@cus",
"type": "custom",
"defined_in": "/home/username/code/scipy/scipy/linalg/meson.build",
"filename": [
"/home/username/code/scipy/build/scipy/linalg/_decomp_update.pyx"
],
"build_by_default": false,
"target_sources": [
{
"language": "unknown",
"compiler": [
"/home/username/anaconda3/envs/scipy-dev/bin/python3.10",
"/home/username/code/scipy/scipy/_build_utils/tempita.py",
"@INPUT@",
"-o",
"@OUTDIR@"
],
"parameters": [],
"sources": [
"/home/username/code/scipy/scipy/linalg/_decomp_update.pyx.in"
],
"generated_sources": []
}
],
"extra_files": [],
"subproject": null,
"installed": false
},
{
"name": "_decomp_update.cpython-310-x86_64-linux-gnu",
"id": "b4ac6f0@@_decomp_update.cpython-310-x86_64-linux-gnu@sha",
"type": "shared module",
"defined_in": "/home/username/code/scipy/scipy/linalg/meson.build",
"filename": [
"/home/username/code/scipy/build/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so"
],
"build_by_default": true,
"target_sources": [
{
"language": "c",
"compiler": [
"/home/username/anaconda3/envs/scipy-dev/bin/x86_64-conda-linux-gnu-cc"
],
"parameters": [
"-I/home/username/code/scipy/build/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p",
"-I/home/username/code/scipy/build/scipy/linalg",
"-I/home/username/code/scipy/scipy/linalg",
"-I/home/username/anaconda3/envs/scipy-dev/lib/python3.10/site-packages/numpy/core/include",
"-I/home/username/anaconda3/envs/scipy-dev/include/python3.10",
"-fvisibility=hidden",
"-fdiagnostics-color=always",
"-D_FILE_OFFSET_BITS=64",
"-Wall",
"-Winvalid-pch",
"-std=c99",
"-O2",
"-g",
"-Wno-unused-but-set-variable",
"-Wno-unused-function",
"-Wno-conversion",
"-Wno-misleading-indentation",
"-fPIC",
"-Wno-cpp"
],
"sources": [],
"generated_sources": [
"/home/username/code/scipy/build/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so.p/_decomp_update.c"
]
}
],
"extra_files": [],
"subproject": null,
"installed": true,
"install_filename": [
"/home/username/code/scipy/build-install/lib/python3.10/site-packages/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so"
]
},
这告诉我们很多信息,比如将使用哪些包含目录,在哪里可以找到Cython生成的C代码,以及使用了哪些编译标志。meson introspect --help
提供了关于全部功能及其使用方法的良好文档。
meson-info
JSON 文件#
在 <build-dir>/meson-info/
中有许多不同的 JSON 文件。这些文件的名称具有描述性,暗示了它们的内容。例如,最终的 _decomp_update
扩展安装位置在 intro-install_plan.json
中描述(注意,这些文件不是预先格式化的,通过 JSON 格式化工具运行它们会有所帮助):
"/home/username/code/scipy/build/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so":{
"destination":"{py_platlib}/scipy/linalg/_decomp_update.cpython-310-x86_64-linux-gnu.so",
"tag":"runtime"
},
我们可能还对了解构建的配置阶段检测到了哪些依赖项感兴趣。因此,我们查看 intro-dependencies.json
:
[
{
"name":"python",
"version":"3.10",
"compile_args":[
"-I/home/username/anaconda3/envs/scipy-dev/include/python3.10"
],
"link_args":[
]
},
{
"name":"openblas",
"version":"0.3.20",
"compile_args":[
"-I/home/username/anaconda3/envs/scipy-dev/include"
],
"link_args":[
"/home/username/anaconda3/envs/scipy-dev/lib/libopenblas.so"
]
},
{
"name":"threads",
"version":"unknown",
"compile_args":[
"-pthread"
],
"link_args":[
"-pthread"
]
}
]
这告诉我们找到了三个依赖项。注意:numpy
和一些其他构建时依赖项在这里缺失,因为我们没有(还)使用内置的 dependency()
Meson 命令搜索这些依赖项。