aboutsummaryrefslogtreecommitdiffstats
path: root/meson.build
diff options
context:
space:
mode:
Diffstat (limited to 'meson.build')
-rw-r--r--meson.build439
1 files changed, 439 insertions, 0 deletions
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..977f685
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,439 @@
+project('pugl', ['c'],
+ version: '0.2.0',
+ license: 'ISC',
+ meson_version: '>= 0.49.2',
+ default_options: [
+ 'c_std=c99',
+ 'cpp_std=c++11',
+ 'default_library=shared'
+ ])
+
+pugl_src_root = meson.current_source_dir()
+major_version = meson.project_version().split('.')[0]
+version_suffix = '-@0@'.format(major_version)
+versioned_name = 'pugl' + version_suffix
+
+# Load build tools
+pkg = import('pkgconfig')
+cc = meson.get_compiler('c')
+
+# Enable C++ support if we're building the examples
+if get_option('examples')
+ add_languages(['cpp'])
+ cpp = meson.get_compiler('cpp')
+endif
+
+# Enable Objective C support if we're building for MacOS
+if host_machine.system() == 'darwin'
+ add_languages(['objc'])
+ objcc = meson.get_compiler('objc')
+endif
+
+# Set ultra strict warnings for developers, if requested
+if get_option('strict')
+ subdir('meson')
+
+ # C warnings
+ c_warnings = all_c_warnings
+ if cc.get_id() == 'clang'
+ c_warnings += [
+ '-Wno-bad-function-cast',
+ '-Wno-documentation', # Cairo
+ '-Wno-documentation-unknown-command', # Cairo
+ '-Wno-float-equal',
+ '-Wno-implicit-fallthrough',
+ '-Wno-padded',
+ '-Wno-reserved-id-macro',
+ '-Wno-switch-default',
+ '-Wno-switch-enum',
+ '-Wno-unused-macros', # Mac
+ ]
+ elif cc.get_id() == 'gcc'
+ c_warnings += [
+ '-Wno-bad-function-cast',
+ '-Wno-float-equal',
+ '-Wno-inline',
+ '-Wno-padded',
+ '-Wno-pedantic',
+ '-Wno-suggest-attribute=const',
+ '-Wno-suggest-attribute=malloc',
+ '-Wno-suggest-attribute=pure',
+ '-Wno-switch-default',
+ '-Wno-switch-enum',
+ '-Wno-unsuffixed-float-constants',
+ ]
+ elif cc.get_id() == 'msvc'
+ c_warnings += [
+ '/wd4061', # enumerator in switch is not explicitly handled
+ '/wd4028', # formal parameter different from declaration
+ '/wd4191', # unsafe conversion from type to type
+ '/wd4996', # function or variable may be unsafe
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4706', # assignment within conditional expression
+ '/wd4710', # function not inlined
+ '/wd4711', # function selected for automatic inline expansion
+ '/wd4820', # padding added after construct
+ '/wd5045', # will insert Spectre mitigation for memory load
+ ]
+ endif
+
+ add_project_arguments(cc.get_supported_arguments(c_warnings),
+ language: ['c', 'objc'])
+
+ # C++ warnings
+ cpp_warnings = all_cpp_warnings
+ if is_variable('cpp')
+ if cpp.get_id() == 'clang'
+ cpp_warnings += [
+ '-Wno-documentation-unknown-command', # Cairo
+ '-Wno-old-style-cast',
+ '-Wno-padded',
+ '-Wno-reserved-id-macro',
+ '-Wno-switch-enum',
+ '-Wno-unused-macros', # Mac
+ ]
+ elif cpp.get_id() == 'gcc'
+ cpp_warnings += [
+ '-Wno-effc++',
+ '-Wno-inline',
+ '-Wno-old-style-cast',
+ '-Wno-padded',
+ '-Wno-suggest-attribute=const',
+ '-Wno-suggest-attribute=malloc',
+ '-Wno-suggest-attribute=pure',
+ '-Wno-suggest-final-methods',
+ '-Wno-switch-default',
+ '-Wno-switch-enum',
+ '-Wno-unused-const-variable',
+ '-Wno-useless-cast',
+ ]
+ elif cpp.get_id() == 'msvc'
+ cpp_warnings += [
+ '/wd4061', # enumerator in switch is not explicitly handled
+ '/wd4191', # unsafe conversion from type to type
+ '/wd4355', # 'this' used in base member initializer list
+ '/wd4514', # unreferenced inline function has been removed
+ '/wd4571', # structured exceptions (SEH) are no longer caught
+ '/wd4625', # copy constructor implicitly deleted
+ '/wd4626', # assignment operator implicitly deleted
+ '/wd4706', # assignment within conditional expression
+ '/wd4710', # function not inlined
+ '/wd4711', # function selected for automatic inline expansion
+ '/wd4820', # padding added after construct
+ '/wd4868', # compiler may not enforce left-to-right evaluation order
+ '/wd4996', # function or variable may be unsafe
+ '/wd5026', # move constructor implicitly deleted
+ '/wd5027', # move assignment operator implicitly deleted
+ '/wd5045', # will insert Spectre mitigation for memory load
+ ]
+ endif
+
+ add_project_arguments(cpp.get_supported_arguments(cpp_warnings),
+ language: ['cpp'])
+ endif
+
+ # Objective C warnings
+ if is_variable('objcc')
+ add_project_arguments(objcc.get_supported_arguments(all_objc_warnings),
+ language: ['objc'])
+ endif
+endif
+
+# Disable deprecated API which is not used by tests or examples
+add_project_arguments(['-DPUGL_DISABLE_DEPRECATED'],
+ language: ['c', 'cpp', 'objc'])
+
+c_headers = [
+ 'include/pugl/pugl.h',
+
+ 'include/pugl/cairo.h',
+ 'include/pugl/gl.h',
+ 'include/pugl/stub.h',
+ 'include/pugl/vulkan.h',
+]
+
+c_header_files = files(c_headers)
+
+cpp_headers = [
+ 'bindings/cxx/include/pugl/pugl.hpp',
+
+ 'bindings/cxx/include/pugl/cairo.hpp',
+ 'bindings/cxx/include/pugl/gl.hpp',
+ 'bindings/cxx/include/pugl/stub.hpp',
+ 'bindings/cxx/include/pugl/vulkan.hpp',
+]
+
+cpp_header_files = files(cpp_headers)
+
+core_sources = [
+ 'src/implementation.c'
+]
+
+# System libraries
+m_dep = cc.find_library('m', required: false)
+dl_dep = cc.find_library('dl', required: false)
+thread_dep = dependency('threads')
+
+# Cairo (optional backend)
+cairo_dep = dependency('cairo',
+ required: get_option('cairo'))
+
+# OpenGL (optional backend)
+opengl_dep = dependency('GL',
+ required: get_option('opengl'))
+
+# Vulkan (optional backend)
+vulkan_dep = dependency('vulkan',
+ required: get_option('vulkan'))
+
+core_args = []
+
+# MacOS
+if host_machine.system() == 'darwin'
+ add_project_arguments(['-Wno-deprecated-declarations'], language: ['objc'])
+ cocoa_dep = dependency('Cocoa', required: false, modules: 'foundation')
+ corevideo_dep = dependency('CoreVideo', required: false)
+
+ platform = 'mac'
+ platform_sources = ['src/mac.m', 'src/mac_stub.m']
+ core_deps = [cocoa_dep, corevideo_dep]
+ extension = '.m'
+
+ add_project_arguments(['-DGL_SILENCE_DEPRECATION'],
+ language: ['c', 'objc'])
+
+ add_project_link_arguments(['-Wl,-framework,Cocoa'],
+ language: ['c', 'objc'])
+
+# Windows
+elif host_machine.system() == 'windows'
+ if cpp.get_id() == 'msvc'
+ msvc_args = [
+ '/TP',
+ '/experimental:external',
+ '/external:W0',
+ '/external:anglebrackets',
+ ]
+
+ add_project_arguments(msvc_args, language: ['c', 'cpp'])
+ endif
+
+ win_args = [
+ '-DWIN32_LEAN_AND_MEAN',
+ '-D_CRT_SECURE_NO_WARNINGS',
+ ]
+
+ add_project_arguments(win_args, language: ['c', 'cpp'])
+
+ platform = 'win'
+ platform_sources = ['src/win.c']
+ core_deps = []
+ extension = '.c'
+
+else # X11
+ x11_dep = cc.find_library('X11')
+
+ xcursor_dep = cc.find_library('Xcursor', required: false)
+ if xcursor_dep.found()
+ core_args += ['-DHAVE_XCURSOR']
+ endif
+
+ xrandr_dep = cc.find_library('Xrandr', required: false)
+ if xrandr_dep.found()
+ core_args += ['-DHAVE_XRANDR']
+ endif
+
+ xext_dep = cc.find_library('Xext', required: false)
+ if xext_dep.found()
+ xsync_fragment = '''#include <X11/Xlib.h>
+ #include <X11/extensions/sync.h>
+ int main(void) { XSyncQueryExtension(0, 0, 0); return 0; }'''
+ if cc.compiles(xsync_fragment, name: 'Xsync')
+ core_args += ['-DHAVE_XSYNC']
+ endif
+ endif
+
+ platform = 'x11'
+ platform_sources = ['src/x11.c']
+ core_deps = [x11_dep, xcursor_dep, xrandr_dep, xext_dep]
+ extension = '.c'
+endif
+
+# Build core library
+
+core_deps += [m_dep]
+core_sources += platform_sources
+core_name = 'pugl_@0@@1@'.format(platform, version_suffix)
+
+library_args = ['-DPUGL_INTERNAL']
+if get_option('default_library') == 'both'
+ if host_machine.system() == 'windows'
+ error('default_library=both is not supported on Windows')
+ endif
+
+ library_type = 'both_libraries'
+elif get_option('default_library') == 'shared'
+ library_type = 'shared_library'
+else
+ library_type = 'static_library'
+ add_project_arguments(['-DPUGL_STATIC'], language: ['c', 'cpp', 'objc'])
+endif
+
+libpugl = build_target(
+ core_name, core_sources,
+ version: meson.project_version(),
+ include_directories: include_directories(['include']),
+ c_args: library_args + core_args,
+ dependencies: core_deps,
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ target_type: library_type)
+
+pugl_dep = declare_dependency(link_with: libpugl, dependencies: core_deps)
+
+pkg.generate(libpugl,
+ name: 'Pugl',
+ filebase: versioned_name,
+ subdirs: [versioned_name],
+ version: meson.project_version(),
+ description: 'Pugl GUI library core')
+
+# Build stub backend
+
+name = 'pugl_' + platform + '_stub' + version_suffix
+sources = 'src/' + platform + '_stub' + extension
+
+stub_backend = build_target(
+ name, sources,
+ version: meson.project_version(),
+ include_directories: include_directories(['include']),
+ c_args: library_args,
+ dependencies: [pugl_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ target_type: library_type)
+
+stub_backend_dep = declare_dependency(link_with: stub_backend)
+
+pkg.generate(stub_backend,
+ name: 'Pugl Stub',
+ filebase: 'pugl-stub-@0@'.format(major_version),
+ subdirs: [name],
+ version: meson.project_version(),
+ description: 'Native window pugl graphics backend')
+
+# Build GL backend
+if opengl_dep.found()
+ name = 'pugl_' + platform + '_gl' + version_suffix
+ sources = 'src/' + platform + '_gl' + extension
+
+ gl_backend = build_target(
+ name, sources,
+ version: meson.project_version(),
+ include_directories: include_directories(['include']),
+ c_args: library_args,
+ dependencies: [pugl_dep, opengl_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ target_type: library_type)
+
+ gl_backend_dep = declare_dependency(link_with: gl_backend,
+ dependencies: [pugl_dep, opengl_dep])
+
+ pkg.generate(gl_backend,
+ name: 'Pugl OpenGL',
+ filebase: 'pugl-gl-@0@'.format(major_version),
+ subdirs: [name],
+ version: meson.project_version(),
+ description: 'Pugl GUI library with OpenGL backend')
+endif
+
+# Build Cairo backend
+if cairo_dep.found()
+ name = 'pugl_' + platform + '_cairo' + version_suffix
+ sources = ['src/' + platform + '_cairo' + extension,
+ 'src/' + platform + '_stub' + extension]
+
+ cairo_backend = build_target(
+ name, sources,
+ version: meson.project_version(),
+ include_directories: include_directories(['include']),
+ c_args: library_args,
+ dependencies: [pugl_dep, cairo_dep, stub_backend_dep],
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ target_type: library_type)
+
+ cairo_backend_dep = declare_dependency(
+ link_with: cairo_backend,
+ dependencies: [pugl_dep, cairo_dep, stub_backend_dep])
+
+ pkg.generate(cairo_backend,
+ name: 'Pugl Cairo',
+ filebase: 'pugl-cairo-@0@'.format(major_version),
+ subdirs: [name],
+ version: meson.project_version(),
+ description: 'Pugl GUI library with Cairo backend')
+endif
+
+# Build Vulkan backend
+if vulkan_dep.found()
+ name = 'pugl_' + platform + '_vulkan' + version_suffix
+ sources = ['src/' + platform + '_vulkan' + extension,
+ 'src/' + platform + '_stub' + extension]
+
+ vulkan_deps = [pugl_dep, vulkan_dep, dl_dep]
+ vulkan_c_args = library_args
+ vulkan_link_args = []
+ if platform == 'mac'
+ metal_dep = dependency('Metal', modules: 'foundation')
+ quartzcore_dep = dependency('QuartzCore', modules: 'foundation')
+
+ vulkan_deps += [metal_dep, quartzcore_dep]
+ endif
+
+ vulkan_backend = build_target(
+ name, sources,
+ version: meson.project_version(),
+ include_directories: include_directories(['include']),
+ c_args: library_args,
+ dependencies: vulkan_deps,
+ gnu_symbol_visibility: 'hidden',
+ install: true,
+ target_type: library_type)
+
+ vulkan_backend_dep = declare_dependency(
+ link_with: vulkan_backend,
+ dependencies: [pugl_dep, vulkan_dep, thread_dep])
+
+ pkg.generate(vulkan_backend,
+ name: 'Pugl Vulkan',
+ filebase: 'pugl-vulkan-@0@'.format(major_version),
+ subdirs: [name],
+ version: meson.project_version(),
+ description: 'Pugl GUI library with Vulkan backend')
+endif
+
+install_headers(c_headers, subdir: versioned_name / 'pugl')
+install_headers(cpp_headers, subdir: 'puglxx' + version_suffix)
+
+if meson.version().version_compare('>=0.53.0')
+ summary('Platform', platform)
+ summary('Cairo backend', cairo_dep.found(), bool_yn: true)
+ summary('OpenGL backend', opengl_dep.found(), bool_yn: true)
+ summary('Vulkan backend', vulkan_dep.found(), bool_yn: true)
+ summary('Tests', get_option('tests'), bool_yn: true)
+ summary('Examples', get_option('examples'), bool_yn: true)
+endif
+
+if not get_option('docs').disabled()
+ subdir('doc')
+endif
+
+if get_option('examples')
+ subdir('examples')
+endif
+
+if get_option('tests')
+ subdir('test')
+endif