On 27/07/18 06:52, Frediano Ziglio wrote: >> >> On 26/07/18 08:46, Frediano Ziglio wrote: >>>> >>>> In a comparison with current autotools build system, meson/ninja >>>> provides a huge improvement in build speed, while keeping the same >>>> functionalities currently available and being considered more user >>>> friendly. >>>> >>>> The new system coexists within the same repository with the current one, >>>> so we can do more extensive testing of its functionality before deciding >>>> if the old system can be removed, or for some reason, has to stay for >>>> good. >>>> >>>> - Meson: https://mesonbuild.com >>>> >>>> This is the equivalent of autogen/configure step in autotools. It >>>> generates the files that will be used by ninja to actually build the >>>> source code. >>>> >>>> The project has received lots of traction recently, with many GNOME >>>> projects willing to move to this new build system. The following wiki >>>> page has more details of the status of the many projects being ported: >>>> >>>> https://wiki.gnome.org/Initiatives/GnomeGoals/MesonPorting >>>> >>>> Meson has a python-like syntax, easy to read, and the documentation >>>> on the project is very complete, with a dedicated page on how to port >>>> from autotools, explaining how most common use cases can be >>>> implemented using meson. >>>> >>>> http://mesonbuild.com/Porting-from-autotools.html >>>> >>>> Other important sources of information: >>>> >>>> http://mesonbuild.com/howtox.html >>>> http://mesonbuild.com/Syntax.html >>>> http://mesonbuild.com/Reference-manual.html >>>> >>>> - Ninja: https://ninja-build.org >>>> >>>> Ninja is the equivalent of make in an autotools setup, which actually >>>> builds the source code. It has being used by large and complex >>>> projects such as Google Chrome, Android and LLVM. There is not much to >>>> say about ninja (other than it is much faster than make) because we >>>> won't interact directly with it as much, as meson does the middle man >>>> job here. The reasoning for creating ninja in the first place is >>>> explained on the following post: >>>> >>>> http://neugierig.org/software/chromium/notes/2011/02/ninja.html >>>> >>>> Also its manual provides more in-depth information about the design >>>> principles: >>>> >>>> https://ninja-build.org/manual.html >>>> >>>> - Basic workflow: >>>> >>>> Meson package is available for most if not all distros, so, taking >>>> Fedora as an example, we only need to run: >>>> >>>> # dnf -y install meson ninja-build. >>>> >>>> With Meson, building in-tree is not possible at all, so we need to >>>> pass a directory as argument to meson where we want the build to be >>>> done. This has the advantage of creating builds with different options >>>> under the same parent directory, e.g.: >>>> >>>> $ meson ./build --prefix=/usr >>>> $ meson ./build-extra -Dextra-checks=true -Dalignment-checks=true >>>> >>>> After configuration is done, we call ninja to actually do the build. >>>> >>>> $ ninja -C ./build >>>> $ ninja -C ./build install >>>> >>>> Ninja defaults to parallel builds, and this can be changed with the -j >>>> flag. >>>> >>>> $ ninja -j 10 -C ./build >>>> >>>> - Hacking: >>>> >>>> * meson.build: Mandatory for the project root and usually found under >>>> each directory you want something to be built. >>>> >>>> * meson_options.txt: Options that can interfere with the result of the >>>> build. >>>> >>>> Signed-off-by: Eduardo Lima (Etrunko) <etrunko@xxxxxxxxxx> >>>> Signed-off-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> >>>> Signed-off-by: Frediano Ziglio <fziglio@xxxxxxxxxx> >>>> --- >>>> Makefile.am | 3 + >>>> build-aux/meson/check-spice-common | 5 + >>>> docs/Makefile.am | 1 + >>>> docs/manual/Makefile.am | 1 + >>>> docs/manual/meson.build | 18 +++ >>>> docs/meson.build | 14 +++ >>>> meson.build | 219 >>>> +++++++++++++++++++++++++++++++++++++ >>>> meson_options.txt | 52 +++++++++ >>>> server/Makefile.am | 1 + >>>> server/meson.build | 188 +++++++++++++++++++++++++++++++ >>>> server/tests/Makefile.am | 1 + >>>> server/tests/meson.build | 85 ++++++++++++++ >>>> subprojects/spice-common | 2 +- >>>> tools/Makefile.am | 4 + >>>> tools/meson.build | 4 + >>>> 15 files changed, 597 insertions(+), 1 deletion(-) >>>> create mode 100755 build-aux/meson/check-spice-common >>>> create mode 100644 docs/manual/meson.build >>>> create mode 100644 docs/meson.build >>>> create mode 100644 meson.build >>>> create mode 100644 meson_options.txt >>>> create mode 100644 server/meson.build >>>> create mode 100644 server/tests/meson.build >>>> create mode 100644 tools/meson.build >>>> >>> >>> .... >>> >>>> diff --git a/docs/meson.build b/docs/meson.build >>>> new file mode 100644 >>>> index 00000000..82864bb8 >>>> --- /dev/null >>>> +++ b/docs/meson.build >>>> @@ -0,0 +1,14 @@ >>>> +if get_option('manual') >>>> + asciidoc = find_program('asciidoc', required : false) >>>> + if asciidoc.found() >>>> + asciidoc_args = ['-a', 'data-uri', '-a', 'icons', '-a', 'toc'] >>>> + foreach doc : ['style', 'threading_model'] >>>> + custom_target('spice_@0@.html'.format(doc), >>>> + input : 'spice_@0@.txt'.format(doc), >>>> + output : 'spice_@0@.html'.format(doc), >>>> + build_by_default: true, >>>> + command : [asciidoc, '-n', asciidoc_args, '-o', >>>> '@OUTPUT@', '@INPUT@']) >>>> + endforeach >>>> + endif >>>> + subdir('manual') >>>> +endif >>>> diff --git a/meson.build b/meson.build >>>> new file mode 100644 >>>> index 00000000..b7b7fee7 >>>> --- /dev/null >>>> +++ b/meson.build >>>> @@ -0,0 +1,219 @@ >>>> +# >>>> +# project definition >>>> +# >>>> +project('spice', 'c', >>>> + version : run_command('build-aux/git-version-gen', >>>> '${MESON_SOURCE_ROOT}/.tarball-version').stdout().strip(), >>>> + license : 'LGPLv2.1', >>>> + meson_version : '>= 0.47.0') >>>> + >>>> +# double check meson.project_version() >>>> +# we can not use 'check' keyword in run_command() for git-version-gen >>>> above >>>> +# https://github.com/mesonbuild/meson/issues/3944 >>>> +version = run_command('build-aux/git-version-gen', >>>> '${MESON_SOURCE_ROOT}/.tarball-version', check : true).stdout().strip() >>>> +if meson.project_version() != version >>>> + error('Wrong project version') >>>> +endif >>>> + >>>> +message('Updating submodules') >>>> +run_command('build-aux/meson/check-spice-common', check : true) >>>> + >>>> +# some global vars >>>> +spice_server_so_version = '1.12.4' >>>> + >>>> +spice_server_global_cflags = ['-fvisibility=hidden', >>>> + '-DSPICE_SERVER_INTERNAL', >>>> + '-DG_LOG_DOMAIN="Spice"', >>>> + '-DHAVE_CONFIG_H', >>>> + #'-Werror', >>>> + '-Wall', >>>> + '-Wextra', >>>> + '-Wno-sign-compare', >>>> + '-Wno-unused-parameter'] >>>> + >>>> +compiler = meson.get_compiler('c') >>>> +spice_server_config_data = configuration_data() >>>> +spice_server_include = [include_directories('.')] >>>> +spice_server_deps = [] >>>> +spice_server_link_args = [] >>>> +spice_server_requires = '' >>>> + >>>> +# >>>> +# Spice common subproject >>>> +# >>>> +spice_common = subproject('spice-common', default_options : >>>> 'generate-code=server') >>>> +spice_server_config_data.merge_from(spice_common.get_variable('spice_common_config_data')) >>>> +spice_server_deps += spice_common.get_variable('spice_common_server_dep') >>>> + >>>> +# >>>> +# check for system headers >>>> +# >>>> +headers = ['sys/time.h', >>>> + 'execinfo.h', >>>> + 'linux/sockios.h', >>>> + 'pthread_np.h'] >>>> + >>>> +foreach header : headers >>>> + if compiler.has_header(header) >>>> + >>>> spice_server_config_data.set('HAVE_@0@'.format(header.underscorify().to_upper()), >>>> '1') >>>> + endif >>>> +endforeach >>>> + >>>> +# TCP_KEEPIDLE definition in netinet/tcp.h >>>> +if compiler.has_header_symbol('netinet/tcp.h', 'TCP_KEEPIDLE') >>>> + spice_server_config_data.set('HAVE_TCP_KEEPIDLE', '1') >>>> +endif >>>> + >>>> +# >>>> +# check for mandatory dependencies >>>> +# >>>> +spice_protocol_version='>= 0.12.15' >>>> + >>>> +glib_version = '2.38' >>>> +glib_version_info = '>= @0@'.format(glib_version) >>>> + >>>> +deps = [['spice-protocol', spice_protocol_version], >>>> + ['glib-2.0', glib_version_info], >>>> + ['gio-2.0', glib_version_info], >>>> + ['gobject-2.0', glib_version_info], >>>> + ['pixman-1', '>= 0.17.7'], >>>> + ['openssl', '>= 1.0.0']] >>>> + >>>> +foreach dep : deps >>>> + spice_server_deps += dependency(dep[0], version : dep[1]) >>>> +endforeach >>>> + >>>> +# TODO: specify minimum version for jpeg and zlib? >>>> +foreach dep : ['libjpeg', 'zlib'] >>>> + spice_server_deps += dependency(dep) >>>> +endforeach >>>> + >>>> +foreach dep : ['librt', 'libm'] >>>> + spice_server_deps += compiler.find_library(dep) >>>> +endforeach >>>> + >>>> +# >>>> +# Non-mandatory/optional dependencies >>>> +# >>>> +optional_deps = [ >>>> + ['celt051', '>= 0.5.1.1'], >>>> + ['opus', '>= 0.9.14'], >>>> + ] >>>> +foreach dep : optional_deps >>>> + option_value = get_option(dep[0]) >>>> + if option_value != 'false' >>>> + d = dependency(dep[0], required: (option_value == 'true'), version : >>>> dep[1]) >>>> + if d.found() >>>> + spice_server_deps += d >>>> + >>>> spice_server_config_data.set('HAVE_@0@'.format(dep[0].underscorify().to_upper()), >>>> '1') >>>> + endif >>>> + endif >>>> +endforeach >>>> + >>>> +# gstreamer >>>> +spice_server_has_gstreamer = false >>>> +spice_server_gst_version = get_option('gstreamer') >>>> +if spice_server_gst_version != 'no' >>>> + gst_deps = ['gstreamer', 'gstreamer-base', 'gstreamer-app', >>>> 'gstreamer-video'] >>>> + foreach dep : gst_deps >>>> + dep = '@0@-@1@'.format(dep, spice_server_gst_version) >>>> + spice_server_deps += dependency(dep) >>>> + endforeach >>>> + spice_server_deps += dependency('orc-0.4') >>>> + >>>> + gst_def = 'HAVE_GSTREAMER' >>>> + if spice_server_gst_version == '1.0' >>>> + gst_def = 'HAVE_GSTREAMER_1_0' >>>> + endif >>>> + >>>> + spice_server_config_data.set(gst_def, '1') >>>> + spice_server_has_gstreamer = true >>>> +endif >>>> + >>>> +# lz4 >>>> +spice_server_has_lz4 = false >>>> +if get_option('lz4') >>>> + lz4_dep = dependency('liblz4', required : false, version : '>= 129') >>>> + if not lz4_dep.found() >>>> + lz4_dep = dependency('liblz4', version : '>= 1.7.3') >>>> + endif >>>> + >>>> + if compiler.has_function('LZ4_compress_fast_continue', dependencies : >>>> lz4_dep) >>>> + spice_server_config_data.set('HAVE_LZ4_COMPRESS_FAST_CONTINUE', '1') >>>> + endif >>>> + >>>> + spice_server_deps += lz4_dep >>>> + spice_server_config_data.set('USE_LZ4', '1') >>>> + spice_server_has_lz4 = true >>>> +endif >>>> + >>>> +# sasl >>>> +spice_server_has_sasl = false >>>> +if get_option('sasl') >>>> + spice_server_deps += dependency('libsasl2') >>>> + spice_server_config_data.set('HAVE_SASL', '1') >>>> + spice_server_has_sasl = true >>>> +endif >>>> + >>>> +# smartcard check >>>> +spice_server_has_smartcard = false >>>> +if get_option('smartcard') >>>> + smartcard_dep = dependency('libcacard', required : false, version : '>= >>>> 2.5.1') >>>> + if smartcard_dep.found() >>>> + spice_server_deps += smartcard_dep >>>> + spice_server_config_data.set('USE_SMARTCARD', '1') >>>> + else >>>> + smartcard012_dep = dependency('libcacard', required : false, version >>>> : >>>> '>= 0.1.2') >>>> + if smartcard012_dep.found() >>>> + spice_server_deps += smartcard012_dep >>>> + spice_server_config_data.set('USE_SMARTCARD_012', '1') >>>> + endif >>>> + endif >>>> + >>>> + spice_server_has_smartcard = smartcard_dep.found() or >>>> smartcard012_dep.found() >>>> + if not spice_server_has_smartcard >>>> + error('Building with smartcard support but dependency not found') >>>> + endif >>>> +endif >>>> + >>>> +# >>>> +# global C defines >>>> +# >>>> +glib_major_minor = glib_version.split('.') >>>> +glib_encoded_version = 'GLIB_VERSION_@0@_@1@'.format(glib_major_minor[0], >>>> glib_major_minor[1]) >>>> +spice_server_global_cflags += >>>> ['-DGLIB_VERSION_MIN_REQUIRED=@0@'.format(glib_encoded_version), >>>> + >>>> '-DGLIB_VERSION_MAX_ALLOWED=@0@'.format(glib_encoded_version)] >>>> + >>>> +foreach arg : spice_server_global_cflags >>>> + add_project_arguments(arg, language : 'c') >>>> +endforeach >>>> + >>>> +# >>>> +# Subdirectories >>>> +# >>>> +subdir('server') >>>> +subdir('tools') >>>> +subdir('docs') >>>> + >>>> +# >>>> +# write config.h >>>> +# >>>> +spice_server_config_data.set_quoted('VERSION', meson.project_version()) >>>> +spice_server_config_data.set('SPICE_USE_SAFER_CONTAINEROF', '1') >>>> + >>>> +if get_option('statistics') >>>> + spice_server_config_data.set('RED_STATISTICS', '1') >>>> +endif >>>> + >>>> +configure_file(output : 'config.h', >>>> + install : false, >>>> + configuration : spice_server_config_data) >>>> + >>>> +# >>>> +# write spice-server.pc >>>> +# >>>> +pkgconfig = import('pkgconfig') >>>> +pkgconfig.generate(spice_server_shared_lib, >>>> + description : 'SPICE server library', >>>> + requires : 'spice-protocol >>>> @0@'.format(spice_protocol_version), >>>> + variables : 'exec_prefix=${prefix}', >>>> + subdirs : 'spice-server') >>> >>> Was testing the difference in installed files. From autoconf: >>> >>> ----- >>> prefix=/home/freddy/qemu >>> exec_prefix=${prefix} >>> libdir=${exec_prefix}/lib >>> includedir=${prefix}/include >>> >>> Name: spice >>> Description: SPICE server library >>> Version: 0.14.0.292-aad0-dirty >>> >>> Requires: spice-protocol >= 0.12.15 >>> Requires.private: libcacard >= 0.1.2 glib-2.0 >= 2.32 gio-2.0 >= 2.32 >>> gobject-2.0 >= 2.32 pixman-1 >= 0.17.7 openssl >>> Libs: -L${libdir} -lspice-server >>> Libs.private: -pthread -lm -lrt >>> Cflags: -I${includedir}/spice-server >>> ---- >>> >>> From Meson: >>> ----- >>> prefix=/usr/local >>> libdir=${prefix}/lib64 >>> includedir=${prefix}/include >>> >>> exec_prefix=${prefix} >>> >>> Name: spice-server >>> Description: SPICE server library >>> Version: 0.14.0.292-aad0-dirty >>> Requires: spice-protocol >= 0.12.15, spice-protocol >= 0.12.12 >>> Requires.private: glib-2.0 >= 2.38, gio-2.0 >= 2.38, gthread-2.0 >= >>> 2.38, pixman-1 >= 0.17.7, openssl >= 1.0.0, celt051 >= 0.5.1.1, opus >>>> = 0.9.14, libcacard >= 0.1.2, gobject-2.0 >= 2.38, libjpeg, zlib, >>> gstreamer-1.0, gstreamer-base-1.0, gstreamer-app-1.0, gstreamer-video-1.0, >>> orc-0.4, liblz4 >= 1.7.3, libsasl2 >>> Libs: -L${libdir} -lspice-server >>> Libs.private: -lm -L${libdir} -lspice-common -lm -lm -lspice-common-server >>> -lm /usr/lib64/librt.so /usr/lib64/libm.so >>> Cflags: -I${includedir}/spice-server >>> ----- >>> >>> Beside directories that is up to the setup: >>> - Name is spice for autotools, spice-server for Meson, seems more correct >>> Meson >>> - Requires in Meson specify 2 times spice-protocol, should not be an issue >>> - Requires.private in Meson contains a lot of more libraries, this cause >>> pkg-config --cflags to add a lot of include directories which are not >>> required to link to spice library and IMHO should be avoided >>> - Libs.private contains duplications, direct shared library names (why?) >>> and libraries (spice-common) which should not be there. Not clear where >>> this directive is used, pkg-config --libs seems not to consider these >>> libraries. >>> I don't know how to solve these, maybe the spice-common library should be >>> more a static library (in libtool they are called convenience libraries). >>> >> >> Basically meson uses the dependencies to build the pkgconfig file. In >> the case of two spice-protocol in 'Requires', the second one comes from >> spice-common, which explains the different version. The duplication in >> 'Libs.private' seems to be the same. >> >> If you think it is necessary, we can of course keep using the >> spice.pc.in instead of the built-in pkgconfig module for meson. This >> will give exact same results as in autotools build. >> > > I'll explain why this module in Meson is buggy. > > Let's say I'm building libc using Meson. libc uses kernel headers to use > some feature and expose a more or less plain C interface. > Do you think all code using libc have to include kernel headers or have > these include in their path list? Surely no, but Meson include directory > paths for all dependencies! Unless the libc headers include kernel headers > but is up to libc to tell the build system this. > > In recent systems for dynamic object (.so/.dll/.whatever) loading the same > is true so the Libs directive is correct. > > The Libs.private however is expected to be used for static library, now: > 1- the library passed is only dynamic, no reason to provide option for > a library that won't be installed; > 2- the directive include a mix of system libraries (-lm), convenience > libraries (-lspice-common) and dynamic libraries (/usr/lib64/libm.so) > but if you want static library you usually want static linking so why > to include dynamic ones? > 5- why libm is specified 5 times? > Agreed, will change this in order to keep using the template file. > Frediano > -- Eduardo de Barros Lima (Etrunko) Software Engineer - RedHat etrunko@xxxxxxxxxx _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel