如何在 Meson 中執行 X?
此頁面列出常用任務的程式碼片段。這些程式碼片段主要使用 C 編譯器編寫,但相同的方法應適用於幾乎所有其他編譯器。
設定編譯器
首次執行 Meson 時,請在環境變數中設定它。
$ CC=mycc meson <options>
請注意,像 CC
這樣的環境變數僅在交叉編譯中參照主機平台。也就是說,CC
參照用於編譯將在我們最終安裝專案的機器上執行的程式之編譯器。用於建置在我們進行建置的機器上執行的程式之編譯器可以使用 CC_FOR_BUILD
指定。您可以在交叉編譯中使用它。
請注意,環境變數絕不是使用 Meson 執行任何操作的慣用方式。最好使用原生和交叉檔案。而且,只能使用交叉檔案指定交叉編譯中主機平台的工具。
這裡有一個支援的所有環境變數表:這裡
設定連結器
0.53.0 版新增功能
與編譯器類似,連結器是透過 <compiler variable>_LD
環境變數選取的,或是透過原生或交叉檔案中的 <compiler entry>_ld
項目選取的。您必須知道您使用的是會自行叫用連結器的編譯器(大多數編譯器,包括 GCC 和 Clang),還是直接叫用的連結器(當使用 MSVC 或像它的編譯器時,包括 Clang-Cl)。前者 c_ld
或 CC_LD
應該是要傳遞給編譯器特殊引數的值(例如 clang 和 gcc 的 -fuse-ld
),後者應該是可執行檔,例如 lld-link.exe
。
注意 在 Meson 0.53.0 中,使用了交叉/原生檔案中的 ld
項目和 LD
環境變數,這導致了大量的回歸,並在 0.53.1 中變更為 <lang>_ld
和 <comp variable>_LD
。
$ CC=clang CC_LD=lld meson <options>
或
$ CC=clang-cl CC_LD=link meson <options>
或在交叉或原生檔案中
[binaries]
c = 'clang'
c_ld = 'lld'
這裡有一個支援的所有環境變數表:這裡
設定預設 C/C++ 語言版本
project('myproj', 'c', 'cpp',
default_options : ['c_std=c11', 'cpp_std=c++11'])
語言版本也可以在每個目標的基礎上設定。
executable(..., override_options : ['c_std=c11'])
啟用執行緒
很多人似乎使用 cc.find_library('pthread')
或類似的東西來手動執行此操作。請勿這麼做。它不具可攜性。請改為執行此操作。
thread_dep = dependency('threads')
executable(..., dependencies : thread_dep)
從外部設定額外的編譯器和連結器標誌(例如,在建置發行套件時)
其行為與其他建置系統相同,在第一次叫用時使用環境變數。當您需要重建原始碼時,請勿使用這些變數
$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options>
僅對特定編譯器使用引數
首先檢查要使用哪些引數。
if meson.get_compiler('c').get_id() == 'clang'
extra_args = ['-fclang-flag']
else
extra_args = []
endif
然後在目標中使用它。
executable(..., c_args : extra_args)
如果您想在所有目標上使用這些引數,請執行此操作。
if meson.get_compiler('c').get_id() == 'clang'
add_global_arguments('-fclang-flag', language : 'c')
endif
將命令的輸出設定為組態設定
txt = run_command('script', 'argument', check: true).stdout().strip()
cdata = configuration_data()
cdata.set('SOMETHING', txt)
configure_file(...)
從檔案產生組態設定資料
fs 模組 提供 read
函式,可讓您將任意檔案的內容新增至組態設定資料(以及其他用途)
fs = import('fs')
cdata = configuration_data()
copyright = fs.read('LICENSE')
cdata.set('COPYRIGHT', copyright)
if build_machine.system() == 'linux'
os_release = fs.read('/etc/os-release')
cdata.set('LINUX_BUILDER', os_release)
endif
configure_file(...)
使用 configure_file
產生可執行的腳本
configure_file
會保留中繼資料,因此如果您的範本檔案具有執行權限,則產生的檔案也會具有這些權限。
產生涵蓋率報告
首先使用此命令初始化建置目錄。
$ meson setup <other flags> -Db_coverage=true
然後發出下列命令。
$ meson compile
$ meson test
$ ninja coverage-html (or coverage-xml)
涵蓋率報告可以在 meson-logs 子目錄中找到。
0.55.0 版新增功能 llvm-cov 支援與 clang 搭配使用
為偵錯組建新增一些最佳化
預設情況下,偵錯組建不會使用任何最佳化。這是大多數情況下所需的做法。但是,有些專案受益於啟用一些次要最佳化。GCC 甚至有一個特定的編譯器標誌 -Og
來執行此操作。若要啟用其使用,只需發出下列命令。
$ meson configure -Dc_args=-Og
這會導致所有後續組建使用此命令列引數。
使用位址清理工具
Clang 和 gcc 隨附了一系列分析工具,例如 位址清理工具。Meson 使用 b_sanitize
選項對這些工具提供原生支援。
$ meson setup <other options> -Db_sanitize=address
在此之後,您只需編譯程式碼並執行測試套件。位址清理工具將中止有錯誤的可執行檔,因此它們會顯示為測試失敗。
使用 Clang 靜態分析工具
安裝 scan-build 程式,然後執行此操作
$ meson setup builddir
$ ninja -C builddir scan-build
您可以使用 SCANBUILD
環境變數來選擇 scan-build 可執行檔。
$ SCANBUILD=<your exe> ninja -C builddir scan-build
您可以使用它來將引數傳遞給 scan-build 程式,方法是建立一個腳本,例如
#!/bin/sh
scan-build -v --status-bugs "$@"
然後透過變數傳遞它(記得使用絕對路徑)
$ SCANBUILD=$(pwd)/my-scan-build.sh ninja -C builddir scan-build
使用設定檔引導最佳化
使用 GCC 的設定檔引導最佳化是分為兩個階段的操作。首先,我們使用已啟用的設定檔測量來設定專案並編譯它。
$ meson setup <Meson options, such as --buildtype=debugoptimized> -Db_pgo=generate
$ meson compile -C builddir
然後,我們需要使用一些代表性輸入來執行程式。此步驟取決於您的專案。
完成後,我們會變更編譯器標誌以使用產生的資訊並重建。
$ meson configure -Db_pgo=use
$ meson compile
完成這些步驟後,產生的二進位檔將完全最佳化。
可移植地新增數學程式庫 (-lm
)
有些平台(例如 Linux)具有獨立的數學程式庫。其他平台(幾乎所有其他平台)則沒有。如何指定僅在需要時才使用 m
?
cc = meson.get_compiler('c')
m_dep = cc.find_library('m', required : false)
executable(..., dependencies : m_dep)
將可執行檔安裝到 libexecdir
executable(..., install : true, install_dir : get_option('libexecdir'))
使用現有的 Find<name>.cmake
檔案
如果安裝了 CMake,Meson 可以使用 CMake find_package()
生態系統。若要使用自訂 Find<name>.cmake
尋找依賴性,請將 cmake_module_path
屬性設定為專案中儲存 CMake 腳本的路徑。
在 cmake
子目錄中尋找 FindCmakeOnlyDep.cmake
的範例
cm_dep = dependency('CmakeOnlyDep', cmake_module_path : 'cmake')
cmake_module_path
屬性僅適用於自訂 CMake 腳本。系統範圍的 CMake 腳本會自動找到。
如需詳細資訊,請參閱這裡
取得預設的找不到依賴性?
null_dep = dependency('', required : false)
這可用於您想要預設值,但稍後可能會覆寫它的情況。
# Not needed on Windows!
my_dep = dependency('', required : false)
if host_machine.system() in ['freebsd', 'netbsd', 'openbsd', 'dragonfly']
my_dep = dependency('some dep', required : false)
elif host_machine.system() == 'linux'
my_dep = dependency('some other dep', required : false)
endif
executable(
'myexe',
my_sources,
deps : [my_dep]
)
從整合建置中排除檔案
如果您的專案支援整合建置,您應該修復在將原始碼檔案串連在一起時出現的任何錯誤。不過,有時這是不可行的,例如,如果原始碼檔案是產生的。
在這種情況下,您可以將它們放在個別的靜態程式庫建置目標中,並覆寫整合設定。
generated_files = ...
unityproof_lib = static_library('unityproof', generated_files,
override_options : ['unity=off'])
main_exe = executable('main', main_sources, link_with : unityproof_lib)
若要將靜態程式庫連結到另一個程式庫目標,您可能需要使用 link_whole
而不是 link_with
。
搜尋結果為