从 Autotools 移植

此页面使用 AppStream-glib 作为示例项目。AppStream-Glib 包含一些库、GObject Introspection 数据、测试、手册页、i18n、bash-completion,以及可选标志以构建/不构建对某些事物的支持。

Meson 附带一个助手脚本 ac_converter,您可以使用它来转换项目的基本 autoconf 检查。

Configure.ac

首先让我们看看 configure.ac,并在 meson.build 中编写相同的代码。

AC_PREREQ(2.63)

Meson 没有提供相同的函数,因此只需忽略此部分。

定义变量

configure.ac:

m4_define([as_major_version], [0])
m4_define([as_minor_version], [3])
m4_define([as_micro_version], [6])
m4_define([as_version],
          [as_major_version.as_minor_version.as_micro_version])

meson.build:


as_version = meson.project_version() # set in project() below
ver_arr = as_version.split('.')

as_major_version = ver_arr[0]
as_minor_version = ver_arr[1]
as_micro_version = ver_arr[2]

初始化项目和设置编译器

configure.ac:

AC_INIT([appstream-glib],[as_version])
AC_PROG_CC

meson.build:

project('appstream-glib', 'c', version : '0.3.6')

请注意,这必须是 meson.build 文件的第一行。

AC_SUBST

configure.ac:

AC_SUBST(AS_MAJOR_VERSION)
AC_SUBST(AS_MINOR_VERSION)
AC_SUBST(AS_MICRO_VERSION)
AC_SUBST(AS_VERSION)

您无需在 Meson 中执行相同的操作,因为 Meson 没有两种不同类型的文件(Makefile、configure)。

自动头文件

configure.ac:

AC_CONFIG_HEADERS([config.h])

meson.build:

conf = configuration_data()
# Surround the version in quotes to make it a C string
conf.set_quoted('VERSION', as_version)
configure_file(output : 'config.h',
               configuration : conf)

Meson 不支持自动头文件,您需要手动指定您想在头文件中看到什么,编写 configuration_data() 对象并使用 configure_file()

您也可以使用配置数据替换类型为 @SOME_VAR@ 的变量。详细信息请参见 配置页面

查找程序

configure.ac:

AC_PATH_PROG(GPERF, [gperf], [no])
if test x$GPERF != xno ; then
        AC_DEFINE(HAVE_GPERF,[1], [Use gperf])
fi
AM_CONDITIONAL(HAVE_GPERF, [test x$GPERF != xno])

meson.build:

gperf = find_program('gperf', required : false)
if gperf.found()
  conf.set('HAVE_GPERF', 1)
endif

查找 pkg-config 模块

configure.ac:

PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.24)

meson.build:

soup = dependency('libsoup-2.4', version : '>= 2.24')

参数

configure.ac:

AC_ARG_ENABLE(dep11, AS_HELP_STRING([--enable-dep11],[enable DEP-11]),
              enable_dep11=$enableval,enable_dep11=yes)
AM_CONDITIONAL(HAVE_DEP11, test x$enable_dep11 = xyes)
if test x$enable_dep11 = xyes; then
  AC_CHECK_HEADER(yaml.h, [], [AC_MSG_ERROR([No yaml.h])])
  YAML_LIBS="-lyaml"
  AC_SUBST(YAML_LIBS)
  AC_DEFINE(AS_BUILD_DEP11,1,[Build DEP-11 code])
fi

meson.build:

if get_option('enable-dep11')
  yaml = dependency('yaml-0.1')
  conf.set('AS_BUILD_DEP11', 1)
else
  yaml = dependency('yaml-0.1', required : false)
endif

meson.options:

option('enable-dep11', type : 'boolean', value : true, description : 'enable DEP-11')

Makefile.am

下一步是 Makefile.am。在 Meson 中,您无需拥有其他文件,您仍然使用 meson.build

子目录

Makefile.am:

SUBDIRS =                                         \
        libappstream-glib

meson.build:

subdir('libappstream-glib')

*CLEANFILES、EXTRA_DIST 等。

Makefile.am:

DISTCLEANFILES =                                        \
        appstream-glib-*.tar.xz

MAINTAINERCLEANFILES =                                  \
        *~                                              \
        ABOUT-NLS                                       \
        aclocal.m4                                      \
        ChangeLog                                       \
        compile                                         \
        config.guess                                    \
        config.h.*                                      \
        config.rpath

EXTRA_DIST =                                            \
        COPYING                                         \
        MAINTAINERS                                     \
        AUTHORS                                         \
        README.md                                       \
        NEWS                                            \
        autogen.sh                                      \
        config.h

在 Meson 中,您无需拥有 *CLEANFILES,因为在 Meson 中,您是在临时目录(通常称为 build)中构建的,您手动将其删除。您也不需要使用 EXTRA_DIST,因为您将通过 git archive 或类似方式制作 tarball。

glib-compile-resources

Makefile.am:

as-resources.c: appstream-glib.gresource.xml                    \
                as-stock-icons.txt                              \
                as-license-ids.txt                              \
                as-blacklist-ids.txt                            \
                as-category-ids.txt                             \
                as-environment-ids.txt
        $(AM_V_GEN)                                             \
        glib-compile-resources                                  \
                --sourcedir=$(srcdir)                           \
                --sourcedir=$(top_builddir)/data                \
                --target=$@                                     \
                --generate-source                               \
                --c-name as                                     \
                $(srcdir)/appstream-glib.gresource.xml
as-resources.h: appstream-glib.gresource.xml                    \
                as-stock-icons.txt                              \
                as-license-ids.txt                              \
                as-blacklist-ids.txt                            \
                as-category-ids.txt                             \
                as-environment-ids.txt
        $(AM_V_GEN)                                             \
        glib-compile-resources                                  \
                --sourcedir=$(srcdir)                           \
                --sourcedir=$(top_builddir)/data                \
                --target=$@                                     \
                --generate-header                               \
                --c-name as                                     \
                $(srcdir)/appstream-glib.gresource.xml

BUILT_SOURCES =                                                 \
        as-resources.c                                          \
        as-resources.h

meson.build:

asresources = gnome.compile_resources(
  'as-resources', 'appstream-glib.gresource.xml',
  source_dir : '.',
  c_name : 'as')

头文件

Makefile.am:

libappstream_glib_includedir = $(includedir)/libappstream-glib
libappstream_glib_include_HEADERS =                             \
        appstream-glib.h                                        \
        as-app.h                                                \
        as-bundle.h                                             \
        as-enums.h                                              \
        as-icon.h                                               \
        as-image.h                                              \
        as-inf.h                                                \
        as-node.h                                               \
        as-problem.h                                            \
        as-provide.h                                            \
        as-release.h                                            \
        as-screenshot.h                                         \
        as-store.h                                              \
        as-tag.h                                                \
        as-utils.h                                              \
        as-version.h

meson.build:

headers = [
  'appstream-glib.h',
  'as-app.h',
  'as-bundle.h',
  'as-enums.h',
  'as-icon.h',
  'as-image.h',
  'as-inf.h',
  'as-node.h',
  'as-problem.h',
  'as-provide.h',
  'as-release.h',
  'as-screenshot.h',
  'as-store.h',
  'as-tag.h',
  'as-utils.h',
  'as-version.h']
install_headers(headers, subdir : 'libappstream-glib')

Makefile.am:

lib_LTLIBRARIES =                                               \
        libappstream-glib.la
libappstream_glib_la_SOURCES =                                  \
        as-app.c                                                \
        as-app-desktop.c                                        \
        as-app-inf.c                                            \
        as-app-private.h                                        \
        as-app-validate.c                                       \
        as-bundle.c                                             \
        as-bundle-private.h                                     \
        as-cleanup.h                                            \
        as-enums.c                                              \
        as-icon.c                                               \
        as-icon-private.h                                       \
        as-image.c                                              \
        as-image-private.h                                      \
        as-inf.c                                                \
        as-inf.h                                                \
        as-node.c                                               \
        as-node-private.h                                       \
        as-problem.c                                            \
        as-problem.h                                            \
        as-provide.c                                            \
        as-provide-private.h                                    \
        as-release.c                                            \
        as-release-private.h                                    \
        as-resources.c                                          \
        as-resources.h                                          \
        as-screenshot.c                                         \
        as-screenshot-private.h                                 \
        as-store.c                                              \
        as-tag.c                                                \
        as-utils.c                                              \
        as-utils-private.h                                      \
        as-version.h                                            \
        as-yaml.c                                               \
        as-yaml.h

libappstream_glib_la_LIBADD =                                   \
        $(GLIB_LIBS)                                            \
        $(GDKPIXBUF_LIBS)                                       \
        $(LIBARCHIVE_LIBS)                                      \
        $(SOUP_LIBS)                                            \
        $(YAML_LIBS)

libappstream_glib_la_LDFLAGS =                                  \
        -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)    \
        -export-dynamic                                         \
        -no-undefined                                           \
        -export-symbols-regex '^as_.*'

meson.build:

sources = [
  'as-app.c',
  'as-app-desktop.c',
  'as-app-inf.c',
  'as-app-private.h',
  'as-app-validate.c',
  'as-bundle.c',
  'as-bundle-private.h',
  'as-cleanup.h',
  'as-enums.c',
  'as-icon.c',
  'as-icon-private.h',
  'as-image.c',
  'as-image-private.h',
  'as-inf.c',
  'as-inf.h',
  'as-node.c',
  'as-node-private.h',
  'as-problem.c',
  'as-problem.h',
  'as-provide.c',
  'as-provide-private.h',
  'as-release.c',
  'as-release-private.h',
  asresources,
  'as-screenshot.c',
  'as-screenshot-private.h',
  'as-store.c',
  'as-tag.c',
  'as-utils.c',
  'as-utils-private.h',
  'as-version.h',
  'as-yaml.c',
  'as-yaml.h']

deps = [glib, gdkpixbuf, libarchive, soup, yaml]

mapfile = 'appstream-glib.map'
vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
asglib = shared_library(
  'appstream-glib', sources,
  soversion : lt_current,
  version : lt_version,
  dependencies : deps,
  include_directories : include_directories('@0@/..'.format(meson.current_build_dir())),
  link_args : ['-Wl,--no-undefined', vflag],
  link_depends : mapfile,
  install : true)

appstream-glib.map:

{
global:
    as_*;
local:
    *;
};

自定义目标

Makefile.am:

if HAVE_GPERF
as-tag-private.h: as-tag.gperf
        $(AM_V_GEN) gperf < $< > $@

libappstream_glib_la_SOURCES += as-tag-private.h
BUILT_SOURCES += as-tag-private.h
endif

meson.build:

if gperf.found()
  astagpriv = custom_target('gperf as-tag',
                            output : 'as-tag-private.h',
                            input : 'as-tag.gperf',
                            command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
  sources = sources + [astagpriv]
endif

全局 CFLAGS

Makefile.am:

AM_CPPFLAGS =                                                   \
        -DAS_COMPILATION                                        \
        -DLOCALSTATEDIR=\""$(localstatedir)"\"                  \
        -DG_LOG_DOMAIN=\"As\"

meson.build:

add_project_arguments('-DG_LOG_DOMAIN="As"', language : 'c')
add_project_arguments('-DAS_COMPILATION', language : 'c')
add_project_arguments('-DLOCALSTATEDIR="/var"', language : 'c')

测试

Makefile.am:

check_PROGRAMS =                                                \
        as-self-test
as_self_test_SOURCES =                                          \
        as-self-test.c
as_self_test_LDADD =                                            \
        $(GLIB_LIBS)                                            \
        $(GDKPIXBUF_LIBS)                                       \
        $(LIBARCHIVE_LIBS)                                      \
        $(SOUP_LIBS)                                            \
        $(YAML_LIBS)                                            \
        $(lib_LTLIBRARIES)
as_self_test_CFLAGS = -DTESTDATADIR=\""$(top_srcdir)/data/tests"\"

TESTS = as-self-test

meson.build:

selftest = executable(
  'as-self-test', 'as-self-test.c',
  include_directories : include_directories('@0@/..'.format(meson.current_build_dir())),
  dependencies : deps,
  c_args : '-DTESTDATADIR="@0@/../data/tests"'.format(meson.current_source_dir()),
  link_with : asglib)
test('as-self-test', selftest)

GObject Introspection

Makefile.am:

introspection_sources =                                         \
        as-app.c                                                \
        as-app-validate.c                                       \
        as-app.h                                                \
        as-bundle.c                                             \
        as-bundle.h                                             \
        as-enums.c                                              \
        as-enums.h                                              \
        as-icon.c                                               \
        as-icon.h                                               \
        as-image.c                                              \
        as-image.h                                              \
        as-inf.c                                                \
        as-inf.h                                                \
        as-node.c                                               \
        as-node.h                                               \
        as-problem.c                                            \
        as-problem.h                                            \
        as-provide.c                                            \
        as-provide.h                                            \
        as-release.c                                            \
        as-release.h                                            \
        as-screenshot.c                                         \
        as-screenshot.h                                         \
        as-store.c                                              \
        as-store.h                                              \
        as-tag.c                                                \
        as-tag.h                                                \
        as-utils.c                                              \
        as-utils.h                                              \
        as-version.h

AppStreamGlib-1.0.gir: libappstream-glib.la
AppStreamGlib_1_0_gir_INCLUDES = GObject-2.0 Gio-2.0 GdkPixbuf-2.0
AppStreamGlib_1_0_gir_CFLAGS = $(AM_CPPFLAGS)
AppStreamGlib_1_0_gir_SCANNERFLAGS = --identifier-prefix=As \
                                --symbol-prefix=as_ \
                                --warn-all \
                                --add-include-path=$(srcdir)
AppStreamGlib_1_0_gir_EXPORT_PACKAGES = appstream-glib
AppStreamGlib_1_0_gir_LIBS = libappstream-glib.la
AppStreamGlib_1_0_gir_FILES = $(introspection_sources)
INTROSPECTION_GIRS += AppStreamGlib-1.0.gir

girdir = $(datadir)/gir-1.0
gir_DATA = $(INTROSPECTION_GIRS)

typelibdir = $(libdir)/girepository-1.0
typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)

CLEANFILES += $(gir_DATA) $(typelib_DATA)

meson.build:

introspection_sources = [
  'as-app.c',
  'as-app-validate.c',
  'as-app.h',
  'as-bundle.c',
  'as-bundle.h',
  'as-enums.c',
  'as-enums.h',
  'as-icon.c',
  'as-icon.h',
  'as-image.c',
  'as-image.h',
  'as-inf.c',
  'as-inf.h',
  'as-node.c',
  'as-node.h',
  'as-problem.c',
  'as-problem.h',
  'as-provide.c',
  'as-provide.h',
  'as-release.c',
  'as-release.h',
  'as-screenshot.c',
  'as-screenshot.h',
  'as-store.c',
  'as-store.h',
  'as-tag.c',
  'as-tag.h',
  'as-utils.c',
  'as-utils.h',
  'as-version.h']

gnome.generate_gir(asglib,
  sources : introspection_sources,
  nsversion : '1.0',
  namespace : 'AppStreamGlib',
  symbol_prefix : 'as_',
  identifier_prefix : 'As',
  export_packages : 'appstream-glib',
  includes : ['GObject-2.0', 'Gio-2.0', 'GdkPixbuf-2.0'],
  install : true
)

GSettings

configure.ac:

GLIB_GSETTINGS

Makefile.am:

gsettings_SCHEMAS = foo.gschema.xml
@GSETTINGS_RULES@

meson.build:

install_data('foo.gschema.xml', install_dir: get_option('datadir') / 'glib-2.0' / 'schemas')
meson.add_install_script('meson_post_install.py')

meson_post_install.py:

#!/usr/bin/env python3

import os
import subprocess

schemadir = os.path.join(os.environ['MESON_INSTALL_PREFIX'], 'share', 'glib-2.0', 'schemas')

if not os.environ.get('DESTDIR'):
    print('Compiling gsettings schemas...')
    subprocess.call(['glib-compile-schemas', schemadir])

gettext

请注意,此示例不包含 intltool 用法。

configure.ac:

AM_GNU_GETTEXT([external])
AM_GNU_GETTEXT_VERSION([0.19.7])

GETTEXT_PACKAGE=foo
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The prefix for our gettext translation domains.])

po/Makevars:

XGETTEXT_OPTIONS =  --from-code=UTF-8 --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 --keyword=g_dngettext:2,3 --add-comments

Makefile.am:

%.desktop: %.desktop.in
    $(AM_V_GEN)$(MSGFMT) --desktop --template $< -d $(top_srcdir)/po -o $@

%.appdata.xml: %.appdata.xml.in
    $(AM_V_GEN)$(MSGFMT) --xml --template $< -d $(top_srcdir)/po -o $@

meson.build:

i18n = import('i18n')

gettext_package = 'foo'
add_project_arguments('-DGETTEXT_PACKAGE=' + gettext_package, language: 'c')
subdir('po')

i18n.merge_file(
  input: 'foo.desktop.in',
  output: 'foo.desktop',
  type: 'desktop',
  po_dir: 'po',
  install: true,
  install_dir: get_option('datadir') / 'applications'
)

i18n.merge_file(
  input: 'foo.appdata.xml.in',
  output: 'foo.appdata.xml',
  po_dir: 'po',
  install: true,
  install_dir: get_option('datadir') / 'appdata'
)

po/meson.build:

i18n.gettext(gettext_package, preset: 'glib')

搜索结果为