1project('igt-gpu-tools', 'c', 2 version : '1.24', 3 default_options: [ 4 'warning_level=2', 5 'c_std=gnu11', 6 'b_ndebug=false', 7 'buildtype=debugoptimized', 8 ], 9 license : 'MIT', 10 meson_version : '>=0.47.0') 11 12if get_option('b_ndebug') != 'false' 13 error('Building without -Db_ndebug=false is not supported') 14endif 15 16cc = meson.get_compiler('c') 17 18# Also make sure that the user doesn't have -DNDEBUG defined in their config 19if not cc.compiles(files('lib/check-ndebug.h'), args: get_option('c_args')) 20 error('Building with NDEBUG defined is not supported') 21endif 22 23cc_args = [ 24 '-Wbad-function-cast', 25 '-Wdeclaration-after-statement', 26 '-Wformat=2', 27# igt_assert(0) in switch statements triggers a bunch of this. 28 '-Wimplicit-fallthrough=0', 29 '-Wlogical-op', 30 '-Wmissing-declarations', 31 '-Wmissing-format-attribute', 32 '-Wmissing-noreturn', 33 '-Wmissing-prototypes', 34 '-Wnested-externs', 35 '-Wold-style-definition', 36 '-Wpointer-arith', 37 '-Wredundant-decls', 38 '-Wshadow', 39 '-Wstrict-prototypes', 40 '-Wuninitialized', 41 '-Wunused', 42 43 '-Wno-clobbered', 44 '-Wno-maybe-uninitialized', 45 '-Wno-missing-field-initializers', 46 '-Wno-pointer-arith', 47 '-Wno-sign-compare', 48# Macros asserting on the range of their arguments triggers this. 49 '-Wno-type-limits', 50 '-Wno-unused-parameter', 51 '-Wno-unused-result', 52 53 '-Werror=address', 54 '-Werror=array-bounds', 55 '-Werror=implicit', 56 '-Werror=init-self', 57 '-Werror=int-to-pointer-cast', 58 '-Werror=main', 59 '-Werror=missing-braces', 60 '-Werror=nonnull', 61 '-Werror=pointer-to-int-cast', 62 '-Werror=return-type', 63 '-Werror=sequence-point', 64 '-Werror=trigraphs', 65 '-Werror=write-strings', 66# Disable the memory allocating builtins as they may cause unexpected behavior 67# with our framework. They *may* get optimized out in favor of a register or 68# stack variable, making them effectively local. Local variables do not play 69# well with longjmp which is heavily used by IGT framework. 70 '-fno-builtin-malloc', 71 '-fno-builtin-calloc', 72] 73 74foreach cc_arg : cc_args 75 if cc.has_argument(cc_arg) 76 add_global_arguments(cc_arg, language : 'c') 77 endif 78endforeach 79 80build_chamelium = get_option('chamelium') 81build_docs = get_option('docs') 82build_tests = not get_option('tests').disabled() 83with_libdrm = get_option('libdrm_drivers') 84 85build_info = ['Build type: ' + get_option('buildtype')] 86 87inc = include_directories('include/drm-uapi', 'lib', 'lib/stubs/syscalls', '.') 88 89inc_for_gtkdoc = include_directories('lib') 90 91config = configuration_data() 92 93null_dep = dependency('', required : false) 94 95libdrm_info = [] 96libdrm_intel = null_dep 97libdrm_nouveau = null_dep 98libdrm_amdgpu = null_dep 99 100libdrm_version = '>=2.4.82' 101libdrm = dependency('libdrm', version : libdrm_version) 102if with_libdrm.contains('auto') or with_libdrm.contains('intel') 103 libdrm_intel = dependency('libdrm_intel', version : libdrm_version, required : with_libdrm.contains('intel')) 104 libdrm_info += 'intel' 105endif 106if with_libdrm.contains('auto') or with_libdrm.contains('nouveau') 107 libdrm_nouveau = dependency('libdrm_nouveau', version : libdrm_version, required : with_libdrm.contains('nouveau')) 108 libdrm_info += 'nouveau' 109endif 110if with_libdrm.contains('auto') or with_libdrm.contains('amdgpu') 111 libdrm_amdgpu = dependency('libdrm_amdgpu', version : libdrm_version, required : with_libdrm.contains('amdgpu')) 112 libdrm_info += 'amdgpu' 113endif 114 115build_info += 'With libdrm: ' + ','.join(libdrm_info) 116 117pciaccess = dependency('pciaccess', version : '>=0.10') 118libkmod = dependency('libkmod') 119libprocps = dependency('libprocps', required : true) 120 121libunwind = dependency('libunwind', required : get_option('libunwind')) 122build_info += 'With libunwind: @0@'.format(libunwind.found()) 123 124libdw = dependency('libdw', required : true) 125pixman = dependency('pixman-1', required : true) 126 127valgrind = dependency('valgrind', required : get_option('valgrind')) 128if valgrind.found() 129 config.set('HAVE_VALGRIND', 1) 130endif 131build_info += 'Valgrind annotations: @0@'.format(valgrind.found()) 132 133cairo = dependency('cairo', version : '>1.12.0', required : true) 134libudev = dependency('libudev', required : true) 135glib = dependency('glib-2.0', required : true) 136 137xmlrpc = dependency('xmlrpc', required : false) 138xmlrpc_util = dependency('xmlrpc_util', required : false) 139xmlrpc_client = dependency('xmlrpc_client', required : false) 140 141xmlrpc_cmd = find_program('xmlrpc-c-config', required : false) 142if not xmlrpc.found() and xmlrpc_cmd.found() 143 libs_cmd = run_command(xmlrpc_cmd, 'client', '--libs') 144 cflags_cmd = run_command(xmlrpc_cmd, 'client', '--cflags') 145 146 if libs_cmd.returncode() == 0 and cflags_cmd.returncode() == 0 147 xmlrpc = declare_dependency(compile_args: cflags_cmd.stdout().strip().split(), 148 link_args : libs_cmd.stdout().strip().split()) 149 xmlrpc_util = declare_dependency() 150 xmlrpc_client = declare_dependency() 151 endif 152endif 153 154if build_chamelium.enabled() and not (xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found()) 155 error('Chamelium build forced and required dependency xmlrpc not found') 156endif 157 158gsl = dependency('gsl', required : build_chamelium) 159alsa = dependency('alsa', required : build_chamelium) 160libcurl = dependency('libcurl', required : build_chamelium) 161 162if xmlrpc.found() and xmlrpc_util.found() and xmlrpc_client.found() and gsl.found() and alsa.found() and libcurl.found() 163 config.set('HAVE_CHAMELIUM', 1) 164 chamelium = declare_dependency(dependencies : [ 165 xmlrpc, 166 xmlrpc_util, 167 xmlrpc_client, 168 gsl, 169 alsa, 170 ]) 171else 172 chamelium = disabler() 173endif 174 175build_info += 'Build Chamelium test: @0@'.format(chamelium.found()) 176 177pthreads = dependency('threads') 178math = cc.find_library('m') 179realtime = cc.find_library('rt') 180dlsym = cc.find_library('dl') 181zlib = cc.find_library('z') 182 183if cc.links(''' 184#include <stdint.h> 185int main(void) { 186 uint32_t x32 = 0; 187 uint64_t x64 = 0; 188 __atomic_load_n(&x32, __ATOMIC_SEQ_CST); 189 __atomic_load_n(&x64, __ATOMIC_SEQ_CST); 190 return 0; 191}''', name : 'built-in atomics') 192 libatomic = null_dep 193else 194 libatomic = cc.find_library('atomic') 195endif 196 197if cc.has_header('linux/kd.h') 198 config.set('HAVE_LINUX_KD_H', 1) 199endif 200if cc.has_header('sys/kd.h') 201 config.set('HAVE_SYS_KD_H', 1) 202endif 203if cc.has_header('libgen.h') 204 config.set('HAVE_LIBGEN_H', 1) 205endif 206if cc.has_header('sys/io.h') 207 config.set('HAVE_SYS_IO_H', 1) 208endif 209if cc.has_header('cpuid.h') 210 # FIXME: Do we need the example link test from configure.ac? 211 config.set('HAVE_CPUID_H', 1) 212endif 213if cc.has_header_symbol('unistd.h', 'gettid', args : '-D_GNU_SOURCE') 214 config.set('HAVE_GETTID', 1) 215endif 216 217if cc.has_member('struct sysinfo', 'totalram', 218 prefix : '#include <sys/sysinfo.h>') 219 config.set('HAVE_STRUCT_SYSINFO_TOTALRAM', 1) 220endif 221 222have = cc.has_function('memfd_create', prefix : '''#include <sys/mman.h>''', args : '-D_GNU_SOURCE') 223config.set10('HAVE_MEMFD_CREATE', have) 224 225add_project_arguments('-D_GNU_SOURCE', language : 'c') 226add_project_arguments('-include', 'config.h', language : 'c') 227 228# FEATURE_TEST_MACROS(7) 229# performs lightweight overflow checks on quite a few libc functions 230# requires -O optimizations 231if ['debugoptimized', 'release', 'minsize'].contains(get_option('buildtype')) 232 add_project_arguments('-D_FORTIFY_SOURCE=2', language : 'c') 233endif 234 235config.set('PACKAGE_NAME', meson.project_name()) 236config.set_quoted('PACKAGE_VERSION', meson.project_version()) 237config.set_quoted('PACKAGE', meson.project_name()) 238config.set('PACKAGE_STRING', meson.project_name() + ' ' + meson.project_version()) 239config.set_quoted('TARGET_CPU_PLATFORM', host_machine.cpu_family()) 240 241configure_file(output: 'config.h', install: false, configuration: config) 242 243prefix = get_option('prefix') 244bindir = get_option('bindir') 245datadir = join_paths(get_option('datadir'), 'igt-gpu-tools') 246includedir = get_option('includedir') 247libdir = get_option('libdir') 248libexecdir = join_paths(get_option('libexecdir'), 'igt-gpu-tools') 249amdgpudir = join_paths(libexecdir, 'amdgpu') 250mandir = get_option('mandir') 251pkgconfigdir = join_paths(libdir, 'pkgconfig') 252 253if get_option('use_rpath') 254 # Set up runpath for the test executables towards libigt.so. 255 # The path should be relative to $ORIGIN so the library is 256 # still found properly even if installed to a path other than 257 # prefix. 258 259 # libdir and bindir are pathnames relative to prefix. meson 260 # enforces this. 261 262 # 1. Start from the executable. 263 # 2. Executables are installed in certain dir. Add a .. for each 264 # directory name in it. 265 # 3. Add relative path to libdir. 266 267 bindir_rpathdir = '$ORIGIN' 268 foreach p : bindir.split('/') 269 bindir_rpathdir = join_paths(bindir_rpathdir, '..') 270 endforeach 271 bindir_rpathdir = join_paths(bindir_rpathdir, libdir) 272 273 libexecdir_rpathdir = '$ORIGIN' 274 foreach p : libexecdir.split('/') 275 libexecdir_rpathdir = join_paths(libexecdir_rpathdir, '..') 276 endforeach 277 libexecdir_rpathdir = join_paths(libexecdir_rpathdir, libdir) 278 279 amdgpudir_rpathdir = '$ORIGIN' 280 foreach p : amdgpudir.split('/') 281 amdgpudir_rpathdir = join_paths(amdgpudir_rpathdir, '..') 282 endforeach 283 amdgpudir_rpathdir = join_paths(amdgpudir_rpathdir, libdir) 284else 285 bindir_rpathdir = '' 286 libexecdir_rpathdir = '' 287 amdgpudir_rpathdir = '' 288endif 289 290subdir('lib') 291if build_tests 292 subdir('tests') 293endif 294build_info += 'Build tests: @0@'.format(build_tests) 295 296subdir('benchmarks') 297subdir('tools') 298subdir('runner') 299if libdrm_intel.found() 300 subdir('assembler') 301endif 302subdir('overlay') 303subdir('man') 304 305gtk_doc = dependency('gtk-doc', required : build_docs) 306python3 = find_program('python3', required : build_docs) 307if build_tests and gtk_doc.found() and python3.found() 308 subdir('docs') 309elif build_docs.enabled() 310 error('Documentation requires building tests') 311endif 312build_info += 'Build documentation: @0@'.format(build_tests and gtk_doc.found()) 313 314message('Build options') 315message('=============') 316foreach str : build_info 317 message(str) 318endforeach 319 320if cairo.version().version_compare('<1.17.2') 321 if pixman.version().version_compare('<0.36.0') 322 warning('Pixman < 0.36.0 found, cannot test HDR formats') 323 endif 324 warning('Cairo < 1.17.2 found, cannot test HDR formats') 325elif pixman.version().version_compare('<0.36.0') 326 # Cairo 1.17.2 requires 0.36.0 to compile, but somehow it went missing? 327 error('Cairo with floating point support found, but pixman version too old') 328endif 329