內省建置步驟#

當您在特定的 Python 擴充模組或其他建置目標遇到問題時,有很多方法可以確切了解建置系統正在做什麼。除了查看感興趣目標的 meson.build 內容之外,這些方法還包括

  1. 閱讀建置目錄中產生的 build.ninja 檔案,

  2. 使用 meson introspect 來了解更多關於目標的建置選項、相依性和標誌的資訊,

  3. 閱讀 <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 命令搜尋它們。