blob: a415d394c07a668c7fb7baf51956a993af8f08a4 [file] [log] [blame]
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +00001project('fontconfig', 'c',
Akira TAGOH7861a712023-01-27 14:46:22 +09002 version: '2.14.2',
Xavier Claessens952a04a2022-09-07 09:32:31 -04003 meson_version : '>= 0.57.0',
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +00004 default_options: [ 'buildtype=debugoptimized'],
5)
6
7fc_version = meson.project_version()
8version_arr = fc_version.split('.')
9fc_version_major = version_arr[0].to_int()
10fc_version_minor = version_arr[1].to_int()
11fc_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)
16soversion = fc_version_major - 1
17curversion = fc_version_minor - 1
18libversion = '@0@.@1@.0'.format(soversion, curversion)
19defversion = '@0@.@1@'.format(curversion, fc_version_micro)
20osxversion = curversion + 1
21
22freetype_req = '>= 21.0.15'
Chun-wei Fane50fbc12020-09-29 13:50:38 +080023freetype_req_cmake = '>= 2.8.1'
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +000024
Chun-wei Fane50fbc12020-09-29 13:50:38 +080025cc = meson.get_compiler('c')
26
27
28freetype_dep = dependency('freetype2', method: 'pkg-config', version: freetype_req, required: false)
29
30# Give another shot using CMake
31if not freetype_dep.found()
32 freetype_dep = dependency('freetype', method: 'cmake', version: freetype_req_cmake,
Jason Francis1bea5462022-10-24 20:25:35 -050033 fallback: ['freetype2', 'freetype_dep'], default_options: 'werror=false')
Chun-wei Fane50fbc12020-09-29 13:50:38 +080034endif
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +000035
Jeremy Huddleston Sequoia1bc38352022-06-20 00:39:25 -070036# Linking expat should not be so difficult... see: https://github.com/mesonbuild/meson/issues/10516
37expat_dep = dependency('expat', required: false)
38if 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
43endif
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +000044
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +000045i18n = import('i18n')
46pkgmod = import('pkgconfig')
47python3 = import('python').find_installation()
48
49check_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
62check_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
85check_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
93check_header_symbols = [
94 ['posix_fadvise', 'fcntl.h']
95]
96
97check_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
105check_sizeofs = [
106 ['void *', {'conf-name': 'SIZEOF_VOID_P'}],
107]
108
109check_alignofs = [
110 ['void *', {'conf-name': 'ALIGNOF_VOID_P'}],
111 ['double'],
112]
113
114add_project_arguments('-DHAVE_CONFIG_H', language: 'c')
115
116c_args = []
117
118conf = configuration_data()
119deps = [freetype_dep, expat_dep]
120incbase = include_directories('.')
121
122# We cannot try compiling against an internal dependency
123if 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
128else
129 check_funcs += check_freetype_funcs
130endif
131
132foreach 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
138endforeach
139
140foreach 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
148endforeach
149
150foreach 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
157endforeach
158
159foreach 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
173endforeach
174
175foreach 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))
182endforeach
183
184foreach 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))
191endforeach
192
193if cc.compiles(files('meson-cc-tests/flexible-array-member-test.c'))
194 conf.set('FLEXIBLE_ARRAY_MEMBER', true)
195else
196 conf.set('FLEXIBLE_ARRAY_MEMBER', 1)
197endif
198
Alex Richardson012ffaa2021-07-12 14:57:49 +0100199if cc.links(files('meson-cc-tests/stdatomic-primitives-test.c'), name: 'stdatomic.h atomics')
200 conf.set('HAVE_STDATOMIC_PRIMITIVES', 1)
201endif
202
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000203if cc.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics')
204 conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1)
205endif
206
207if cc.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops')
208 conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1)
209endif
210
211
212prefix = get_option('prefix')
213
214fonts_conf = configuration_data()
215
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100216default_fonts_dirs = get_option('default-fonts-dirs')
217if 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']
Niklas Guertlerbc842282020-09-15 17:12:53 +0200222 else
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100223 fc_fonts_paths = ['/usr/share/fonts', '/usr/local/share/fonts']
Niklas Guertlerbc842282020-09-15 17:12:53 +0200224 endif
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100225else
226 fc_fonts_paths = default_fonts_dirs
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000227endif
Akira TAGOH10c73902021-03-03 21:25:06 +0900228xml_path = ''
229escaped_xml_path = ''
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100230foreach p : fc_fonts_paths
Akira TAGOH10c73902021-03-03 21:25:06 +0900231 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
236endforeach
237conf.set_quoted('FC_DEFAULT_FONTS', escaped_xml_path)
238fonts_conf.set('FC_DEFAULT_FONTS', xml_path)
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000239
Tim-Philipp Müller66fa47c2022-07-02 18:22:43 +0100240# 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
243fc_add_fonts = []
244additional_fonts_dirs = get_option('additional-fonts-dirs')
245if 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
252elif additional_fonts_dirs == ['no']
253 # nothing to do
254else
255 fc_add_fonts = additional_fonts_dirs
256endif
257xml_path = ''
258escaped_xml_path = ''
259foreach 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
265endforeach
266conf.set_quoted('FC_FONTPATH', escaped_xml_path)
267fonts_conf.set('FC_FONTPATH', xml_path)
268
Tim-Philipp Müller6ae56232022-07-02 18:48:10 +0100269fc_cachedir = get_option('cache-dir')
270if 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
276endif
277
278if host_machine.system() != 'windows'
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100279 thread_dep = dependency('threads')
280 conf.set('HAVE_PTHREAD', 1)
281 deps += [thread_dep]
282endif
283
Tim-Philipp Müller0c7bb302022-07-02 19:12:09 +0100284fc_templatedir = get_option('template-dir')
285if fc_templatedir in ['default', 'yes', 'no']
286 fc_templatedir = prefix / get_option('datadir') / 'fontconfig/conf.avail'
287endif
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000288
Tim-Philipp Müller0c7bb302022-07-02 19:12:09 +0100289fc_baseconfigdir = get_option('baseconfig-dir')
290if fc_baseconfigdir in ['default', 'yes', 'no']
291fc_baseconfigdir = prefix / get_option('sysconfdir') / 'fonts'
292endif
293
294fc_configdir = get_option('config-dir')
295if fc_configdir in ['default', 'yes', 'no']
296 fc_configdir = fc_baseconfigdir / 'conf.d'
297endif
298
299fc_xmldir = get_option('xml-dir')
300if fc_xmldir in ['default', 'yes', 'no']
301 fc_xmldir = prefix / get_option('datadir') / 'xml/fontconfig'
302endif
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000303
304conf.set_quoted('CONFIGDIR', fc_configdir)
305conf.set_quoted('FC_CACHEDIR', fc_cachedir)
306conf.set_quoted('FC_TEMPLATEDIR', fc_templatedir)
307conf.set_quoted('FONTCONFIG_PATH', fc_baseconfigdir)
308conf.set_quoted('FC_FONTPATH', '')
309
310fonts_conf.set('FC_FONTPATH', '')
311fonts_conf.set('FC_CACHEDIR', fc_cachedir)
312fonts_conf.set('CONFIGDIR', fc_configdir)
313# strip off fc_baseconfigdir prefix if that is the prefix
314if fc_configdir.startswith(fc_baseconfigdir + '/')
315 fonts_conf.set('CONFIGDIR', fc_configdir.split(fc_baseconfigdir + '/')[1])
316endif
317
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500318gperf = find_program('gperf', required: false)
319gperf_len_type = ''
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000320
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500321if gperf.found()
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000322 gperf_test_format = '''
323 #include <string.h>
324 const char * in_word_set(const char *, @0@);
325 @1@
326 '''
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500327 gperf_snippet = run_command(gperf, '-L', 'ANSI-C', files('meson-cc-tests/gperf.txt'),
328 check: true).stdout()
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000329
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500330 foreach type : ['size_t', 'unsigned']
331 if cc.compiles(gperf_test_format.format(type, gperf_snippet))
332 gperf_len_type = type
333 break
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000334 endif
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500335 endforeach
336
337 if gperf_len_type == ''
338 error('unable to determine gperf len type')
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000339 endif
Christopher Degawaa07e2f12022-10-25 14:41:05 -0500340else
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'
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000345endif
346
347message('gperf len type is @0@'.format(gperf_len_type))
348
349conf.set('FC_GPERF_SIZE_T', gperf_len_type,
350 description : 'The type of gperf "len" parameter')
351
352conf.set('_GNU_SOURCE', true)
353
354conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
355
356incsrc = include_directories('src')
357
358# We assume stdint.h is available
359foreach 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
363endforeach
364
365fcstdint_h = configure_file(
366 input: 'src/fcstdint.h.in',
367 output: 'fcstdint.h',
368 copy: true)
369
Tim-Philipp Müller57a224f2020-07-31 07:26:11 +0000370makealias = files('src/makealias.py')[0]
371
372alias_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
378ft_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
384tools_man_pages = []
385
386# Do not reorder
387subdir('fc-case')
388subdir('fc-lang')
389subdir('src')
390
391if 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')
401endif
402
403if not get_option('tests').disabled()
404 subdir('test')
405endif
406
407subdir('conf.d')
408subdir('its')
409
410# xgettext is optional (on Windows for instance)
411if find_program('xgettext', required : get_option('nls')).found()
412 subdir('po')
413 subdir('po-conf')
414endif
415
416if not get_option('doc').disabled()
417 subdir('doc')
418endif
419
420configure_file(output: 'config.h', configuration: conf)
421
422configure_file(output: 'fonts.conf',
423 input: 'fonts.conf.in',
424 configuration: fonts_conf,
425 install_dir: fc_baseconfigdir,
426 install: true)
427
428install_data('fonts.dtd',
429 install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'xml/fontconfig')
430)
431
432fc_headers = [
433 'fontconfig/fontconfig.h',
434 'fontconfig/fcfreetype.h',
435 'fontconfig/fcprivate.h',
436]
437
438install_headers(fc_headers, subdir: meson.project_name())
439
Tim-Philipp Müllera5fd5dc2020-07-31 15:15:07 +0100440# Summary
Nirbheek Chauhan7b09c812022-01-09 17:04:25 +0530441doc_targets = get_variable('doc_targets', [])
Tim-Philipp Müllera5fd5dc2020-07-31 15:15:07 +0100442
Nirbheek Chauhan7b09c812022-01-09 17:04:25 +0530443summary({
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: ', ')
Tim-Philipp Müller56a24872022-07-02 17:05:47 +0100449summary({
Tim-Philipp Müller0d8d75e2022-07-02 17:30:27 +0100450 'Hinting': preferred_hinting,
451 'Font directories': fc_fonts_paths,
Tim-Philipp Müller66fa47c2022-07-02 18:22:43 +0100452 'Additional font directories': fc_add_fonts,
Tim-Philipp Müller56a24872022-07-02 17:05:47 +0100453 }, section: 'Defaults', bool_yn: true, list_sep: ', ')
Tim-Philipp Müller6ae56232022-07-02 18:48:10 +0100454summary({
455 'Cache directory': fc_cachedir,
Tim-Philipp Müller0c7bb302022-07-02 19:12:09 +0100456 'Template directory': fc_templatedir,
457 'Base config directory': fc_baseconfigdir,
458 'Config directory': fc_configdir,
459 'XML directory': fc_xmldir,
Tim-Philipp Müller6ae56232022-07-02 18:48:10 +0100460 }, section: 'Paths', bool_yn: true, list_sep: ', ')