1project(
2  'evince', ['c'],
3  version: '41.3',
4  license: 'GPL2+',
5  default_options: 'buildtype=debugoptimized',
6  meson_version: '>= 0.53.0',
7)
8
9if get_option('development')
10  app_id = 'org.gnome.Evince.Devel'
11else
12  app_id = 'org.gnome.Evince'
13endif
14
15ev_name = meson.project_name().to_lower()
16
17ev_version = meson.project_version()
18version_array = ev_version.split('.')
19ev_major_version = version_array[0].to_int()
20ev_minor_version = version_array[1]
21
22ev_prefix = get_option('prefix')
23ev_bindir = join_paths(ev_prefix, get_option('bindir'))
24ev_datadir = join_paths(ev_prefix, get_option('datadir'))
25ev_includedir = join_paths(ev_prefix, get_option('includedir'))
26ev_libdir = join_paths(ev_prefix, get_option('libdir'))
27ev_libexecdir = join_paths(ev_prefix, get_option('libexecdir'))
28ev_localedir = join_paths(ev_prefix, get_option('localedir'))
29ev_mandir = join_paths(ev_prefix, get_option('mandir'))
30
31ev_pkgdatadir = join_paths(ev_datadir, ev_name)
32
33ev_appstreamdir = join_paths(ev_datadir, 'metainfo')
34
35# Libtool versioning. The backend and view libraries have separate versions.
36# Before making a release, the libtool version should be modified.
37# The string is of the form C:R:A.
38# - If interfaces have been changed or added, but binary compatibility has
39#   been preserved, change to C+1:0:A+1
40# - If binary compatibility has been broken (eg removed or changed interfaces)
41#   change to C+1:0:0
42# - If the interface is the same as the previous version, change to C:R+1:A
43
44# Libtool version of the backend library
45ev_document_current = 4
46ev_document_revision = 0
47ev_document_age = 0
48ev_document_version = '@0@.@1@.@2@'.format(ev_document_current, ev_document_revision, ev_document_age)
49ev_document_current_minus_age = ev_document_current - ev_document_age
50
51# Libtool version of the view library
52ev_view_current = 3
53ev_view_revision = 0
54ev_view_age = 0
55ev_view_version = '@0@.@1@.@2@'.format(ev_view_current, ev_view_revision, ev_view_age)
56ev_view_current_minus_age = ev_view_current - ev_view_age
57
58ev_api_version = '3.0'
59
60ev_include_subdir = join_paths(ev_name, ev_api_version)
61
62# Backends directory
63ev_binary_version = ev_document_current
64ev_backends_binary_version = ev_binary_version
65ev_backends_subdir = join_paths(ev_name, ev_backends_binary_version.to_string(), 'backends')
66ev_backendsdir = join_paths(ev_libdir, ev_backends_subdir)
67
68ev_namespace = 'org.gnome.Evince'
69
70ev_code_prefix = 'Ev'
71
72ev_debug = get_option('buildtype').contains('debug')
73
74cc = meson.get_compiler('c')
75
76config_h = configuration_data()
77
78# package
79config_h.set_quoted('PACKAGE_ICON_NAME', app_id)
80config_h.set_quoted('PACKAGE_VERSION', ev_version)
81config_h.set_quoted('VERSION', ev_version)
82
83# i18n
84config_h.set_quoted('GETTEXT_PACKAGE', ev_name)
85config_h.set('ENABLE_NLS', true)
86
87# portability checks
88# FIXME: there is no use of backtrace in the code
89# for backtrace()
90cc.has_header('execinfo.h')
91
92# Support for nl_langinfo (_NL_MEASUREMENT_MEASUREMENT) (optional)
93langinfo_measurement_src = '''
94  #include <langinfo.h>
95  int main() {
96    char c;
97    c = *((unsigned char *)  nl_langinfo(_NL_MEASUREMENT_MEASUREMENT));
98  };
99'''
100config_h.set('HAVE__NL_MEASUREMENT_MEASUREMENT', cc.compiles(langinfo_measurement_src, name: 'Support for nl_langinfo'),
101             description: 'Define if _NL_MEASUREMENT_MEASUREMENT is available')
102
103# compiler flags
104common_flags = ['-DHAVE_CONFIG_H']
105
106common_ldflags = []
107
108if build_machine.system() == 'windows'
109  common_flags += '-D_WIN32_WINNT=0x0500'
110
111  common_ldflags = cc.get_supported_link_arguments('-mwindows')
112endif
113
114# GLib on macOS expects so as shared_module suffix, while meson uses dylib by default
115if host_machine.system() == 'darwin'
116  name_suffix = 'so'
117else
118  name_suffix = []
119endif
120
121if ev_debug
122  common_flags += ['-DEV_ENABLE_DEBUG'] + cc.get_supported_arguments([
123    '-Wnested-externs',
124    '-Wstrict-prototypes',
125    '-Werror=format=2',
126    '-Werror=implicit-function-declaration',
127    '-Werror=init-self',
128    '-Werror=missing-include-dirs',
129    '-Werror=missing-prototypes',
130    '-Werror=pointer-arith',
131    '-Werror=return-type',
132  ])
133endif
134
135add_project_arguments(common_flags, language: 'c')
136
137lib_symbol_map = join_paths(meson.current_source_dir(), 'lib-symbol.map')
138lib_ldflags = cc.get_supported_link_arguments('-Wl,--version-script,' + lib_symbol_map)
139
140gnome = import('gnome')
141i18n = import('i18n')
142pkg = import('pkgconfig')
143
144source_root = meson.current_source_dir()
145
146data_dir = join_paths(source_root, 'data')
147po_dir = join_paths(source_root, 'po')
148
149top_inc = include_directories('.')
150
151glib_req_version = '>= 2.44.0'
152gtk_req_version = '>= 3.22.0'
153hdy_req_version = '>= 1.0.0'
154
155gdk_pixbuf_dep = dependency('gdk-pixbuf-2.0', version: '>= 2.40.0')
156config_h.set_quoted('EXTRA_GDK_PIXBUF_LOADERS_DIR',
157                    join_paths (ev_libdir, ev_name, 'gdk-pixbuf', gdk_pixbuf_dep.get_pkgconfig_variable('gdk_pixbuf_binary_version')))
158
159gio_dep = dependency('gio-2.0', version: glib_req_version)
160glib_dep = dependency('glib-2.0', version: glib_req_version)
161gmodule_dep = dependency('gmodule-2.0')
162gmodule_no_export_dep = dependency('gmodule-no-export-2.0', version: glib_req_version)
163gtk_dep = dependency('gtk+-3.0', version: gtk_req_version)
164gthread_dep = dependency('gthread-2.0', version: glib_req_version)
165# Keep the version here synchronised with subprojects/libhandy.wrap
166hdy_dep = dependency('libhandy-1', version: hdy_req_version, fallback: ['libhandy', 'libhandy_dep'])
167
168m_dep = cc.find_library('m')
169
170# Although GTK+ 3.10 includes hi-dpi functionality, it does not require a cairo with
171# cairo_surface_set_device_scale(), which we also need if we're to support hi-dpi,
172# so we need check for that explicitly.
173cairo_dep = dependency('cairo', version: '>= 1.10.0')
174config_h.set('HAVE_HIDPI_SUPPORT', cc.has_function('cairo_surface_set_device_scale', dependencies: cairo_dep))
175
176# ZLIB support (required)
177zlib_dep = cc.find_library('z', required: false)
178assert(zlib_dep.found() and cc.has_function('inflate', dependencies: zlib_dep) and cc.has_function('crc32', dependencies: zlib_dep),
179      'No sufficient zlib library found on your system')
180
181ev_platform = get_option('platform')
182if ev_platform == 'gnome'
183  # Evince has a rather soft run-time dependency on hicolor-icon-theme.
184  # If the hicolor theme is not available, Evince fails to display some
185  # icons. Because we cannot check for it at run-time, we instead
186  # would like to require the icon theme at compile-time. But, because
187  # the hicolor-icon-theme does not have a pkgconfig file, on gnome we
188  # require the gnome icon theme instead.
189  adwaita_icon_theme_dep = dependency('adwaita-icon-theme', version: '>= 2.17.1')
190
191  # *** Nautilus property page build ***
192  enable_nautilus = get_option('nautilus')
193  if enable_nautilus
194    libnautilus_extension_dep = dependency('libnautilus-extension', version: '>= 3.28.0')
195    nautilus_extension_dir = libnautilus_extension_dep.get_pkgconfig_variable('extensiondir', define_variable: ['libdir', ev_libdir])
196  endif
197
198  # *** DBUS ***
199  enable_dbus = get_option('dbus')
200  if enable_dbus
201    # Check for dbus service dir
202    dbus_service_dir = dependency('dbus-1').get_pkgconfig_variable('session_bus_services_dir', define_variable: ['datadir', ev_datadir])
203    gio_unix_dep = dependency('gio-unix-2.0', version: glib_req_version)
204  endif
205  config_h.set('ENABLE_DBUS', enable_dbus)
206
207  # *** GNOME Keyring support ***
208  libsecret_dep = dependency('libsecret-1', version: '>= 0.5', required: get_option('keyring'))
209  enable_keyring = libsecret_dep.found()
210  config_h.set('WITH_KEYRING', enable_keyring)
211
212  # GKT+ Unix Printing
213  gtk_unix_print_dep = dependency('gtk+-unix-print-3.0', version: gtk_req_version, required: get_option('gtk_unix_print'))
214  enable_gtk_unix_print = gtk_unix_print_dep.found()
215  config_h.set10('GTKUNIXPRINT_ENABLED', enable_gtk_unix_print)
216else
217  message('Evince has a soft run-time dependency on hicolor-icon-theme. You are advised to have this theme installed when running Evince.')
218  enable_nautilus = false
219  enable_dbus = false
220  enable_keyring = false
221  enable_gtk_unix_print = false
222endif
223
224# *** GObject Introspection ***
225enable_introspection = get_option('introspection')
226if enable_introspection
227  dependency('gobject-introspection-1.0', version: '>= 1.0')
228endif
229
230# *** GNOME Desktop (Thumbnail cache) ***
231gnome_desktop_dep = dependency('gnome-desktop-3.0', required: get_option('thumbnail_cache'))
232enable_thumbnail_cache = gdk_pixbuf_dep.found() and gnome_desktop_dep.found()
233config_h.set('HAVE_LIBGNOME_DESKTOP', enable_thumbnail_cache)
234
235# *** GStreamer (Multimedia) ***
236gstreamer_base_dep = dependency('gstreamer-base-1.0', required: get_option('multimedia'))
237gstreamer_dep = dependency('gstreamer-1.0', required: get_option('multimedia'))
238gstreamer_video_dep = dependency('gstreamer-video-1.0', required: get_option('multimedia'))
239
240enable_multimedia = gstreamer_dep.found() and gstreamer_base_dep.found() and gstreamer_video_dep.found()
241config_h.set('ENABLE_MULTIMEDIA', enable_multimedia)
242
243# *** Gspell ***
244gspell_dep = dependency('gspell-1', version: '>= 1.6.0', required: get_option('gspell'))
245enable_gspell = gspell_dep.found()
246config_h.set10('WITH_GSPELL', enable_gspell)
247
248# *** systemd user unit dir ***
249systemd_user_unit_dir = get_option('systemduserunitdir')
250install_systemd_user_unit_dir = (systemd_user_unit_dir != 'no')
251
252if install_systemd_user_unit_dir and systemd_user_unit_dir == ''
253  systemd_user_unit_dir = join_paths(ev_prefix, 'lib', 'systemd', 'user')
254endif
255
256# *** Check for Desktop Schemas ***
257gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas', required: false)
258config_h.set('HAVE_DESKTOP_SCHEMAS', gsettings_desktop_schemas_dep.found())
259
260# *** libsynctex ***
261if get_option('internal_synctex') == 'true'
262  external_synctex = false
263else
264  synctex_dep = dependency('synctex', version: '>= 1.19', required: false)
265  external_synctex = synctex_dep.found()
266
267  if not external_synctex and get_option('internal_synctex') == 'false'
268    error('External synctex requested but not found')
269  endif
270endif
271
272# *** Mime types list ***
273mime_types_list = {
274  'comics': [
275    'application/vnd.comicbook-rar',
276    'application/vnd.comicbook+zip',
277    'application/x-cb7',
278    'application/x-cbr',
279    'application/x-cbt',
280    'application/x-cbz',
281    'application/x-ext-cb7',
282    'application/x-ext-cbr',
283    'application/x-ext-cbt',
284    'application/x-ext-cbz',
285  ],
286  'djvu': [
287    'application/x-ext-djv',
288    'application/x-ext-djvu',
289    'image/vnd.djvu+multipage',
290  ],
291  'dvi': [
292    'application/x-bzdvi',
293    'application/x-dvi',
294    'application/x-ext-dvi',
295    'application/x-gzdvi',
296  ],
297  'illustrator': [
298    'application/illustrator'
299  ],
300  'pdf': [
301    'application/pdf',
302    'application/x-bzpdf',
303    'application/x-ext-pdf',
304    'application/x-gzpdf',
305    'application/x-xzpdf',
306  ],
307  'ps': [
308    'application/postscript',
309    'application/x-bzpostscript',
310    'application/x-gzpostscript',
311    'application/x-ext-eps',
312    'application/x-ext-ps',
313    'image/x-bzeps',
314    'image/x-eps',
315    'image/x-gzeps',
316  ],
317  'tiff': [
318    'image/tiff'
319  ],
320  'xps': [
321    'application/oxps',
322    'application/vnd.ms-xpsdocument',
323  ],
324}
325
326backends = {}
327evince_mime_types = []
328
329# *** Spectre ***
330if not get_option('ps').disabled() or not get_option('dvi').disabled()
331  # libspectre (used by ps and dvi backends)
332  libspectre_req_version = '>= 0.2.0'
333  libspectre_dep = dependency('libspectre', version: libspectre_req_version, required: false)
334  config_h.set('HAVE_SPECTRE', libspectre_dep.found())
335else
336  libspectre_dep = disabler()
337endif
338
339# *** Comic Book ***
340libarchive_req_version = '>= 3.2.0'
341libarchive_dep = dependency('libarchive', version: libarchive_req_version, required: get_option('comics'))
342enable_comics = libarchive_dep.found()
343if enable_comics
344  backends += {'comics': mime_types_list.get('comics')}
345  evince_mime_types += mime_types_list.get('comics')
346elif get_option('comics').auto()
347  warning('** Comics support is disabled since libarchive (version ' + libarchive_req_version + ') is needed')
348endif
349
350# *** DJVU ***
351ddjvuapi_req_version = '>= 3.5.22'
352ddjvuapi_dep = dependency('ddjvuapi', version: ddjvuapi_req_version, required: get_option('djvu'))
353enable_djvu = ddjvuapi_dep.found()
354if enable_djvu
355  backends += {'djvu': mime_types_list.get('djvu')}
356  evince_mime_types += mime_types_list.get('djvu')
357elif get_option('djvu').auto()
358  warning('Djvu support is disabled since a recent version of the djvulibre library was not found. You need at least djvulibre ' + ddjvuapi_req_version + ' which can be found on http://djvulibre.djvuzone.org')
359endif
360
361# *** DVI ***
362kpathsea_dep = cc.find_library('kpathsea', required: get_option('dvi'))
363enable_dvi = libspectre_dep.found() and kpathsea_dep.found() and cc.has_function('kpse_init_prog', dependencies: kpathsea_dep)
364if enable_dvi
365  config_h.set10('STDC_HEADERS', true)
366
367  if not cc.has_type('size_t', prefix: '#include<sys/types.h>')
368    config_h.set('size_t', 'unsigned int')
369  endif
370
371  types = [
372    ['short', 'SHORT'],
373    ['int', 'INT'],
374    ['long', 'LONG'],
375    ['long long', 'LONG_LONG'],
376    ['void  *', 'VOID_P'],
377  ]
378
379  foreach type: types
380    config_h.set('SIZEOF_' + type[1], cc.sizeof(type[0]))
381  endforeach
382
383  t1_dep = cc.find_library('t1', required: get_option('t1lib'))
384  enable_t1lib = t1_dep.found() and cc.has_function('T1_InitLib', dependencies: t1_dep)
385  config_h.set('WITH_TYPE1_FONTS', enable_t1lib)
386
387  backends += {'dvi': mime_types_list.get('dvi')}
388  evince_mime_types += mime_types_list.get('dvi')
389elif get_option('dvi').auto()
390  warning('Dvi support is disabled since kpathsea library or libspectre are not found. Check your installation.')
391endif
392
393# *** PDF ***
394poppler_req_version = '>= 0.86.0'
395poppler_glib_dep = dependency('poppler-glib', version: poppler_req_version, required: get_option('pdf'))
396
397libxml_req_version = '>= 2.5.0'
398libxml_dep = dependency('libxml-2.0', version: libxml_req_version, required: get_option('pdf'))
399
400enable_pdf = poppler_glib_dep.found() and libxml_dep.found()
401if enable_pdf
402  cairo_pdf_dep = dependency('cairo-pdf', required: false)
403  cairo_ps_dep = dependency('cairo-ps', required: false)
404
405  backends += {'pdf': mime_types_list.get('pdf')}
406  evince_mime_types += mime_types_list.get('pdf')
407elif get_option('pdf').auto()
408  warning('PDF support is disabled since poppler-glib version ' + poppler_req_version + ' or libxml-2.0 version ' + libxml_req_version + ' not found')
409endif
410
411# *** PostScript ***
412enable_ps = not get_option('ps').disabled() and libspectre_dep.found()
413if enable_ps
414  backends += {'ps': mime_types_list.get('ps')}
415  evince_mime_types += mime_types_list.get('ps')
416elif not get_option('ps').disabled()
417  str = 'PS support is disabled since libspectre (version ' + libspectre_req_version + ') is needed'
418  if get_option('ps').auto()
419    error(str)
420  endif
421  warning(str)
422endif
423
424# *** TIFF ***
425libtiff_dep = dependency('libtiff-4', required: get_option('tiff'))
426enable_tiff = libtiff_dep.found()
427if enable_tiff
428  backends += {'tiff': mime_types_list.get('tiff')}
429  evince_mime_types += mime_types_list.get('tiff')
430elif get_option('tiff').auto()
431  warning('Tiff support is disabled since tiff library version 4.0 or newer not found')
432endif
433
434# *** XPS ***
435libgxps_req_version = '>= 0.2.1'
436libgxps_dep = dependency('libgxps', version: libgxps_req_version, required: get_option('xps'))
437enable_xps = libgxps_dep.found()
438if enable_xps
439  backends += {'xps': mime_types_list.get('xps')}
440  evince_mime_types += mime_types_list.get('xps')
441elif get_option('xps').auto()
442  warning('** XPS support is disabled since libgxps (version ' + libgxps_req_version + ') is needed')
443endif
444
445if enable_pdf and enable_ps
446  backends += {
447    'pdf': mime_types_list.get('pdf') + mime_types_list.get('illustrator'),
448    'ps': mime_types_list.get('ps') + mime_types_list.get('illustrator'),
449  }
450  evince_mime_types += mime_types_list.get('illustrator')
451endif
452
453mime_types_conf = configuration_data()
454mime_types_conf.set('EVINCE_MIME_TYPES', ';'.join(evince_mime_types))
455mime_types_conf.set('PACKAGE_ICON_NAME', app_id)
456
457subdir('cut-n-paste')
458subdir('libdocument')
459subdir('backend')
460subdir('libview')
461subdir('libmisc')
462subdir('properties')
463
464# *** Document Viewer ***
465enable_viewer = get_option('viewer')
466if enable_viewer
467  subdir('shell')
468endif
469
470subdir('po')
471subdir('help')
472
473# *** Thumbnailer ***
474enable_thumbnailer = get_option('thumbnailer')
475if enable_thumbnailer
476  subdir('thumbnailer')
477endif
478
479# Print Previewer
480enable_previewer = get_option('previewer')
481if enable_previewer
482  subdir('previewer')
483endif
484
485subdir('data')
486
487headers = files(
488  'evince-document.h',
489  'evince-view.h',
490)
491
492install_headers(
493  headers,
494  subdir: ev_include_subdir,
495)
496
497# Appdata files
498appdata = ev_namespace + '.appdata.xml'
499
500i18n.merge_file(
501  appdata,
502  input: appdata + '.in',
503  output: appdata,
504  po_dir: po_dir,
505  install: true,
506  install_dir: ev_appstreamdir,
507)
508
509configure_file(
510  output: 'config.h',
511  configuration: config_h,
512)
513
514meson.add_install_script(
515  'meson_post_install.py',
516  ev_datadir,
517)
518
519
520summary({'Platform...................': ev_platform,
521         'Debug mode.................': ev_debug,
522        }, section: 'General', bool_yn: true)
523summary({'Viewer.....................': enable_viewer,
524         'Previewer..................': enable_previewer,
525         'Thumbnailer................': enable_thumbnailer,
526         'Nautilus extension.........': enable_nautilus,
527        }, section: 'Frontends', bool_yn: true)
528summary({'Comics.....................': enable_comics,
529         'DJVU.......................': enable_djvu,
530         'DVI........................': enable_dvi,
531         'PDF........................': enable_pdf,
532         'PostScript.................': enable_ps,
533         'TIFF.......................': enable_tiff,
534         'XPS........................': enable_xps,
535        }, section: 'Backends', bool_yn: true)
536summary({'Gtk-doc reference..........': enable_gtk_doc,
537         'User documentation.........': enable_user_doc,
538         'GObject introspection......': enable_introspection,
539         'DBus communication.........': enable_dbus,
540         'Systemd units installation.': systemd_user_unit_dir,
541         'Keyring integration........': enable_keyring,
542         'GTK+ Unix print ...........': enable_gtk_unix_print,
543         'Thumbnail cache ...........': enable_thumbnail_cache,
544         'Multimedia ................': enable_multimedia,
545         'Spell checker .............': enable_gspell,
546         'SyncTex ...................': external_synctex.to_string('external', 'internal'),
547        }, section: 'Features', bool_yn: true)
548