meson.build revision a4e54154
1project('fontconfig', 'c', 2 version: '2.14.0', 3 meson_version : '>= 0.56.0', 4 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' 23freetype_req_cmake = '>= 2.8.1' 24 25cc = 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, 33 fallback: ['freetype2', 'freetype_dep']) 34endif 35 36expat_dep = dependency('expat', 37 fallback: ['expat', 'expat_dep']) 38 39i18n = import('i18n') 40pkgmod = import('pkgconfig') 41python3 = import('python').find_installation() 42 43check_headers = [ 44 ['dirent.h'], 45 ['fcntl.h'], 46 ['stdlib.h'], 47 ['string.h'], 48 ['unistd.h'], 49 ['sys/statvfs.h'], 50 ['sys/vfs.h'], 51 ['sys/statfs.h'], 52 ['sys/param.h'], 53 ['sys/mount.h'], 54] 55 56check_funcs = [ 57 ['link'], 58 ['mkstemp'], 59 ['mkostemp'], 60 ['_mktemp_s'], 61 ['mkdtemp'], 62 ['getopt'], 63 ['getopt_long'], 64 ['getprogname'], 65 ['getexecname'], 66 ['rand'], 67 ['random'], 68 ['lrand48'], 69 ['random_r'], 70 ['rand_r'], 71 ['readlink'], 72 ['fstatvfs'], 73 ['fstatfs'], 74 ['lstat'], 75 ['mmap'], 76 ['vprintf'], 77] 78 79check_freetype_funcs = [ 80 ['FT_Get_BDF_Property', {'dependencies': freetype_dep}], 81 ['FT_Get_PS_Font_Info', {'dependencies': freetype_dep}], 82 ['FT_Has_PS_Glyph_Names', {'dependencies': freetype_dep}], 83 ['FT_Get_X11_Font_Format', {'dependencies': freetype_dep}], 84 ['FT_Done_MM_Var', {'dependencies': freetype_dep}], 85] 86 87check_header_symbols = [ 88 ['posix_fadvise', 'fcntl.h'] 89] 90 91check_struct_members = [ 92 ['struct statvfs', 'f_basetype', ['sys/statvfs.h']], 93 ['struct statvfs', 'f_fstypename', ['sys/statvfs.']], 94 ['struct statfs', 'f_flags', []], 95 ['struct statfs', 'f_fstypename', []], 96 ['struct dirent', 'd_type', ['sys/types.h', 'dirent.h']], 97] 98 99check_sizeofs = [ 100 ['void *', {'conf-name': 'SIZEOF_VOID_P'}], 101] 102 103check_alignofs = [ 104 ['void *', {'conf-name': 'ALIGNOF_VOID_P'}], 105 ['double'], 106] 107 108add_project_arguments('-DHAVE_CONFIG_H', language: 'c') 109 110c_args = [] 111 112conf = configuration_data() 113deps = [freetype_dep, expat_dep] 114incbase = include_directories('.') 115 116# We cannot try compiling against an internal dependency 117if freetype_dep.type_name() == 'internal' 118 foreach func: check_freetype_funcs 119 name = func[0] 120 conf.set('HAVE_@0@'.format(name.to_upper()), 1) 121 endforeach 122else 123 check_funcs += check_freetype_funcs 124endif 125 126foreach check : check_headers 127 name = check[0] 128 129 if cc.has_header(name) 130 conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1) 131 endif 132endforeach 133 134foreach check : check_funcs 135 name = check[0] 136 opts = check.length() > 1 ? check[1] : {} 137 extra_deps = opts.get('dependencies', []) 138 139 if cc.has_function(name, dependencies: extra_deps) 140 conf.set('HAVE_@0@'.format(name.to_upper()), 1) 141 endif 142endforeach 143 144foreach check : check_header_symbols 145 name = check[0] 146 header = check[1] 147 148 if cc.has_header_symbol(header, name) 149 conf.set('HAVE_@0@'.format(name.to_upper()), 1) 150 endif 151endforeach 152 153foreach check : check_struct_members 154 struct_name = check[0] 155 member_name = check[1] 156 headers = check[2] 157 158 prefix = '' 159 160 foreach header : headers 161 prefix += '#include <@0@>\n'.format(header) 162 endforeach 163 164 if cc.has_member(struct_name, member_name, prefix: prefix) 165 conf.set('HAVE_@0@_@1@'.format(struct_name, member_name).to_upper().underscorify(), 1) 166 endif 167endforeach 168 169foreach check : check_sizeofs 170 type = check[0] 171 opts = check.length() > 1 ? check[1] : {} 172 173 conf_name = opts.get('conf-name', 'SIZEOF_@0@'.format(type.to_upper())) 174 175 conf.set(conf_name, cc.sizeof(type)) 176endforeach 177 178foreach check : check_alignofs 179 type = check[0] 180 opts = check.length() > 1 ? check[1] : {} 181 182 conf_name = opts.get('conf-name', 'ALIGNOF_@0@'.format(type.to_upper())) 183 184 conf.set(conf_name, cc.alignment(type)) 185endforeach 186 187if cc.compiles(files('meson-cc-tests/flexible-array-member-test.c')) 188 conf.set('FLEXIBLE_ARRAY_MEMBER', true) 189else 190 conf.set('FLEXIBLE_ARRAY_MEMBER', 1) 191endif 192 193if cc.links(files('meson-cc-tests/stdatomic-primitives-test.c'), name: 'stdatomic.h atomics') 194 conf.set('HAVE_STDATOMIC_PRIMITIVES', 1) 195endif 196 197if cc.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics') 198 conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1) 199endif 200 201if cc.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops') 202 conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1) 203endif 204 205 206prefix = get_option('prefix') 207 208fonts_conf = configuration_data() 209 210if host_machine.system() == 'windows' 211 fc_fonts_path = ['WINDOWSFONTDIR', 'WINDOWSUSERFONTDIR'] 212 fc_cachedir = 'LOCAL_APPDATA_FONTCONFIG_CACHE' 213else 214 if host_machine.system() == 'darwin' 215 fc_fonts_path = ['/System/Library/Fonts', '/Library/Fonts', '~/Library/Fonts', '/System/Library/Assets/com_apple_MobileAsset_Font3', '/System/Library/Assets/com_apple_MobileAsset_Font4'] 216 else 217 fc_fonts_path = ['/usr/share/fonts', '/usr/local/share/fonts'] 218 endif 219 fc_cachedir = join_paths(prefix, get_option('localstatedir'), 'cache', meson.project_name()) 220 thread_dep = dependency('threads') 221 conf.set('HAVE_PTHREAD', 1) 222 deps += [thread_dep] 223endif 224xml_path = '' 225escaped_xml_path = '' 226foreach p : fc_fonts_path 227 s = '\t<dir>' + p + '</dir>\n' 228 xml_path += s 229 # No substitution method for string 230 s = '\\t<dir>' + p + '</dir>\\n' 231 escaped_xml_path += s 232endforeach 233conf.set_quoted('FC_DEFAULT_FONTS', escaped_xml_path) 234fonts_conf.set('FC_DEFAULT_FONTS', xml_path) 235 236fc_templatedir = join_paths(prefix, get_option('datadir'), 'fontconfig/conf.avail') 237fc_baseconfigdir = join_paths(prefix, get_option('sysconfdir'), 'fonts') 238fc_configdir = join_paths(fc_baseconfigdir, 'conf.d') 239fc_xmldir = join_paths(prefix, get_option('datadir'), 'xml/fontconfig') 240 241 242conf.set_quoted('CONFIGDIR', fc_configdir) 243conf.set_quoted('FC_CACHEDIR', fc_cachedir) 244conf.set_quoted('FC_TEMPLATEDIR', fc_templatedir) 245conf.set_quoted('FONTCONFIG_PATH', fc_baseconfigdir) 246conf.set_quoted('FC_FONTPATH', '') 247 248fonts_conf.set('FC_FONTPATH', '') 249fonts_conf.set('FC_CACHEDIR', fc_cachedir) 250fonts_conf.set('CONFIGDIR', fc_configdir) 251# strip off fc_baseconfigdir prefix if that is the prefix 252if fc_configdir.startswith(fc_baseconfigdir + '/') 253 fonts_conf.set('CONFIGDIR', fc_configdir.split(fc_baseconfigdir + '/')[1]) 254endif 255 256# It will automatically fallback to subproject if not found on system 257gperf = find_program('gperf') 258 259sh = find_program('sh', required : false) 260 261if not sh.found() # host_machine.system() == 'windows' or not sh.found() 262 # TODO: This is not always correct 263 if cc.get_id() == 'msvc' 264 gperf_len_type = 'size_t' 265 else 266 gperf_len_type = 'unsigned' 267 endif 268else 269 gperf_test_format = ''' 270 #include <string.h> 271 const char * in_word_set(const char *, @0@); 272 @1@ 273 ''' 274 gperf_snippet_format = 'echo foo,bar | @0@ -L ANSI-C' 275 gperf_snippet = run_command(sh, '-c', gperf_snippet_format.format(gperf.path())) 276 gperf_test = gperf_test_format.format('size_t', gperf_snippet.stdout()) 277 278 if cc.compiles(gperf_test) 279 gperf_len_type = 'size_t' 280 else 281 gperf_test = gperf_test_format.format('unsigned', gperf_snippet.stdout()) 282 if cc.compiles(gperf_test) 283 gperf_len_type = 'unsigned' 284 else 285 error('unable to determine gperf len type') 286 endif 287 endif 288endif 289 290message('gperf len type is @0@'.format(gperf_len_type)) 291 292conf.set('FC_GPERF_SIZE_T', gperf_len_type, 293 description : 'The type of gperf "len" parameter') 294 295conf.set('_GNU_SOURCE', true) 296 297conf.set_quoted('GETTEXT_PACKAGE', meson.project_name()) 298 299incsrc = include_directories('src') 300 301# We assume stdint.h is available 302foreach t : ['uint64_t', 'int32_t', 'uintptr_t', 'intptr_t'] 303 if not cc.has_type(t, prefix: '#include <stdint.h>') 304 error('Sanity check failed: type @0@ not provided via stdint.h'.format(t)) 305 endif 306endforeach 307 308fcstdint_h = configure_file( 309 input: 'src/fcstdint.h.in', 310 output: 'fcstdint.h', 311 copy: true) 312 313makealias = files('src/makealias.py')[0] 314 315alias_headers = custom_target('alias_headers', 316 output: ['fcalias.h', 'fcaliastail.h'], 317 input: ['fontconfig/fontconfig.h', 'src/fcdeprecate.h', 'fontconfig/fcprivate.h'], 318 command: [python3, makealias, join_paths(meson.current_source_dir(), 'src'), '@OUTPUT@', '@INPUT@'], 319) 320 321ft_alias_headers = custom_target('ft_alias_headers', 322 output: ['fcftalias.h', 'fcftaliastail.h'], 323 input: ['fontconfig/fcfreetype.h'], 324 command: [python3, makealias, join_paths(meson.current_source_dir(), 'src'), '@OUTPUT@', '@INPUT@'] 325) 326 327tools_man_pages = [] 328 329# Do not reorder 330subdir('fc-case') 331subdir('fc-lang') 332subdir('src') 333 334if not get_option('tools').disabled() 335 subdir('fc-cache') 336 subdir('fc-cat') 337 subdir('fc-conflist') 338 subdir('fc-list') 339 subdir('fc-match') 340 subdir('fc-pattern') 341 subdir('fc-query') 342 subdir('fc-scan') 343 subdir('fc-validate') 344endif 345 346if not get_option('tests').disabled() 347 subdir('test') 348endif 349 350subdir('conf.d') 351subdir('its') 352 353# xgettext is optional (on Windows for instance) 354if find_program('xgettext', required : get_option('nls')).found() 355 subdir('po') 356 subdir('po-conf') 357endif 358 359if not get_option('doc').disabled() 360 subdir('doc') 361endif 362 363configure_file(output: 'config.h', configuration: conf) 364 365configure_file(output: 'fonts.conf', 366 input: 'fonts.conf.in', 367 configuration: fonts_conf, 368 install_dir: fc_baseconfigdir, 369 install: true) 370 371install_data('fonts.dtd', 372 install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'xml/fontconfig') 373) 374 375fc_headers = [ 376 'fontconfig/fontconfig.h', 377 'fontconfig/fcfreetype.h', 378 'fontconfig/fcprivate.h', 379] 380 381install_headers(fc_headers, subdir: meson.project_name()) 382 383# Summary 384doc_targets = get_variable('doc_targets', []) 385 386summary({ 387 'Documentation': (doc_targets.length() > 0 ? doc_targets : false), 388 'NLS': not get_option('nls').disabled(), 389 'Tests': not get_option('tests').disabled(), 390 'Tools': not get_option('tools').disabled(), 391 }, section: 'General', bool_yn: true, list_sep: ', ') 392