upgrade to 2.14.2
[platform/upstream/fontconfig.git] / meson.build
1 project('fontconfig', 'c',
2   version: '2.14.2',
3   meson_version : '>= 0.57.0',
4   default_options: [ 'buildtype=debugoptimized'],
5 )
6
7 fc_version = meson.project_version()
8 version_arr = fc_version.split('.')
9 fc_version_major = version_arr[0].to_int()
10 fc_version_minor = version_arr[1].to_int()
11 fc_version_micro = version_arr[2].to_int()
12
13 # Try and maintain compatibility with the previous libtool versioning
14 # (this is a bit of a hack, but it should work fine for our case where
15 # API is added, in which case LT_AGE and LIBT_CURRENT are both increased)
16 soversion = fc_version_major - 1
17 curversion = fc_version_minor - 1
18 libversion = '@0@.@1@.0'.format(soversion, curversion)
19 defversion = '@0@.@1@'.format(curversion, fc_version_micro)
20 osxversion = curversion + 1
21
22 freetype_req = '>= 21.0.15'
23 freetype_req_cmake = '>= 2.8.1'
24
25 cc = meson.get_compiler('c')
26
27
28 freetype_dep = dependency('freetype2', method: 'pkg-config', version: freetype_req, required: false)
29
30 # Give another shot using CMake
31 if not freetype_dep.found()
32   freetype_dep = dependency('freetype', method: 'cmake', version: freetype_req_cmake,
33     fallback: ['freetype2', 'freetype_dep'], default_options: 'werror=false')
34 endif
35
36 # Linking expat should not be so difficult... see: https://github.com/mesonbuild/meson/issues/10516
37 expat_dep = dependency('expat', required: false)
38 if not expat_dep.found()
39   expat_dep = cc.find_library('expat', required : false)
40   if not expat_dep.found()
41     expat_dep = dependency('expat', method: 'system', fallback: ['expat', 'expat_dep'])
42   endif
43 endif
44
45 i18n = import('i18n')
46 pkgmod = import('pkgconfig')
47 python3 = import('python').find_installation()
48
49 check_headers = [
50   ['dirent.h'],
51   ['fcntl.h'],
52   ['stdlib.h'],
53   ['string.h'],
54   ['unistd.h'],
55   ['sys/statvfs.h'],
56   ['sys/vfs.h'],
57   ['sys/statfs.h'],
58   ['sys/param.h'],
59   ['sys/mount.h'],
60 ]
61
62 check_funcs = [
63   ['link'],
64   ['mkstemp'],
65   ['mkostemp'],
66   ['_mktemp_s'],
67   ['mkdtemp'],
68   ['getopt'],
69   ['getopt_long'],
70   ['getprogname'],
71   ['getexecname'],
72   ['rand'],
73   ['random'],
74   ['lrand48'],
75   ['random_r'],
76   ['rand_r'],
77   ['readlink'],
78   ['fstatvfs'],
79   ['fstatfs'],
80   ['lstat'],
81   ['mmap'],
82   ['vprintf'],
83 ]
84
85 check_freetype_funcs = [
86   ['FT_Get_BDF_Property', {'dependencies': freetype_dep}],
87   ['FT_Get_PS_Font_Info', {'dependencies': freetype_dep}],
88   ['FT_Has_PS_Glyph_Names', {'dependencies': freetype_dep}],
89   ['FT_Get_X11_Font_Format', {'dependencies': freetype_dep}],
90   ['FT_Done_MM_Var', {'dependencies': freetype_dep}],
91 ]
92
93 check_header_symbols = [
94   ['posix_fadvise', 'fcntl.h']
95 ]
96
97 check_struct_members = [
98   ['struct statvfs', 'f_basetype', ['sys/statvfs.h']],
99   ['struct statvfs', 'f_fstypename', ['sys/statvfs.']],
100   ['struct statfs', 'f_flags', []],
101   ['struct statfs', 'f_fstypename', []],
102   ['struct dirent', 'd_type', ['sys/types.h', 'dirent.h']],
103 ]
104
105 check_sizeofs = [
106   ['void *', {'conf-name': 'SIZEOF_VOID_P'}],
107 ]
108
109 check_alignofs = [
110   ['void *', {'conf-name': 'ALIGNOF_VOID_P'}],
111   ['double'],
112 ]
113
114 add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
115
116 c_args = []
117
118 conf = configuration_data()
119 deps = [freetype_dep, expat_dep]
120 incbase = include_directories('.')
121
122 # We cannot try compiling against an internal dependency
123 if freetype_dep.type_name() == 'internal'
124   foreach func: check_freetype_funcs
125     name = func[0]
126     conf.set('HAVE_@0@'.format(name.to_upper()), 1)
127   endforeach
128 else
129   check_funcs += check_freetype_funcs
130 endif
131
132 foreach check : check_headers
133   name = check[0]
134
135   if cc.has_header(name)
136     conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1)
137   endif
138 endforeach
139
140 foreach check : check_funcs
141   name = check[0]
142   opts = check.length() > 1 ? check[1] : {}
143   extra_deps = opts.get('dependencies', [])
144
145   if cc.has_function(name, dependencies: extra_deps)
146     conf.set('HAVE_@0@'.format(name.to_upper()), 1)
147   endif
148 endforeach
149
150 foreach check : check_header_symbols
151   name = check[0]
152   header = check[1]
153
154   if cc.has_header_symbol(header, name)
155     conf.set('HAVE_@0@'.format(name.to_upper()), 1)
156   endif
157 endforeach
158
159 foreach check : check_struct_members
160   struct_name = check[0]
161   member_name = check[1]
162   headers = check[2]
163
164   prefix = ''
165
166   foreach header : headers
167     prefix += '#include <@0@>\n'.format(header)
168   endforeach
169
170   if cc.has_member(struct_name, member_name, prefix: prefix)
171     conf.set('HAVE_@0@_@1@'.format(struct_name, member_name).to_upper().underscorify(), 1)
172   endif
173 endforeach
174
175 foreach check : check_sizeofs
176   type = check[0]
177   opts = check.length() > 1 ? check[1] : {}
178
179   conf_name = opts.get('conf-name', 'SIZEOF_@0@'.format(type.to_upper()))
180
181   conf.set(conf_name, cc.sizeof(type))
182 endforeach
183
184 foreach check : check_alignofs
185   type = check[0]
186   opts = check.length() > 1 ? check[1] : {}
187
188   conf_name = opts.get('conf-name', 'ALIGNOF_@0@'.format(type.to_upper()))
189
190   conf.set(conf_name, cc.alignment(type))
191 endforeach
192
193 if cc.compiles(files('meson-cc-tests/flexible-array-member-test.c'))
194   conf.set('FLEXIBLE_ARRAY_MEMBER', true)
195 else
196   conf.set('FLEXIBLE_ARRAY_MEMBER', 1)
197 endif
198
199 if cc.links(files('meson-cc-tests/stdatomic-primitives-test.c'), name: 'stdatomic.h atomics')
200   conf.set('HAVE_STDATOMIC_PRIMITIVES', 1)
201 endif
202
203 if cc.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics')
204   conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1)
205 endif
206
207 if cc.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops')
208   conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1)
209 endif
210
211
212 prefix = get_option('prefix')
213
214 fonts_conf = configuration_data()
215
216 default_fonts_dirs = get_option('default-fonts-dirs')
217 if default_fonts_dirs == ['yes']
218   if host_machine.system() == 'windows'
219     fc_fonts_paths = ['WINDOWSFONTDIR', 'WINDOWSUSERFONTDIR']
220   elif host_machine.system() == 'darwin'
221     fc_fonts_paths = ['/System/Library/Fonts', '/Library/Fonts', '~/Library/Fonts', '/System/Library/Assets/com_apple_MobileAsset_Font3', '/System/Library/Assets/com_apple_MobileAsset_Font4']
222   else
223     fc_fonts_paths = ['/usr/share/fonts', '/usr/local/share/fonts']
224   endif
225 else
226   fc_fonts_paths = default_fonts_dirs
227 endif
228 xml_path = ''
229 escaped_xml_path = ''
230 foreach p : fc_fonts_paths
231   s = '\t<dir>' + p + '</dir>\n'
232   xml_path += s
233   # No substitution method for string
234   s = '\\t<dir>' + p + '</dir>\\n'
235   escaped_xml_path += s
236 endforeach
237 conf.set_quoted('FC_DEFAULT_FONTS', escaped_xml_path)
238 fonts_conf.set('FC_DEFAULT_FONTS', xml_path)
239
240 # Add more fonts if available.  By default, add only the directories
241 # with outline fonts; those with bitmaps can be added as desired in
242 # local.conf or ~/.fonts.conf
243 fc_add_fonts = []
244 additional_fonts_dirs = get_option('additional-fonts-dirs')
245 if additional_fonts_dirs == ['yes']
246   fs = import('fs')
247   foreach dir : ['/usr/X11R6/lib/X11', '/usr/X11/lib/X11', '/usr/lib/X11']
248     if fs.is_dir(dir / 'fonts')
249       fc_add_fonts += [dir / 'fonts']
250     endif
251   endforeach
252 elif additional_fonts_dirs == ['no']
253   # nothing to do
254 else
255   fc_add_fonts = additional_fonts_dirs
256 endif
257 xml_path = ''
258 escaped_xml_path = ''
259 foreach p : fc_add_fonts
260   s = '\t<dir>' + p + '</dir>\n'
261   xml_path += s
262   # No substitution method for string
263   s = '\\t<dir>' + p + '</dir>\\n'
264   escaped_xml_path += s
265 endforeach
266 conf.set_quoted('FC_FONTPATH', escaped_xml_path)
267 fonts_conf.set('FC_FONTPATH', xml_path)
268
269 fc_cachedir = get_option('cache-dir')
270 if fc_cachedir in ['yes', 'no', 'default']
271   if host_machine.system() == 'windows'
272     fc_cachedir = 'LOCAL_APPDATA_FONTCONFIG_CACHE'
273   else
274     fc_cachedir = join_paths(prefix, get_option('localstatedir'), 'cache', meson.project_name())
275   endif
276 endif
277
278 if host_machine.system() != 'windows'
279   thread_dep = dependency('threads')
280   conf.set('HAVE_PTHREAD', 1)
281   deps += [thread_dep]
282 endif
283
284 fc_templatedir = get_option('template-dir')
285 if fc_templatedir in ['default', 'yes', 'no']
286   fc_templatedir = prefix / get_option('datadir') / 'fontconfig/conf.avail'
287 endif
288
289 fc_baseconfigdir = get_option('baseconfig-dir')
290 if fc_baseconfigdir in ['default', 'yes', 'no']
291 fc_baseconfigdir = prefix / get_option('sysconfdir') / 'fonts'
292 endif
293
294 fc_configdir = get_option('config-dir')
295 if fc_configdir in ['default', 'yes', 'no']
296   fc_configdir = fc_baseconfigdir / 'conf.d'
297 endif
298
299 fc_xmldir = get_option('xml-dir')
300 if fc_xmldir in ['default', 'yes', 'no']
301   fc_xmldir = prefix / get_option('datadir') / 'xml/fontconfig'
302 endif
303
304 conf.set_quoted('CONFIGDIR', fc_configdir)
305 conf.set_quoted('FC_CACHEDIR', fc_cachedir)
306 conf.set_quoted('FC_TEMPLATEDIR', fc_templatedir)
307 conf.set_quoted('FONTCONFIG_PATH', fc_baseconfigdir)
308 conf.set_quoted('FC_FONTPATH', '')
309
310 fonts_conf.set('FC_FONTPATH', '')
311 fonts_conf.set('FC_CACHEDIR', fc_cachedir)
312 fonts_conf.set('CONFIGDIR', fc_configdir)
313 # strip off fc_baseconfigdir prefix if that is the prefix
314 if fc_configdir.startswith(fc_baseconfigdir + '/')
315   fonts_conf.set('CONFIGDIR', fc_configdir.split(fc_baseconfigdir + '/')[1])
316 endif
317
318 gperf = find_program('gperf', required: false)
319 gperf_len_type = ''
320
321 if gperf.found()
322   gperf_test_format = '''
323   #include <string.h>
324   const char * in_word_set(const char *, @0@);
325   @1@
326   '''
327   gperf_snippet = run_command(gperf, '-L', 'ANSI-C', files('meson-cc-tests/gperf.txt'),
328     check: true).stdout()
329
330   foreach type : ['size_t', 'unsigned']
331     if cc.compiles(gperf_test_format.format(type, gperf_snippet))
332       gperf_len_type = type
333       break
334     endif
335   endforeach
336
337   if gperf_len_type == ''
338     error('unable to determine gperf len type')
339   endif
340 else
341   # Fallback to subproject
342   gperf = find_program('gperf')
343   # assume if we are compiling from the wrap, the size is just size_t
344   gperf_len_type = 'size_t'
345 endif
346
347 message('gperf len type is @0@'.format(gperf_len_type))
348
349 conf.set('FC_GPERF_SIZE_T', gperf_len_type,
350   description : 'The type of gperf "len" parameter')
351
352 conf.set('_GNU_SOURCE', true)
353
354 conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
355
356 incsrc = include_directories('src')
357
358 # We assume stdint.h is available
359 foreach t : ['uint64_t', 'int32_t', 'uintptr_t', 'intptr_t']
360   if not cc.has_type(t, prefix: '#include <stdint.h>')
361     error('Sanity check failed: type @0@ not provided via stdint.h'.format(t))
362   endif
363 endforeach
364
365 fcstdint_h = configure_file(
366   input: 'src/fcstdint.h.in',
367   output: 'fcstdint.h',
368   copy: true)
369
370 makealias = files('src/makealias.py')[0]
371
372 alias_headers = custom_target('alias_headers',
373   output: ['fcalias.h', 'fcaliastail.h'],
374   input: ['fontconfig/fontconfig.h', 'src/fcdeprecate.h', 'fontconfig/fcprivate.h'],
375   command: [python3, makealias, join_paths(meson.current_source_dir(), 'src'), '@OUTPUT@', '@INPUT@'],
376 )
377
378 ft_alias_headers = custom_target('ft_alias_headers',
379   output: ['fcftalias.h', 'fcftaliastail.h'],
380   input: ['fontconfig/fcfreetype.h'],
381   command: [python3, makealias, join_paths(meson.current_source_dir(), 'src'), '@OUTPUT@', '@INPUT@']
382 )
383
384 tools_man_pages = []
385
386 # Do not reorder
387 subdir('fc-case')
388 subdir('fc-lang')
389 subdir('src')
390
391 if not get_option('tools').disabled()
392   subdir('fc-cache')
393   subdir('fc-cat')
394   subdir('fc-conflist')
395   subdir('fc-list')
396   subdir('fc-match')
397   subdir('fc-pattern')
398   subdir('fc-query')
399   subdir('fc-scan')
400   subdir('fc-validate')
401 endif
402
403 if not get_option('tests').disabled()
404   subdir('test')
405 endif
406
407 subdir('conf.d')
408 subdir('its')
409
410 # xgettext is optional (on Windows for instance)
411 if find_program('xgettext', required : get_option('nls')).found()
412   subdir('po')
413   subdir('po-conf')
414 endif
415
416 if not get_option('doc').disabled()
417   subdir('doc')
418 endif
419
420 configure_file(output: 'config.h', configuration: conf)
421
422 configure_file(output: 'fonts.conf',
423   input: 'fonts.conf.in',
424   configuration: fonts_conf,
425   install_dir: fc_baseconfigdir,
426   install: true)
427
428 install_data('fonts.dtd',
429   install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'xml/fontconfig')
430 )
431
432 fc_headers = [
433   'fontconfig/fontconfig.h',
434   'fontconfig/fcfreetype.h',
435   'fontconfig/fcprivate.h',
436 ]
437
438 install_headers(fc_headers, subdir: meson.project_name())
439
440 # Summary
441 doc_targets = get_variable('doc_targets', [])
442
443 summary({
444        'Documentation': (doc_targets.length() > 0 ? doc_targets : false),
445        'NLS': not get_option('nls').disabled(),
446        'Tests': not get_option('tests').disabled(),
447        'Tools': not get_option('tools').disabled(),
448        }, section: 'General', bool_yn: true, list_sep: ', ')
449 summary({
450        'Hinting': preferred_hinting,
451        'Font directories': fc_fonts_paths,
452        'Additional font directories': fc_add_fonts,
453        }, section: 'Defaults', bool_yn: true, list_sep: ', ')
454 summary({
455        'Cache directory': fc_cachedir,
456        'Template directory': fc_templatedir,
457        'Base config directory': fc_baseconfigdir,
458        'Config directory': fc_configdir,
459        'XML directory': fc_xmldir,
460        }, section: 'Paths', bool_yn: true, list_sep: ', ')