meson.build 6.35 KB
Newer Older
1
# Depedencies
Niklas Haas's avatar
Niklas Haas committed
2
cc = meson.get_compiler('c')
3 4
cxx = meson.get_compiler('cpp')

5 6
build_deps = [
  cc.find_library('m', required: false),
7 8 9 10 11
]

subprojects = [
  subproject('xtalloc'),
  subproject('bstr'),
12 13
]

14
vulkan = dependency('vulkan', version: '>=1.0.42', required: get_option('vulkan'))
15

16 17 18 19 20 21 22
# configuration data
conf_public = configuration_data()
conf_internal = configuration_data()
conf_public.set('majorver', majorver)
conf_public.set('apiver', apiver)
conf_public.set('fixver', fixver)
conf_public.set_quoted('version', version_pretty)
Niklas Haas's avatar
Niklas Haas committed
23

24

25
# work-arounds for shaderc braindeath
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
shaderc_names = [
    'shaderc_shared',
    'shaderc_combined',
]

shaderc = disabler()
foreach n : shaderc_names
  if not shaderc.found()
    shaderc = cc.find_library(n, required: get_option('shaderc'))
  endif
endforeach

if shaderc.found()
  conf_internal.set('SHADERC_HAS_PERF', cc.has_header_symbol(
    'shaderc/shaderc.h',
    'shaderc_optimization_level_performance',
    dependencies: shaderc,
  ))
endif

46
# work-arounds for glslang braindeath
47 48
glslang_combined = disabler()
glslang_min_ver = 2763
49
glslang_req = get_option('glslang')
50

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
if glslang_req.auto() and shaderc.found()

  # we only need one or the other, and shaderc is preferred
  message('Skipping `glslang` because `shaderc` is available')
  glslang_req = false
  glslang_found = false

else

  glslang_deps = [
    cxx.find_library('glslang',     required: glslang_req),
    cxx.find_library('HLSL',        required: glslang_req),
    cxx.find_library('OGLCompiler', required: glslang_req),
    cxx.find_library('OSDependent', required: glslang_req),
    cxx.find_library('SPIRV',       required: glslang_req),
    cxx.find_library('SPVRemapper', required: glslang_req),
  ]

  glslang_found = true
  foreach d : glslang_deps
    glslang_found = glslang_found and d.found()
  endforeach

endif
75 76

if glslang_found
77 78 79 80 81
  glslang_ver = cxx.get_define('GLSLANG_PATCH_LEVEL',
      prefix: '#include <glslang/Include/revision.h>'
  ).to_int()

  if glslang_ver >= glslang_min_ver
82 83 84 85 86 87 88
    # glslang must be linked against pthreads on platforms where pthreads is
    # available. Because of their horrible architecture, gcc can't do it
    # automatically, and for some reason dependency('threads') (which uses
    # -pthread) doesn't work. We actually need -lpthreads for the glslang
    # object files to link, for whatever weird reason.
    pthread = cxx.find_library('pthread', required: false)
    glslang_combined = declare_dependency(dependencies: glslang_deps + [pthread])
89
  else
90 91
    error('glslang revision @0@ too old! Must be at least @1@'
          .format(glslang_ver, glslang_min_ver))
92 93 94
  endif
endif

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123

# Source files
sources = [
  'colorspace.c',
  'common.c',
  'context.c',
  'dither.c',
  'dispatch.c',
  'filters.c',
  'gpu.c',
  'renderer.c',
  'shaders.c',
  'shaders/av1.c',
  'shaders/colorspace.c',
  'shaders/sampling.c',
  'spirv.c',
  'swapchain.c',
  'utils/upload.c',
]

tests = [
  'context.c',
  'colorspace.c',
  'dither.c',
  'filters.c',
  'utils.c',
]


124
# Optional dependencies / components
125
components = [
126 127
  {
    'name': 'lcms',
128
    'deps':  dependency('lcms2', version: '>=2.6', required: get_option('lcms')),
129 130 131 132 133 134 135 136 137
    'srcs': 'lcms.c',
  }, {
    'name': 'glslang',
    'deps': glslang_combined,
    'srcs': [ 'glsl/glslang.cc',
              'spirv_glslang.c',
            ],
  }, {
    'name': 'shaderc',
138
    'deps': cc.find_library('shaderc_shared', required: get_option('shaderc')),
139 140 141 142 143 144 145 146 147 148 149 150 151 152
    'srcs': 'spirv_shaderc.c',
  }, {
    'name': 'vulkan',
    'deps': vulkan,
    'srcs': [ 'vulkan/command.c',
              'vulkan/context.c',
              'vulkan/formats.c',
              'vulkan/gpu.c',
              'vulkan/malloc.c',
              'vulkan/swapchain.c',
              'vulkan/utils.c',
            ],
    'test': 'vulkan.c'
  }
Niklas Haas's avatar
Niklas Haas committed
153 154
]

155
defs = ''
156
comps = configuration_data()
Niklas Haas's avatar
Niklas Haas committed
157

158
foreach c : components
159 160
  name = c['name']
  deps = c['deps']
161 162

  pretty = name.underscorify().to_upper()
163 164 165
  defs += '#define PL_HAVE_@0@ @1@\n'.format(pretty, deps.found() ? 1 : 0)

  if deps.found()
166
    comps.set(name, 1)
167 168 169
    build_deps += deps
    sources += c.get('srcs', [])
    tests += c.get('test', [])
170 171
  endif
endforeach
Niklas Haas's avatar
Niklas Haas committed
172

173
# check to see if libplacebo built this way is sane
174 175 176 177 178 179 180
if not comps.has('vulkan')
  warning('Building without support for Vulkan. Currently, libplacebo only ' +
          'supports the Vulkan graphics API. libplacebo built this way still ' +
          'has some limited use (e.g. generating GLSL shaders), but most of ' +
          'its functionality will be missing or impaired!')
endif

Niklas Haas's avatar
Niklas Haas committed
181
if comps.has('vulkan') and not (comps.has('shaderc') or comps.has('glslang'))
182 183 184 185 186
  error('Building with support for Vulkan requires either `shaderc` or ' +
        '`glslang` to be of any use, otherwise libplacebo would fail to ' +
        'compile GLSL to SPIR-V (needed by the Vulkan API)!')
endif

187 188

# Build process
189
conf_public.set('extra_defs', defs)
190

Niklas Haas's avatar
Niklas Haas committed
191 192 193 194
configure_file(
  input: 'config.h.in',
  output: 'config.h',
  install_dir: 'include/libplacebo',
195 196 197 198 199 200
  configuration: conf_public,
)

configure_file(
  output: 'config_internal.h',
  configuration: conf_internal
Niklas Haas's avatar
Niklas Haas committed
201 202
)

203 204 205 206 207 208 209 210 211
# work around meson bugs
build_deps += dependency('threads')
inc = [ include_directories('./include') ]
obj = []
foreach s : subprojects
  inc += s.get_variable('inc')
  obj += s.get_variable('lib').extract_all_objects(recursive: false)
endforeach

Niklas Haas's avatar
Niklas Haas committed
212 213
lib = library('placebo', sources,
  install: true,
214
  dependencies: build_deps,
Niklas Haas's avatar
Niklas Haas committed
215
  soversion: apiver,
216
  include_directories: inc,
217
  objects: obj,
218
  link_args: link_args,
Niklas Haas's avatar
Niklas Haas committed
219 220
)

221

Niklas Haas's avatar
Niklas Haas committed
222
# Install process
223
install_subdir('include/libplacebo', install_dir: get_option('includedir'))
224 225 226 227 228

pkg = import('pkgconfig')
pkg.generate(
  name: meson.project_name(),
  description: 'Reusable library for GPU-accelerated video/image rendering',
229
  libraries: lib,
230
  version: version,
231
)
232

233

234
# Tests
235
tdep = [ declare_dependency(
Niklas Haas's avatar
Niklas Haas committed
236 237
    link_with: lib,
    dependencies: build_deps,
238
    include_directories: inc,
239 240 241 242 243
) ]

foreach s : subprojects
    tdep += s.get_variable('dep')
endforeach
244

245
if get_option('tests')
246
  foreach t : tests
247
    e = executable('test.' + t, 'tests/' + t,
Niklas Haas's avatar
Niklas Haas committed
248 249
        objects: lib.extract_all_objects(recursive: false),
        dependencies: tdep,
250 251
    )

252 253 254
    test(t, e)
  endforeach
endif
255 256 257 258 259 260

if get_option('bench')
  if not vulkan.found()
    error('Compiling the benchmark suite requires vulkan support!')
  endif

Niklas Haas's avatar
Niklas Haas committed
261
  bench = executable('bench', 'tests/bench.c', dependencies: tdep)
262 263
  test('benchmark', bench, is_parallel: false, timeout: 600)
endif