Всем снова привет. После предыдущих трех сообщений о основных исполняемых файлах, базовом управлении зависимостями и установке ваших двоичных файлов в Meson, сегодня я хочу сосредоточиться на двух вещах, которые до сих пор просто игнорировались: базовый синтаксис языка и команда Meson. линия. Что касается части командной строки, я также покажу, как использовать инструмент тестирования, и кратко расскажу о модульных тестах.
Синтаксис языка
У меня есть сильная тенденция сравнивать язык Meson с языком CMake. Почему? Ну, в основном потому, что, если я сейчас использую Meson, одно из моих самых больших разочарований, безусловно, было из-за языка CMake.
Приход в Meson, убегающий от бесконечных экспериментов с управлением пространством, интерполяцией переменных и совершенно безумными условными операторами, - это находка и одна из главных причин, почему я решил остановиться на Meson.
Итак, как выглядит синтаксис Meson? Что ж, для тех, кто привык к любому «обычному» (как в популярному) языку программирования, Meson не представляет никаких трудностей.
В Meson переменные могут содержать любой тип, но этот тип является сильным. Это означает, что Meson может легко обнаруживать ошибки во время настройки. Самое приблизительное, что вы можете придумать, - это сильный динамический язык программирования, такой как Python.
Вот тизер основных типов данных:
- числа
- булевы
- струны
- массивы
- настраиваемые объекты, возвращаемые Meson
- функции
- методы
- поток управления
- зацикливание
- логические операции
- тернарный оператор
- Комментарии
Я постараюсь быть как можно короче, чтобы объяснить все это с помощью фрагмента кода:
# Comments start with # and last for the rest of the line my_number = 7 # This is a number my_string = 'hello' # This is a string # Ternary operator and booleans cond = true result = cond ? true : false # An array. Can hold any kind of objects arr = ['hello', 1, false] # Add more elements arr += ['bye', true] # You can add a single item without enclosing in array arr += 'world' # add to array # Looping foreach a : arr message(a) # Function call endforecach cpp_compiler = meson.get_compiler('cpp') mylib = cpp_compiler.find_library('somelib', required : false) mylib2 = cpp_compiler.find_library('anotherlib', required : false) # Control flow with logical operation and (or also supported) if mylib.found() and mylib2.found() # Method from object called message('Lib found') endif # Nested arrays and indexing some_data = [['somelib', 'dir1'], ['someotherlib', 'dir2']] foreach sd : some_data cpp_compiler.find_library(sd[0], dirs : sd[1]) endforeach
Думаю, это легко понять любому среднему программисту. Я упомяну только несколько вещей, которые могут быть немного другими или более неожиданными. Условные выражения и циклы заканчиваются на endif и endforeach соответственно. Массивы неизменяемы (при использовании + = концептуально создается новый массив со всем содержимым). Это означает, что этот код
arr1 = [3] arr2 = arr1 arr2 += 5
возвращает arr1 со значением [3] и arr2 со значением [3, 5], а именно, arr1 не добавляет элемент arr2.
У строк есть несколько методов для разделения, объединения, проверки, начинается ли оно, подчеркивания и другие методы, которые очень странно обрабатывать с помощью CMake. Посмотрите на строковый объект в справочнике, если вам нужна дополнительная информация.
Командная строка Meson
Основная командная строка в Meson гибкая и не слишком отличается от командной строки CMake и Autotools.
Meson, как CMake, является генератором системы сборки: он генерирует файлы внутренней системы сборки. Генерация по умолчанию использует ниндзя в качестве бэкэнда, но можно использовать и другие. Остерегайтесь, поскольку, насколько мне известно, текущая поддержка: ninja лучше всего поддерживается, Visual Studio должна работать довольно хорошо, а XCode на самом деле не готов к производству. На данный момент я постоянно использую себя ниндзя и планирую проверить поддержку Visual Studio, но я не могу утверждать, насколько хорошо это работает на практике со сложным проектом с run_commands, run_targets и пользовательскими скриптами. Бэкэнд ниндзя работает отлично, по крайней мере, могу сказать :)
В Meson у вас есть два позиционных аргумента, которые соответствуют каталогу источника и каталогу сборки. Насколько мне известно, если вы просто перечислите один из каталогов, Meson угадает, что это builddir или исходный каталог. Так, например, предположим, что вы находитесь в корне своего проекта, и выполните следующие действия:
mkdir build cd build meson .. # Here you are mentioning the source dir
Вышеупомянутые команды определят каталог .. как исходный каталог и поместят все содержимое в build
directory. Часть вывода этого вызова для моего проекта выглядит так:
The Meson build system Version: 0.47.0.dev1 Source dir: /Users/germandiago/Desktop/tpii Build dir: /Users/germandiago/Desktop/tpii/build Build type: native build Project name: tpii Native C++ compiler: ccache c++ (clang 9.0.0 "Apple LLVM version 9.0.0 (clang-900.0.39.2)") Build machine cpu family: x86_64 Build machine cpu: x86_64 Configuring tpi-service-config.hpp using configuration Program git found: YES (/usr/bin/git) Program cmake found: YES (/usr/local/bin/cmake) Program make found: YES (/usr/local/bin/make) Dependency Boost (filesystem, regex, iostreams, system) found: YES 1.66, /usr/local/Cellar/boost/1.66.0/ Dependency Boost () found: YES 1.66, /usr/local/Cellar/boost/1.66.0/ Message: Initializating git submodules and compiling needed libraries. This can take a while... Using json from cache. Using json-2.1.1-1-wrap.zip from cache.
Да, я использую CMake для создания другого проекта, поэтому вы его видите здесь :) После завершения настройки вы можете просто сделать ninja
и весело смотреть, как строится ваш проект.
Вы также можете из корня вашего проекта:
mkdir build meson build # Here you are mentioning the build dir ninja -C build
То есть вы можете просто создать каталог сборки и вызвать мезон из корня. Параметр -C в команде ninja указывает Ninja на сборку из каталога сборки, как это может делать GNU Make.
Теперь перейдем к самой командной строке: ваш терминал и введите meson --help
. Вы увидите нечто похожее на это (вывод обрезан для соответствующего обсуждения):
optional arguments: -h, --help show this help message and exit --buildtype {plain,debug,debugoptimized,release,minsize} Build type to use (default: debug). --strip Strip targets on install. --unity {on,off,subprojects} Unity build (default: off). --werror Treat warnings as errors. --warnlevel {1,2,3} Compiler warning level to use (default: 1). --layout {mirror,flat} Build directory layout (default: mirror). --default-library {shared,static,both} Default library type (default: shared). --backend {ninja,vs,vs2010,vs2015,vs2017,xcode} Backend to use (default: ninja). --stdsplit Split stdout and stderr in test logs. --errorlogs Whether to print the logs from failing tests. --install-umask INSTALL_UMASK Default umask to apply on permissions of installed files (default: 022). -D option Set the value of an option, can be used several times to set multiple options. --cross-file CROSS_FILE File describing cross compilation environment. -v, --version show program's version number and exit --wrap-mode {WrapMode.default,WrapMode.nofallback,WrapMode.nodownload,WrapMode.forcefallback} Special wrap mode to use --prefix PREFIX Installation prefix (default: /usr/local).
Давайте рассмотрим некоторые из наиболее распространенных вариантов:
- buildtype
- префикс
- единство
- -Doption = ценность
При первом вызове Meson он настроит и кэширует результаты вызова.
Например, вы можете сделать следующее:
meson --buildtype=release --prefix=`pwd`/install -Dmyoption=true --unity=on
Это создаст сборку выпуска, которая будет установлена в вашем установочном каталоге вашего текущего каталога вызова с вашим настраиваемым параметром (определенным в meson_options.txt) и с использованием сборок единства.
Это для первого вызова.
Перенастройка проектов
После того, как проекты настроены, вы можете увидеть текущую конфигурацию с помощью meson configure builddir
. Это покажет что-то похожее на это:
Core properties: Source dir ... Build dir ... Core options: Option Current Value Possible Values Description ------ ------------- --------------- ----------- buildtype debug [plain, debug, debugoptimized, release, minsize] Build type to use. warning_level 1 [1, 2, 3] Compiler warning level to use. werror false [true, false] Treat warnings as errors. strip false [true, false] Strip targets on install. unity off [on, off, subprojects] Unity build. default_library shared [shared, static, both] Default library type. install_umask 18 Default umask to apply on permissions of installed files. Option Current Value Description ------ ------------- ----------- backend_max_links 0 Maximum number of linker processes to run or 0 for no limit Base options: Option Current Value Possible Values Description ------ ------------- --------------- ----------- b_asneeded true [true, false] Use -Wl,--as-needed when linking b_colorout always [auto, always, never] Use colored output b_coverage false [true, false] Enable coverage tracking. b_lto false [true, false] Use link time optimization b_ndebug false [true, false, if-release] Disable asserts b_pch true [true, false] Use precompiled headers b_pgo off [off, generate, use] Use profile guided optimization b_sanitize none [none, address, thread, undefined, memory, address,undefined] Code sanitizer to use b_staticpic true [true, false] Build static libraries as position independent Compiler arguments: cpp_args [] Linker args: cpp_link_args [] Compiler options: Option Current Value Description ------ ------------- ----------- cpp_std none C++ language standard to use Directories: Option Current Value Description ------ ------------- ----------- prefix /usr/local Installation prefix. libdir lib Library directory. libexecdir libexec Library executable directory. bindir bin Executable directory. sbindir sbin System executable directory. includedir include Header file directory. datadir share Data file directory. mandir share/man Manual page directory. infodir share/info Info page directory. localedir share/locale Locale data directory. sysconfdir etc Sysconf data directory. localstatedir /var/local Localstate data directory. sharedstatedir /var/local/lib Architecture-independent data directory. Project options: Option Current Value Possible Values Description ------ ------------- --------------- ----------- build_boost_from_source false [true, false] Download and build boost from sources and use that dependency. build_tests false [true, false] Build the test suite enable_content_creation false [true, false] Enable custom commands to create website .html contents from .org files enable_tpi false [true, false] Build standalone tpi enable_tpi_service true [true, false] Build the tpi server tpi_service_enable_https false [true, false] Wether https is enabled or not. Used for base url tpi_service_host localhost:8085 Default host or ip address for tpi-service. It can include the port separated by colon tpi_service_listen_port 8085 Default port for tpi-service. It will be used as default when running tpi-service without port argument Testing options: Option Current Value Possible Values Description ------ ------------- --------------- ----------- stdsplit true [true, false] Split stdout and stderr in test logs. errorlogs true [true, false] Whether to print the logs from failing tests.
Любую из этих опций, которые вы видите в списке, можно изменить с помощью -Doptionname = value. Вы можете видеть, что возможные значения перечислены в выводе. Это должно упростить задачу. Итак, теперь давайте удалим сборку Unity из проекта и создадим отладочную версию со статическими библиотеками.
meson configure -Ddefault_library=static -Dbuildtype=debug -Dunity=off builddir
Теперь ваш каталог сборки должен быть уже готов к компиляции с новой конфигурацией.
Вы можете настроить любую опцию с обозначением -Doption = value, даже встроенную, начиная с Meson 0.46.0 (например, prefix и default_library).
Подкоманды и тестирование Meson
В Meson есть несколько подкоманд, стиль которых соответствует популярному контролю версий git. Два из них meson introspect(
, как следует из названия, для анализа метаданных о целях, таких как файлы сборки и т. Д.) И meson test
. Здесь мы увидим только meson test
.
В Meson, когда вы добавляете тесты в свой meson.build
файл с помощью функции test
, и вы можете запускать их в обычном режиме с вызовом серверной части, например ninja test
, без использования meson test
. Как мы увидим, подкоманда meson предназначена для более продвинутого использования и не всегда требуется.
Вот как вы добавляете тест в Meson:
exe = executable('myexe', sources : ['source.cpp']) test('mytest', exe, args : ['--somearg'], env : ['ENVVAR=val'])
Как видите, test поддерживает аргументы и переменные среды. Теперь, запустив ninja test
, можно запустить этот тест. В Meson параллельно проводятся тесты.
Тесты часто запускаются вместе с -Db_coverage = true, чтобы получить отчеты о покрытии тестами.
Существует также benchmark
функция, аналогичная тесту, у которой есть соответствующая цель в ниндзя для запуска тестов. Тесты по сути такие же, как тесты, но они не выполняются параллельно.
Теперь давайте посмотрим, как вы можете вызвать инструмент тестирования в некоторых фрагментах:
# Same as ninja testmeson test
# Invoke the test with name 'testname'meson test testname
# Invoke all tests 10 times (for example because you have randomized tests)meson test --repeat=10
# Run 'testname' under valgrindmeson test --wrap=valgrind testname
# Looking for a strange, unusual crash? First crash puts you in gdbmeson test --gdb --repeat=10000 testname
Вывод
Я думаю, что на данный момент это все, и вы можете получить представление о том, как работает командная строка, как выглядит синтаксис и как вызывать некоторые тесты при различных потребностях. Это все для серии "Начало работы в Meson"!
В своем следующем посте в блоге я начну серию постов, чтобы рассказать о том, как я сделал небольшой, но достаточно большой реальный проект, исходный код которого скоро будет открыт под лицензией Boost. Этот проект использует веб-интерфейс React, библиотеку, исполняемый файл C ++, а также компилирует и экспортирует некоторое содержимое в режиме .org из Emacs в файлы html, которые позже отображаются после манипулирования DOM с помощью внешнего интерфейса React.
Некоторые из вещей, которые будут включены в проект:
- компиляция исполняемого файла и библиотек
- использование meson_options.txt для настройки параметров проекта во время конфигурации
- создание файла project-config.hpp для использования в проекте
- использование run_commands для загрузки зависимости и компиляции в CMake перед настройкой
- запущенные тесты
- использование подпроектов обертывания
- установка цели для запуска веб-службы
Эта следующая серия сообщений в блоге не будет сосредоточена только на Meson, но она обязательно покажет, как все было построено, и будет опубликована в качестве примера, на который вы можете взглянуть в своих проектах. Быть в курсе!
Спасибо за чтение!