diff --git a/configure_meson b/configure_meson new file mode 100755 index 00000000..40c24cac --- /dev/null +++ b/configure_meson @@ -0,0 +1,166 @@ +#!/bin/bash +# configure script adapter for Meson +# Based on build-api: https://github.com/cgwalters/build-api +# Copyright 2010, 2011, 2013 Colin Walters +# Copyright 2016, 2017 Emmanuele Bassi +# Copyright 2017 Iñigo Martínez +# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php) + +# Build API variables: + +# Little helper function for reading args from the commandline. +# it automatically handles -a b and -a=b variants, and returns 1 if +# we need to shift $3. +read_arg() { + # $1 = arg name + # $2 = arg value + # $3 = arg parameter + local rematch='^[^=]*=(.*)$' + if [[ $2 =~ $rematch ]]; then + read "$1" <<< "${BASH_REMATCH[1]}" + else + read "$1" <<< "$3" + # There is no way to shift our callers args, so + # return 1 to indicate they should do it instead. + return 1 + fi +} + +sanitycheck() { + # $1 = arg name + # $1 = arg command + # $2 = arg alternates + local cmd=$( which $2 2>/dev/null ) + + if [ -x "$cmd" ]; then + read "$1" <<< "$cmd" + return 0 + fi + + test -z $3 || { + for alt in $3; do + cmd=$( which $alt 2>/dev/null ) + + if [ -x "$cmd" ]; then + read "$1" <<< "$cmd" + return 0 + fi + done + } + + echo -e "\e[1;31mERROR\e[0m: Command '$2' not found" + exit 1 +} + +checkoption() { + # $1 = arg + option="${1#*--}" + action="${option%%-*}" + name="${option#*-}" + if [ ${default_options[$name]+_} ]; then + case "$action" in + enable) meson_options[$name]=true;; + disable) meson_options[$name]=false;; + *) echo -e "\e[1;33mINFO\e[0m: Ignoring unknown action '$action'";; + esac + else + echo -e "\e[1;33mINFO\e[0m: Ignoring unknown option '$option'" + fi +} + +echooption() { + # $1 = option + if [ ${meson_options[$1]+_} ]; then + echo ${meson_options[$1]} + elif [ ${default_options[$1]+_} ]; then + echo ${default_options[$1]} + fi +} + +sanitycheck MESON 'meson' +sanitycheck MESONTEST 'mesontest' +sanitycheck NINJA 'ninja' 'ninja-build' + +declare -A default_options=( + ['gtk-doc']=false + ['tracing']=false +) + +declare -A meson_options + +while (($# > 0)); do + case "${1%%=*}" in + --prefix) read_arg prefix "$@" || shift;; + --bindir) read_arg bindir "$@" || shift;; + --sbindir) read_arg sbindir "$@" || shift;; + --libexecdir) read_arg libexecdir "$@" || shift;; + --datarootdir) read_arg datarootdir "$@" || shift;; + --datadir) read_arg datadir "$@" || shift;; + --sysconfdir) read_arg sysconfdir "$@" || shift;; + --libdir) read_arg libdir "$@" || shift;; + --mandir) read_arg mandir "$@" || shift;; + --includedir) read_arg includedir "$@" || shift;; + *) checkoption $1;; + esac + shift +done + +# Defaults +test -z ${prefix} && prefix="/usr/local" +test -z ${bindir} && bindir=${prefix}/bin +test -z ${sbindir} && sbindir=${prefix}/sbin +test -z ${libexecdir} && libexecdir=${prefix}/bin +test -z ${datarootdir} && datarootdir=${prefix}/share +test -z ${datadir} && datadir=${datarootdir} +test -z ${sysconfdir} && sysconfdir=${prefix}/etc +test -z ${libdir} && libdir=${prefix}/lib +test -z ${mandir} && mandir=${prefix}/share/man +test -z ${includedir} && includedir=${prefix}/include + +# The source directory is the location of this file +srcdir=$(dirname $0) + +# The build directory is the current location +builddir=`pwd` + +# If we're calling this file from the source directory then +# we automatically create a build directory and ensure that +# both Meson and Ninja invocations are relative to that +# location +if [[ -f "${builddir}/meson.build" ]]; then + mkdir -p _build + builddir="${builddir}/_build" + NINJA_OPT="-C ${builddir}" +fi + +# Wrapper Makefile for Ninja +cat > Makefile < + + + + + + diff --git a/doc/reference/xml/meson.build b/doc/reference/xml/meson.build new file mode 100644 index 00000000..ee0004db --- /dev/null +++ b/doc/reference/xml/meson.build @@ -0,0 +1,7 @@ +ent = 'gtkdocentities.ent' + +configure_file( + input: ent + '.in', + output: ent, + configuration: config_h +) diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..f3c0a36f --- /dev/null +++ b/meson.build @@ -0,0 +1,212 @@ +project( + 'gnome-calendar', 'c', + version: '3.25.3', + license: 'GPL3+', + default_options: [ + 'buildtype=debugoptimized', + 'warning_level=1' + ], + meson_version: '>= 0.41.0' +) + +calendar_version = meson.project_version() +version_array = calendar_version.split('.') +calendar_major_version = version_array[0].to_int() +calendar_minor_version = version_array[1].to_int() +calendar_micro_version = version_array[2].to_int() + +calendar_prefix = get_option('prefix') +calendar_bindir = join_paths(calendar_prefix, get_option('bindir')) +calendar_localedir = join_paths(calendar_prefix, get_option('localedir')) +calendar_datadir = join_paths(calendar_prefix, get_option('datadir')) + +calendar_pkgdatadir = join_paths(calendar_datadir, meson.project_name()) + +calendar_schemadir = join_paths(calendar_datadir, 'glib-2.0', 'schemas') + +calendar_buildtype = get_option('buildtype') + +calendar_debug = calendar_minor_version.is_odd() or buildtype.contains('debug') + +enable_tracing = get_option('enable-tracing') +enable_gtk_doc = get_option('enable-gtk-doc') + +cc = meson.get_compiler('c') + +config_h = configuration_data() + +package_bugreport = 'http://bugzilla.gnome.org/enter_bug.cgi?product=' + meson.project_name() + +# package +set_defines = [ + ['PACKAGE', meson.project_name()], + ['PACKAGE_BUGREPORT', package_bugreport], + ['PACKAGE_NAME', meson.project_name()], + ['PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), calendar_version)], + ['PACKAGE_TARNAME', meson.project_name()], + ['PACKAGE_URL', 'https://wiki.gnome.org/Apps/Calendar'], + ['PACKAGE_VERSION', calendar_version], + ['VERSION', calendar_version], + ['GETTEXT_PACKAGE', meson.project_name()] +] + +foreach define: set_defines + config_h.set_quoted(define[0], define[1]) +endforeach + +# headers +check_headers = [ + ['HAVE_DLFCN_H', 'dlfcn.h'], + ['HAVE_INTTYPES_H', 'inttypes.h'], + ['HAVE_LANGINFO_H', 'langinfo.h'], + ['HAVE_LOCALE_H', 'locale.h'], + ['HAVE_MEMORY_H', 'memory.h'], + ['HAVE_STDINT_H', 'stdint.h'], + ['HAVE_STDLIB_H', 'stdlib.h'], + ['HAVE_STRINGS_H', 'strings.h'], + ['HAVE_STRING_H', 'string.h'], + ['HAVE_SYS_STAT_H', 'sys/stat.h'], + ['HAVE_SYS_TYPES_H', 'sys/types.h'], + ['HAVE_UNISTD_H', 'unistd.h'] +] + +foreach header: check_headers + if cc.has_header(header[1]) + config_h.set(header[0], true) + endif +endforeach + +# functions +check_functions = [ + ['HAVE_DCGETTEXT', 'dcgettext'], + ['HAVE_GETTEXT', 'gettext'], + ['HAVE_FLOOR', 'floor'], + ['HAVE_ICONV', 'iconv'], + ['HAVE_MEMSET', 'memset'], + ['HAVE_NL_LANGINFO', 'nl_langinfo'], + ['HAVE_POW', 'pow'], + ['HAVE_SETLOCALE', 'setlocale'], + ['HAVE_STRSTR', 'strstr'] +] + +if host_machine.system().contains('darwin') + check_functions += [ + ['HAVE_CFLOCALECOPYCURRENT', 'CFLocaleCopyCurrent'], + ['HAVE_CFPREFERENCESCOPYAPPVALUE', 'CFPreferencesCopyAppValue'] + ] +endif + +foreach func: check_functions + if cc.has_function(func[1]) + config_h.set(func[0], true) + endif +endforeach + +assert(cc.has_function('strerror'), '"strerror" not found') + +# options +config_h.set('ENABLE_TRACING', enable_tracing) + +# _NL_TIME_FIRST_WEEKDAY is an enum and not a define +nl_time_first_weekday_src = ''' + #include + int main() { + nl_langinfo(_NL_TIME_FIRST_WEEKDAY); + }; +''' + +config_h.set('HAVE__NL_TIME_FIRST_WEEKDAY', cc.compiles(nl_time_first_weekday_src), + description: 'Define if _NL_TIME_FIRST_WEEKDAY is available') + +# Compiler flags +common_flags = [ + '-DHAVE_CONFIG_H', + '-DPACKAGE_LOCALE_DIR="@0@"'.format(calendar_localedir), + '-DPACKAGE_DATA_DIR="@0@"'.format(calendar_pkgdatadir), + '-DUI_DATA_DIR="@0@"'.format(join_paths(calendar_datadir), 'style'), + '-DEDS_DISABLE_DEPRECATED', + '-DGOA_API_IS_SUBJECT_TO_CHANGE' +] + +test_cflags = ['-Wno-sign-compare'] + +foreach cflag: test_cflags + if cc.has_argument(cflag) + common_flags += [cflag] + endif +endforeach + +if calendar_debug + common_flags += [ + '-DG_DISABLE_CAST_CHECKS' + ] +elif calendar_buildtype == 'release' + common_flags += [ + '-DG_DISABLE_ASSERT', + '-DG_DISABLE_CHECKS', + '-DG_DISABLE_CAST_CHECKS' + ] +endif + +add_project_arguments(common_flags, language: 'c') + +# dependencies +libical_dep = dependency('libical', version: '>= 1.0') +config_h.set('HAVE_LIBICAL', libical_dep.found()) + +assert(cc.has_function('icaltime_days_in_year', dependencies: libical_dep), + 'Error: icaltime_days_in_year() not found in libical!. Upgrade your libical library.') + +glib_dep = dependency('glib-2.0', version: '>= 2.43.4') +gtk_dep = dependency('gtk+-3.0', version: '>= 3.21.6') + +calendar_deps = [ + dependency('gmodule-export-2.0'), + dependency('gio-2.0', version: '>= 2.43.4'), + glib_dep, + dependency('goa-1.0', version: '>= 3.2.0'), + gtk_dep, + dependency('libecal-1.2', version: '>= 3.13.90'), + dependency('libedataserver-1.2', version: '>= 3.17.1'), + dependency('libedataserverui-1.2', version: '>= 3.17.1'), + libical_dep, + dependency('libsoup-2.4'), + dependency('gsettings-desktop-schemas', version: '>= 3.21.2'), + cc.find_library('m') +] + +configure_file( + output: 'config.h', + configuration: config_h +) + +gnome = import('gnome') +i18n = import('i18n') +pkg = import('pkgconfig') + +top_inc = include_directories('.') + +data_dir = join_paths(meson.source_root(), 'data') +po_dir = join_paths(meson.source_root(), 'po') + +subdir('data') +subdir('src') +subdir('po') + +if get_option('enable-gtk-doc') + subdir('doc/reference') +endif + +meson.add_install_script('meson_post_install.py') + +output = '\n GNOME Calendar ' + calendar_version + '\n' +output += ' =========================\n\n' +output += ' Source ........................... ' + meson.source_root() + '\n' +output += ' Prefix ........................... ' + calendar_prefix + '\n' +output += ' Compiler ......................... ' + cc.get_id() + '\n\n' +output += ' Development options\n' +output += ' Enable Debug: .................... ' + calendar_debug.to_string() + '\n' +output += ' Enable Tracing: .................. ' + enable_tracing.to_string() + '\n' +output += ' Enable Documentation: ............ ' + enable_gtk_doc.to_string() + '\n\n' +output += ' Now type "ninja -C ' + meson.build_root() + '" to build ' + meson.project_name() + '\n' +message(output) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..b8d65a56 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,2 @@ +option('enable-tracing', type: 'boolean', value: false, description: 'add extra debugging information') +option('enable-gtk-doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation') diff --git a/meson_post_install.py b/meson_post_install.py new file mode 100644 index 00000000..e1ea68c7 --- /dev/null +++ b/meson_post_install.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +import glob +import os +import re +import subprocess + +install_prefix = os.environ['MESON_INSTALL_PREFIX'] + +name_pattern = re.compile('hicolor_apps_(?:\d+x\d+|symbolic)_(.*)') +search_pattern = '/**/hicolor_*' + +icondir = os.path.join(install_prefix, 'share', 'icons', 'hicolor') +[os.rename(file, os.path.join(os.path.dirname(file), name_pattern.search(file).group(1))) + for file in glob.glob(icondir + search_pattern, recursive=True)] + +schemadir = os.path.join(install_prefix, 'share', 'glib-2.0', 'schemas') + +if not os.environ.get('DESTDIR'): + print('Update icon cache...') + subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir]) + + print('Compiling gsettings schemas...') + subprocess.call(['glib-compile-schemas', schemadir]) diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 00000000..e9b77d79 --- /dev/null +++ b/po/meson.build @@ -0,0 +1 @@ +i18n.gettext(meson.project_name(), preset: 'glib') diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..e19cb2c4 --- /dev/null +++ b/src/meson.build @@ -0,0 +1,113 @@ +src_inc = include_directories('.') + +enum_headers = files('gcal-utils.h') + +sources = files( + 'views/gcal-month-view.c', + 'views/gcal-range-tree.c', + 'views/gcal-week-grid.c', + 'views/gcal-week-header.c', + 'views/gcal-week-view.c', + 'views/gcal-year-view.c', + 'e-cal-data-model-subscriber.c', + 'e-cal-data-model.c', + 'gcal-application.c', + 'gcal-clock.c', + 'gcal-date-chooser-day.c', + 'gcal-date-chooser.c', + 'gcal-date-selector.c', + 'gcal-edit-dialog.c', + 'gcal-event-widget.c', + 'gcal-event.c', + 'gcal-log.c', + 'gcal-manager.c', + 'gcal-multi-choice.c', + 'gcal-quick-add-popover.c', + 'gcal-recurrence.c', + 'gcal-search-view.c', + 'gcal-shell-search-provider.c', + 'gcal-source-dialog.c', + 'gcal-subscriber-view.c', + 'gcal-time-selector.c', + 'gcal-utils.c', + 'gcal-view.c', + 'gcal-window.c', + 'main.c' +) + +gnome.mkenums( + 'org.gnome.calendar.enums.xml', + sources: enum_headers, + comments: '', + fhead: '', + vhead: ' <@type@ id="org.gnome.calendar.@EnumName@">', + vprod: ' ', + vtail: ' ', + ftail: '', + install_header: true, + install_dir: calendar_schemadir +) + +enum_types = 'gcal-enum-types' + +sources += gnome.mkenums( + enum_types, + sources: enum_headers, + c_template: enum_types + '.c.template', + h_template: enum_types + '.h.template' +) + +sources += gnome.compile_resources( + 'gcal-resources', + gresource, + source_dir: data_dir, + c_name: 'calendar', + dependencies: resource_data, + export: true +) + +sources += gnome.gdbus_codegen( + 'gcal-shell-search-provider-generated', + shell_search_provider_dbus_interfaces, + interface_prefix: 'org.gnome.', + namespace: 'Gcal' +) + +debug_conf = configuration_data() +debug_conf.set('BUGREPORT_URL', package_bugreport) +debug_conf.set('ENABLE_TRACING', (enable_tracing ? 1 : 0)) + +debug = 'gcal-debug.h' + +sources += configure_file( + input: debug + '.in', + output: debug, + configuration: debug_conf +) + +incs = [ + top_inc, + include_directories('views') +] + +executable( + meson.project_name(), + sources, + include_directories: incs, + dependencies: calendar_deps, + install: true, + install_dir: calendar_bindir +) + +libgcal = shared_library( + 'gcal', + sources: sources, + include_directories: incs, + dependencies: calendar_deps +) + +libgcal_dep = declare_dependency( + link_with: libgcal, + include_directories: src_inc, + dependencies: calendar_deps +)