aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-01-06 23:53:33 +0100
committerDavid Robillard <d@drobilla.net>2021-01-08 18:13:49 +0100
commit69d5d2adde1d13578a94e8b1934235987cf9b2bd (patch)
tree9720c044447bb12e6e714ac969ebb7b0daf87c5f
parent94e30b9c3c188dfdf4765f026872f95ea3cfdda2 (diff)
downloadpugl-69d5d2adde1d13578a94e8b1934235987cf9b2bd.tar.gz
pugl-69d5d2adde1d13578a94e8b1934235987cf9b2bd.tar.bz2
pugl-69d5d2adde1d13578a94e8b1934235987cf9b2bd.zip
Switch to Meson
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci.yml114
-rw-r--r--.gitmodules3
-rw-r--r--README.md6
-rw-r--r--doc/_static/meson.build2
-rw-r--r--doc/c/Doxyfile.in (renamed from doc/c/Doxyfile)10
-rw-r--r--doc/c/api/meson.build5
-rw-r--r--doc/c/meson.build44
-rw-r--r--doc/c/wscript45
-rw-r--r--doc/c/xml/meson.build19
-rw-r--r--doc/conf.py.in6
-rw-r--r--doc/cpp/Doxyfile.in (renamed from doc/cpp/Doxyfile)14
-rw-r--r--doc/cpp/api/meson.build5
-rw-r--r--doc/cpp/meson.build43
-rw-r--r--doc/cpp/wscript44
-rw-r--r--doc/cpp/xml/meson.build21
-rw-r--r--doc/meson.build18
-rw-r--r--examples/meson.build80
-rw-r--r--examples/shaders/meson.build35
-rw-r--r--meson.build439
-rw-r--r--meson/meson.build196
-rw-r--r--meson_options.txt20
-rwxr-xr-xscripts/cat.py7
-rwxr-xr-xscripts/dox_to_sphinx.py1
-rw-r--r--test/meson.build33
-rwxr-xr-xwaf27
m---------waflib0
-rw-r--r--wscript814
28 files changed, 1053 insertions, 1000 deletions
diff --git a/.gitignore b/.gitignore
index dad71c3..41c45d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,3 @@
-.waf*/
build/
-.lock-waf*
__pycache__
*.pyc
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c0d0330..f48f1ab 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,48 +2,45 @@ stages:
- build
- deploy
-variables:
- GIT_SUBMODULE_STRATEGY: normal
-
.build_template: &build_definition
stage: build
arm32_dbg:
<<: *build_definition
image: lv2plugin/debian-arm32
- script: python ./waf configure build -dST --werror --no-coverage
- variables:
- CC: "arm-linux-gnueabihf-gcc"
- CXX: "arm-linux-gnueabihf-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/arm-linux-gnueabihf.ini -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
arm32_rel:
<<: *build_definition
image: lv2plugin/debian-arm32
- script: python ./waf configure build -ST --werror --no-coverage
- variables:
- CC: "arm-linux-gnueabihf-gcc"
- CXX: "arm-linux-gnueabihf-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/arm-linux-gnueabihf.ini -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
arm64_dbg:
<<: *build_definition
image: lv2plugin/debian-arm64
- script: python ./waf configure build -dST --werror --no-coverage
- variables:
- CC: "aarch64-linux-gnu-gcc"
- CXX: "aarch64-linux-gnu-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/aarch64-linux-gnu.ini -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
arm64_rel:
<<: *build_definition
image: lv2plugin/debian-arm64
- script: python ./waf configure build -ST --werror --no-coverage
- variables:
- CC: "aarch64-linux-gnu-gcc"
- CXX: "aarch64-linux-gnu-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/aarch64-linux-gnu.ini -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
x64_dbg:
<<: *build_definition
image: lv2plugin/debian-x64
- script: python3 ./waf configure build -dST --werror --no-coverage --docs
+ script:
+ - meson setup build -Dbuildtype=debug -Ddocs=enabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
artifacts:
paths:
- build/doc
@@ -51,60 +48,91 @@ x64_dbg:
x64_rel:
<<: *build_definition
image: lv2plugin/debian-x64
- script: python ./waf configure build -ST --werror --no-coverage
+ script:
+ - meson setup build -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
+
+x64_static:
+ <<: *build_definition
+ image: lv2plugin/debian-x64
+ script:
+ - meson setup build -Ddefault_library=static -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
+
+x64_sanitize:
+ <<: *build_definition
+ image: lv2plugin/debian-x64-clang
+ script:
+ - meson setup build -Db_lundef=false -Dbuildtype=plain -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+ variables:
+ CC: "clang"
+ CXX: "clang++"
+ CFLAGS: "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=unsigned-integer-overflow -fsanitize=implicit-conversion -fsanitize=local-bounds -fsanitize=nullability"
+ CXXFLAGS: "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=unsigned-integer-overflow -fsanitize=implicit-conversion -fsanitize=local-bounds -fsanitize=nullability"
+ LDFLAGS: "-fno-sanitize-recover=all -fsanitize=address -fsanitize=undefined -fsanitize=float-divide-by-zero -fsanitize=unsigned-integer-overflow -fsanitize=implicit-conversion -fsanitize=local-bounds -fsanitize=nullability"
+
mingw32_dbg:
<<: *build_definition
image: lv2plugin/debian-mingw32
- script: python ./waf configure build -dST --werror --no-coverage --target=win32
- variables:
- CC: "i686-w64-mingw32-gcc"
- CXX: "i686-w64-mingw32-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-w64-mingw32.ini -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
mingw32_rel:
<<: *build_definition
image: lv2plugin/debian-mingw32
- script: python ./waf configure build -ST --werror --no-coverage --target=win32
- variables:
- CC: "i686-w64-mingw32-gcc"
- CXX: "i686-w64-mingw32-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/i686-w64-mingw32.ini -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
mingw64_dbg:
<<: *build_definition
image: lv2plugin/debian-mingw64
- script: python ./waf configure build -dST --werror --no-coverage --target=win32
- variables:
- CC: "x86_64-w64-mingw32-gcc"
- CXX: "x86_64-w64-mingw32-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/x86_64-w64-mingw32.ini -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
mingw64_rel:
<<: *build_definition
image: lv2plugin/debian-mingw64
- script: python ./waf configure build -ST --werror --no-coverage --target=win32
- variables:
- CC: "x86_64-w64-mingw32-gcc"
- CXX: "x86_64-w64-mingw32-g++"
+ script:
+ - meson setup build --cross-file=/usr/share/meson/cross/x86_64-w64-mingw32.ini -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
mac_dbg:
<<: *build_definition
- script: python ./waf configure build -dST --werror --no-coverage
tags: [macos]
+ script:
+ - meson setup build -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
mac_rel:
<<: *build_definition
- script: python ./waf configure build -ST --werror --no-coverage
tags: [macos]
+ script:
+ - meson setup build -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
+
win_dbg:
<<: *build_definition
+ tags: [windows,meson]
script:
- - python ./waf configure build -dST --werror --no-coverage
- tags: [windows,msvc,python]
+ - meson setup build -Dbuildtype=debug -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
win_rel:
<<: *build_definition
- script: python ./waf configure build -ST --werror --no-coverage
- tags: [windows,msvc,python]
+ tags: [windows,meson]
+ script:
+ - meson setup build -Dbuildtype=release -Ddocs=disabled -Dwerror=true -Dexamples=true -Dtests=true
+ - ninja -C build
pages:
stage: deploy
diff --git a/.gitmodules b/.gitmodules
index cc8b569..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "waflib"]
- path = waflib
- url = ../../drobilla/autowaf.git
diff --git a/README.md b/README.md
index 97906a8..d05381e 100644
--- a/README.md
+++ b/README.md
@@ -43,8 +43,10 @@ Documentation
Pugl is a C library that includes C++ bindings.
Each API is documented separately:
- * [C Documentation](https://lv2.gitlab.io/pugl/c/singlehtml)
- * [C++ Documentation](https://lv2.gitlab.io/pugl/cpp/singlehtml)
+ * [C Documentation (single page)](https://lv2.gitlab.io/pugl/c/singlehtml/)
+ * [C Documentation (paginated)](https://lv2.gitlab.io/pugl/c/html/)
+ * [C++ Documentation (single page)](https://lv2.gitlab.io/pugl/cpp/singlehtml/)
+ * [C++ Documentation (paginated)](https://lv2.gitlab.io/pugl/cpp/html/)
The documentation can also be built from the source by configuring with `--docs`.
diff --git a/doc/_static/meson.build b/doc/_static/meson.build
new file mode 100644
index 0000000..fc7792c
--- /dev/null
+++ b/doc/_static/meson.build
@@ -0,0 +1,2 @@
+configure_file(copy: true, input: '../../resources/pugl.svg', output: 'pugl.svg')
+
diff --git a/doc/c/Doxyfile b/doc/c/Doxyfile.in
index e16cd28..96bbf63 100644
--- a/doc/c/Doxyfile
+++ b/doc/c/Doxyfile.in
@@ -8,6 +8,7 @@ WARN_NO_PARAMDOC = NO
JAVADOC_AUTOBRIEF = YES
+FULL_PATH_NAMES = NO
CASE_SENSE_NAMES = YES
HIDE_IN_BODY_DOCS = YES
REFERENCES_LINK_SOURCE = NO
@@ -21,10 +22,7 @@ SHOW_FILES = NO
MACRO_EXPANSION = YES
PREDEFINED = PUGL_API PUGL_DISABLE_DEPRECATED PUGL_CONST_API= PUGL_CONST_FUNC=
-INPUT = ../../include/pugl/cairo.h \
- ../../include/pugl/gl.h \
- ../../include/pugl/pugl.h \
- ../../include/pugl/stub.h \
- ../../include/pugl/vulkan.h
+STRIP_FROM_PATH = @PUGL_SRCDIR@
+INPUT = @PUGL_HEADERS@
-OUTPUT_DIRECTORY = .
+OUTPUT_DIRECTORY = doc/c
diff --git a/doc/c/api/meson.build b/doc/c/api/meson.build
new file mode 100644
index 0000000..5c1e30e
--- /dev/null
+++ b/doc/c/api/meson.build
@@ -0,0 +1,5 @@
+c_pugl_rst = custom_target(
+ 'C API ReST Documentation',
+ command: [dox_to_sphinx, '-f', '@INPUT0@', 'doc/c/api'],
+ input: [c_index_xml] + c_rst_files,
+ output: 'pugl.rst')
diff --git a/doc/c/meson.build b/doc/c/meson.build
new file mode 100644
index 0000000..df9363e
--- /dev/null
+++ b/doc/c/meson.build
@@ -0,0 +1,44 @@
+config = configuration_data()
+config.set('PUGL_VERSION', meson.project_version())
+
+conf_py = configure_file(configuration: config,
+ input: '../conf.py.in',
+ output: 'conf.py')
+
+configure_file(copy: true, input: '../deployment.rst', output: 'deployment.rst')
+configure_file(copy: true, input: '../summary.rst', output: 'summary.rst')
+
+c_rst_files = files(
+ 'index.rst',
+ 'overview.rst',
+ 'world.rst',
+ 'view.rst',
+ 'events.rst',
+ 'event-loop.rst',
+ 'shutting-down.rst'
+)
+
+foreach f : c_rst_files
+ configure_file(copy: true, input: f, output: '@PLAINNAME@')
+endforeach
+
+subdir('xml')
+subdir('api')
+
+docs = custom_target(
+ 'C API Documentation (singlehtml)',
+ command: [sphinx_build, '-M', 'singlehtml', 'doc/c/', 'doc/c/', '-E', '-q', '-t', 'singlehtml'],
+ input: [c_rst_files, c_pugl_rst, c_index_xml],
+ output: 'singlehtml',
+ build_by_default: true,
+ install: true,
+ install_dir: docdir / 'pugl-0')
+
+docs = custom_target(
+ 'C API Documentation (html)',
+ command: [sphinx_build, '-M', 'html', 'doc/c/', 'doc/c/', '-E', '-q', '-t', 'html'],
+ input: [c_rst_files, c_pugl_rst, c_index_xml],
+ output: 'html',
+ build_by_default: true,
+ install: true,
+ install_dir: docdir / 'pugl-0')
diff --git a/doc/c/wscript b/doc/c/wscript
deleted file mode 100644
index dc97f6e..0000000
--- a/doc/c/wscript
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-
-def build(bld):
- dox_to_sphinx = bld.path.find_node("../../scripts/dox_to_sphinx.py")
- index_xml = bld.path.get_bld().make_node("xml/index.xml")
-
- files = [
- ("../../resources/pugl.svg", "sphinx/_static/pugl.svg"),
- ("../deployment.rst", "sphinx/deployment.rst"),
- ("../summary.rst", "sphinx/summary.rst"),
- ("event-loop.rst", "sphinx/event-loop.rst"),
- ("events.rst", "sphinx/events.rst"),
- ("index.rst", "sphinx/index.rst"),
- ("overview.rst", "sphinx/overview.rst"),
- ("shutting-down.rst", "sphinx/shutting-down.rst"),
- ("view.rst", "sphinx/view.rst"),
- ("world.rst", "sphinx/world.rst"),
- ]
-
- # Run Doxygen to generate XML documentation
- bld(features="doxygen", doxyfile="Doxyfile")
-
- # Substitute variables to make Sphinx configuration file
- bld(features="subst",
- source="../conf.py.in",
- target="sphinx/conf.py",
- PUGL_VERSION=bld.env.PUGL_VERSION)
-
- # Copy static documentation files to Sphinx build directory
- for f in files:
- bld(features="subst", is_copy=True, source=f[0], target=f[1])
-
- # Generate Sphinx markup from Doxygen XML
- bld.add_group()
- bld(rule="${PYTHON} " + dox_to_sphinx.abspath() + " -f ${SRC} ${TGT}",
- source=index_xml,
- target="sphinx/api/")
-
- # Run Sphinx to generate HTML documentation
- doc_dir = bld.env.DOCDIR + "/pugl-%s/" % bld.env.PUGL_MAJOR_VERSION
- bld(features="sphinx",
- sphinx_source=bld.path.get_bld().make_node("sphinx"),
- sphinx_output_format="singlehtml",
- sphinx_options=["-E", "-q", "-t", "singlehtml"],
- install_path=doc_dir + "c/singlehtml/")
diff --git a/doc/c/xml/meson.build b/doc/c/xml/meson.build
new file mode 100644
index 0000000..d79d59a
--- /dev/null
+++ b/doc/c/xml/meson.build
@@ -0,0 +1,19 @@
+doxygen = find_program('doxygen')
+
+c_doxygen_input = []
+foreach h : c_headers
+ c_doxygen_input += ['..' / h]
+endforeach
+
+config = configuration_data()
+config.set('PUGL_HEADERS', ' '.join(c_doxygen_input))
+config.set('PUGL_SRCDIR', pugl_src_root)
+
+c_doxyfile = configure_file(configuration: config,
+ input: '../Doxyfile.in',
+ output: 'Doxyfile')
+
+c_index_xml = custom_target('c-index.xml',
+ command: [doxygen, '@INPUT0@'],
+ input: [c_doxyfile] + c_header_files,
+ output: 'index.xml')
diff --git a/doc/conf.py.in b/doc/conf.py.in
index d6c9160..3fa8ea2 100644
--- a/doc/conf.py.in
+++ b/doc/conf.py.in
@@ -41,7 +41,7 @@ cpp_index_common_prefix = ["pugl::"]
html_copy_source = False
html_short_title = "Pugl"
-html_static_path = ["_static"]
+html_static_path = ["../_static"]
html_theme = "sphinx_lv2_theme"
if tags.has('singlehtml'):
@@ -52,8 +52,8 @@ if tags.has('singlehtml'):
}
html_theme_options = {
- "body_max_width": "50em",
- "body_min_width": "50em",
+ "body_max_width": "51em",
+ "body_min_width": "51em",
"description": "A minimal portable API for embeddable GUIs.",
"show_footer_version": True,
"show_logo_version": False,
diff --git a/doc/cpp/Doxyfile b/doc/cpp/Doxyfile.in
index 517ba05..889ac0b 100644
--- a/doc/cpp/Doxyfile
+++ b/doc/cpp/Doxyfile.in
@@ -26,15 +26,7 @@ SHOW_FILES = NO
MACRO_EXPANSION = YES
PREDEFINED = PUGL_API PUGL_DISABLE_DEPRECATED PUGL_CONST_API= PUGL_CONST_FUNC=
-INPUT = ../../include/pugl/cairo.h \
- ../../include/pugl/gl.h \
- ../../include/pugl/pugl.h \
- ../../include/pugl/stub.h \
- ../../include/pugl/vulkan.h \
- ../../bindings/cxx/include/pugl/cairo.hpp \
- ../../bindings/cxx/include/pugl/gl.hpp \
- ../../bindings/cxx/include/pugl/pugl.hpp \
- ../../bindings/cxx/include/pugl/stub.hpp \
- ../../bindings/cxx/include/pugl/vulkan.hpp
+STRIP_FROM_PATH = @PUGL_SRCDIR@
+INPUT = @PUGL_HEADERS@
-OUTPUT_DIRECTORY = .
+OUTPUT_DIRECTORY = doc/cpp
diff --git a/doc/cpp/api/meson.build b/doc/cpp/api/meson.build
new file mode 100644
index 0000000..4bbbec2
--- /dev/null
+++ b/doc/cpp/api/meson.build
@@ -0,0 +1,5 @@
+cpp_pugl_rst = custom_target(
+ 'C++ API ReST Documentation',
+ command: [dox_to_sphinx, '-l', 'cpp', '-f', '@INPUT@', 'doc/cpp/api'],
+ input: cpp_index_xml,
+ output: 'pugl.rst')
diff --git a/doc/cpp/meson.build b/doc/cpp/meson.build
new file mode 100644
index 0000000..d8bae11
--- /dev/null
+++ b/doc/cpp/meson.build
@@ -0,0 +1,43 @@
+config = configuration_data()
+config.set('PUGL_VERSION', meson.project_version())
+
+conf_py = configure_file(configuration: config,
+ input: '../conf.py.in',
+ output: 'conf.py')
+
+configure_file(copy: true, input: '../deployment.rst', output: 'deployment.rst')
+configure_file(copy: true, input: '../summary.rst', output: 'summary.rst')
+
+cpp_rst_files = files(
+ 'index.rst',
+ 'overview.rst',
+ 'world.rst',
+ 'view.rst',
+ 'events.rst',
+ 'event-loop.rst',
+)
+
+foreach f : cpp_rst_files
+ configure_file(copy: true, input: f, output: '@PLAINNAME@')
+endforeach
+
+subdir('xml')
+subdir('api')
+
+docs = custom_target(
+ 'C++ API Documentation (singlehtml)',
+ command: [sphinx_build, '-M', 'singlehtml', 'doc/cpp/', 'doc/cpp/', '-E', '-q', '-t', 'singlehtml'],
+ input: [cpp_rst_files, cpp_pugl_rst, cpp_index_xml],
+ output: 'singlehtml',
+ build_by_default: true,
+ install: true,
+ install_dir: docdir / 'puglxx-0')
+
+docs = custom_target(
+ 'C++ API Documentation (html)',
+ command: [sphinx_build, '-M', 'html', 'doc/cpp/', 'doc/cpp/', '-E', '-q', '-t', 'html'],
+ input: [cpp_rst_files, cpp_pugl_rst, cpp_index_xml],
+ output: 'html',
+ build_by_default: true,
+ install: true,
+ install_dir: docdir / 'puglxx-0')
diff --git a/doc/cpp/wscript b/doc/cpp/wscript
deleted file mode 100644
index 4bef6c2..0000000
--- a/doc/cpp/wscript
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-
-def build(bld):
- dox_to_sphinx = bld.path.find_node("../../scripts/dox_to_sphinx.py")
- index_xml = bld.path.get_bld().make_node("xml/index.xml")
-
- files = [
- ("../../resources/pugl.svg", "sphinx/_static/pugl.svg"),
- ("../deployment.rst", "sphinx/deployment.rst"),
- ("../summary.rst", "sphinx/summary.rst"),
- ("event-loop.rst", "sphinx/event-loop.rst"),
- ("events.rst", "sphinx/events.rst"),
- ("index.rst", "sphinx/index.rst"),
- ("overview.rst", "sphinx/overview.rst"),
- ("view.rst", "sphinx/view.rst"),
- ("world.rst", "sphinx/world.rst"),
- ]
-
- # Run Doxygen to generate XML documentation
- bld(features="doxygen", doxyfile="Doxyfile")
-
- # Substitute variables to make Sphinx configuration file
- bld(features="subst",
- source="../conf.py.in",
- target="sphinx/conf.py",
- PUGL_VERSION=bld.env.PUGL_VERSION)
-
- # Copy static documentation files to Sphinx build directory
- for f in files:
- bld(features="subst", is_copy=True, source=f[0], target=f[1])
-
- # Generate Sphinx markup from Doxygen XML
- bld.add_group()
- bld(rule="${PYTHON} " + dox_to_sphinx.abspath() + " -l cpp -f ${SRC} ${TGT}",
- source=index_xml,
- target="sphinx/api/")
-
- # Run Sphinx to generate HTML documentation
- doc_dir = bld.env.DOCDIR + "/pugl-%s/" % bld.env.PUGL_MAJOR_VERSION
- bld(features="sphinx",
- sphinx_source=bld.path.get_bld().make_node("sphinx"),
- sphinx_output_format="singlehtml",
- sphinx_options=["-E", "-q", "-t", "singlehtml"],
- install_path=doc_dir + "cpp/singlehtml/")
diff --git a/doc/cpp/xml/meson.build b/doc/cpp/xml/meson.build
new file mode 100644
index 0000000..3f87f2a
--- /dev/null
+++ b/doc/cpp/xml/meson.build
@@ -0,0 +1,21 @@
+doxygen = find_program('doxygen')
+
+cpp_doxygen_input = []
+foreach h : c_headers + cpp_headers
+ cpp_doxygen_input += ['..' / h]
+endforeach
+
+config = configuration_data()
+config.set('PUGL_HEADERS', ' '.join(cpp_doxygen_input))
+config.set('PUGL_SRCDIR', pugl_src_root)
+
+cpp_doxyfile = configure_file(configuration: config,
+ input: '../Doxyfile.in',
+ output: 'Doxyfile')
+
+cpp_index_xml = custom_target(
+ 'cpp-index.xml',
+ command: [doxygen, '@INPUT0@'],
+ input: [cpp_doxyfile] + c_header_files + cpp_header_files,
+ output: 'index.xml')
+
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644
index 0000000..ba6ea11
--- /dev/null
+++ b/doc/meson.build
@@ -0,0 +1,18 @@
+docdir = get_option('datadir') / 'doc'
+
+doxygen = find_program('doxygen', required: get_option('docs'))
+dox_to_sphinx = find_program('../scripts/dox_to_sphinx.py')
+sphinx_build = find_program('sphinx-build', required: get_option('docs'))
+
+build_docs = doxygen.found() and sphinx_build.found()
+
+if build_docs
+ subdir('_static')
+ subdir('c')
+ subdir('cpp')
+endif
+
+if meson.version().version_compare('>=0.53.0')
+ summary('Documentation', build_docs, bool_yn: true)
+endif
+
diff --git a/examples/meson.build b/examples/meson.build
new file mode 100644
index 0000000..d455faf
--- /dev/null
+++ b/examples/meson.build
@@ -0,0 +1,80 @@
+data_dir = get_option('prefix') / get_option('datadir') / 'pugl-0'
+example_args = ['-DPUGL_DATA_DIR="@0@"'.format(data_dir)]
+
+gl_examples = [
+ 'pugl_cxx_demo.cpp',
+ 'pugl_embed_demo.c',
+ 'pugl_print_events.c',
+ 'pugl_shader_demo.c',
+ 'pugl_window_demo.c',
+]
+
+cairo_examples = [
+ 'pugl_cairo_demo.c'
+]
+
+vulkan_examples = [
+ 'pugl_vulkan_cxx_demo.cpp',
+ 'pugl_vulkan_demo.c',
+]
+
+includes = [
+ '.',
+ '..',
+ '../bindings/cxx/include',
+ '../include',
+]
+
+subdir('shaders')
+
+# Build GL examples
+if opengl_dep.found()
+ foreach example : gl_examples
+ source = [example]
+ target = example.split('.')[0]
+ dependencies = [gl_backend_dep]
+
+ if target == 'pugl_shader_demo'
+ source += ['file_utils.c', 'glad/glad.c']
+ dependencies += [dl_dep]
+ elif target == 'pugl_print_events'
+ dependencies += [stub_backend_dep]
+ endif
+
+ executable(target, source,
+ include_directories: include_directories(includes),
+ c_args: example_args,
+ cpp_args: example_args,
+ dependencies: dependencies)
+ endforeach
+endif
+
+# Build Cairo examples
+if cairo_dep.found()
+ foreach example : cairo_examples
+ target = example.split('.')[0]
+ executable(target, example,
+ include_directories: include_directories(includes),
+ c_args: example_args,
+ dependencies: [pugl_dep, cairo_backend_dep])
+ endforeach
+endif
+
+# Build Vulkan examples
+if vulkan_dep.found()
+ foreach example : vulkan_examples
+ source = [example]
+ target = example.split('.')[0]
+ dependencies = [dl_dep, vulkan_backend_dep]
+
+ if target == 'pugl_vulkan_cxx_demo'
+ source += ['file_utils.c']
+ endif
+
+ executable(target, source,
+ include_directories: include_directories(includes),
+ c_args: example_args,
+ cpp_args: example_args,
+ dependencies: dependencies)
+ endforeach
+endif
diff --git a/examples/shaders/meson.build b/examples/shaders/meson.build
new file mode 100644
index 0000000..e47be9d
--- /dev/null
+++ b/examples/shaders/meson.build
@@ -0,0 +1,35 @@
+shader_files = [
+ 'header_330.glsl',
+ 'header_420.glsl',
+ 'rect.frag',
+ 'rect.vert',
+]
+
+# Copy shader sources for GL examples
+foreach shader_file : shader_files
+ configure_file(copy: true, input: shader_file, output: shader_file)
+endforeach
+
+# Build SPV shader binaries for Vulkan examples
+if vulkan_dep.found()
+ cat = find_program('../../scripts/cat.py')
+ glslang = find_program('glslangValidator')
+
+ shaders = ['rect.vert', 'rect.frag']
+ foreach shader : shaders
+ source = shader.split('.')[0] + '.vulkan.' + shader.split('.')[1]
+ shader_input = custom_target(source,
+ output: source,
+ input: ['header_420.glsl', shader],
+ command: [cat, '@INPUT@'],
+ build_by_default: true,
+ capture: true)
+
+ mytarget = custom_target(shader,
+ output: shader + '.spv',
+ input: shader_input,
+ command: [glslang, '-V', '-o', '@OUTPUT@', '@INPUT@'],
+ build_by_default: true,
+ install: false)
+ endforeach
+endif
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
diff --git a/meson/meson.build b/meson/meson.build
new file mode 100644
index 0000000..20e0522
--- /dev/null
+++ b/meson/meson.build
@@ -0,0 +1,196 @@
+# General code to enable approximately all warnings.
+#
+# This is trivial for clang and MSVC, but GCC does not have such an option, and
+# has several esoteric warnings, so we need to enable everything we want
+# explicitly. We enable everything that does not require a value argument,
+# except for warnings that are only relevant for very old languages (earlier
+# than C99 or C++11) or non-standard extensions.
+#
+# Omitted common warnings:
+#
+# Wabi=
+# Waggregate-return
+# Walloc-size-larger-than=BYTES
+# Walloca-larger-than=BYTES
+# Wframe-larger-than=BYTES
+# Wlarger-than=BYTES
+# Wstack-usage=BYTES
+# Wsystem-headers
+# Wtraditional
+# Wtraditional-conversion
+# Wtrampolines
+# Wvla-larger-than=BYTES
+#
+# Omitted C warnings:
+#
+# Wc90-c99-compat
+# Wdeclaration-after-statement
+# Wtraditional
+# Wtraditional-conversion
+#
+# Omitted C++ warnings:
+#
+# Wnamespaces
+# Wtemplates
+
+gcc_common_warnings = [
+ '-Walloc-zero',
+ '-Walloca',
+ '-Wanalyzer-too-complex',
+ '-Warith-conversion',
+ '-Warray-bounds=2',
+ '-Wattribute-alias=2',
+ '-Wcast-align=strict',
+ '-Wcast-qual',
+ '-Wconversion',
+ '-Wdate-time',
+ '-Wdisabled-optimization',
+ '-Wdouble-promotion',
+ '-Wduplicated-branches',
+ '-Wduplicated-cond',
+ '-Wfloat-equal',
+ '-Wformat-overflow=2',
+ '-Wformat-signedness',
+ '-Wformat-truncation=2',
+ '-Wformat=2',
+ '-Wimplicit-fallthrough=2',
+ '-Winit-self',
+ '-Winline',
+ '-Winvalid-pch',
+ '-Wlogical-op',
+ '-Wmissing-declarations',
+ '-Wmissing-include-dirs',
+ '-Wmultichar',
+ '-Wnormalized=nfc',
+ '-Wnull-dereference',
+ '-Wpacked',
+ '-Wpadded',
+ '-Wredundant-decls',
+ '-Wscalar-storage-order',
+ '-Wshadow',
+ '-Wshift-overflow=2',
+ '-Wsizeof-array-argument',
+ '-Wstack-protector',
+ '-Wstrict-aliasing=3',
+ '-Wstrict-overflow=5',
+ '-Wstringop-overflow=3',
+ '-Wsuggest-attribute=cold',
+ '-Wsuggest-attribute=const',
+ '-Wsuggest-attribute=format',
+ '-Wsuggest-attribute=malloc',
+ '-Wsuggest-attribute=noreturn',
+ '-Wsuggest-attribute=pure',
+ '-Wswitch-default',
+ '-Wswitch-enum',
+ '-Wsync-nand',
+ '-Wundef',
+ '-Wunused-const-variable=2',
+ '-Wunused-macros',
+ '-Wvarargs',
+ '-Wvector-operation-performance',
+ '-Wvla',
+ '-Wwrite-strings',
+]
+
+gcc_c_warnings = [
+ '-Wbad-function-cast',
+ '-Wc++-compat',
+ '-Wc99-c11-compat',
+ '-Wdesignated-init',
+ '-Wdiscarded-array-qualifiers',
+ '-Wdiscarded-qualifiers',
+ '-Wincompatible-pointer-types',
+ '-Wjump-misses-init',
+ '-Wmissing-prototypes',
+ '-Wnested-externs',
+ '-Wold-style-definition',
+ '-Wstrict-prototypes',
+ '-Wunsuffixed-float-constants',
+]
+
+# Set all_c_warnings for the current C compiler
+if is_variable('cc')
+ if cc.get_id() == 'clang'
+ all_c_warnings = ['-Weverything']
+ elif cc.get_id() == 'gcc'
+ all_c_warnings = gcc_common_warnings + [
+ '-Wbad-function-cast',
+ '-Wc++-compat',
+ '-Wc99-c11-compat',
+ '-Wdesignated-init',
+ '-Wdiscarded-array-qualifiers',
+ '-Wdiscarded-qualifiers',
+ '-Wincompatible-pointer-types',
+ '-Wjump-misses-init',
+ '-Wmissing-prototypes',
+ '-Wnested-externs',
+ '-Wold-style-definition',
+ '-Wstrict-prototypes',
+ '-Wunsuffixed-float-constants',
+ ]
+ elif cc.get_id() == 'msvc'
+ all_c_warnings = ['/Wall']
+ else
+ all_c_warnings = []
+ endif
+endif
+
+# Set all_cpp_warnings for the current C++ compiler
+if is_variable('cpp')
+ if cpp.get_id() == 'clang'
+ all_cpp_warnings = [
+ '-Weverything',
+ '-Wno-c++98-compat',
+ '-Wno-c++98-compat-pedantic'
+ ]
+ elif cpp.get_id() == 'gcc'
+ all_cpp_warnings = gcc_common_warnings + [
+ '-Wabi-tag',
+ '-Waligned-new=all',
+ '-Wcatch-value=3',
+ '-Wcomma-subscript',
+ '-Wconditionally-supported',
+ '-Wctor-dtor-privacy',
+ '-Wdeprecated-copy-dtor',
+ '-Weffc++',
+ '-Wextra-semi',
+ '-Wmismatched-tags',
+ '-Wmultiple-inheritance',
+ '-Wnoexcept',
+ '-Wnoexcept-type',
+ '-Wnon-virtual-dtor',
+ '-Wold-style-cast',
+ '-Woverloaded-virtual',
+ '-Wplacement-new=2',
+ '-Wredundant-tags',
+ '-Wregister',
+ '-Wsign-promo',
+ '-Wstrict-null-sentinel',
+ '-Wsuggest-final-methods',
+ '-Wsuggest-final-types',
+ '-Wsuggest-override',
+ '-Wuseless-cast',
+ '-Wvirtual-inheritance',
+ '-Wvolatile',
+ '-Wzero-as-null-pointer-constant',
+ ]
+ elif cpp.get_id() == 'msvc'
+ all_cpp_warnings = ['/Wall']
+ else
+ all_cpp_warnings = []
+ endif
+endif
+
+# Set all_objc_warnings for the current Objective C compiler
+if is_variable('objcc')
+ all_objc_warnings = []
+ if objcc.get_id() == 'clang'
+ all_objc_warnings = ['-Weverything']
+ elif objc.get_id() == 'gcc'
+ all_objc_warnings = gcc_common_warnings + [
+ '-Wno-direct-ivar-access',
+ ]
+ else
+ all_objc_warnings = []
+ endif
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..dd6ea8c
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,20 @@
+option('cairo', type: 'feature', value: 'auto',
+ description : 'Enable support for the Cairo graphics API')
+
+option('examples', type: 'boolean', value: true,
+ description: 'Build example programs')
+
+option('docs', type: 'feature', value: 'auto',
+ description: 'Build documentation')
+
+option('opengl', type: 'feature', value: 'auto',
+ description : 'Enable support for the OpenGL graphics API')
+
+option('strict', type: 'boolean', value: false,
+ description: 'Enable ultra-strict warnings')
+
+option('tests', type: 'boolean', value: true,
+ description: 'Build tests')
+
+option('vulkan', type: 'feature', value: 'auto',
+ description : 'Enable support for the Vulkan graphics API')
diff --git a/scripts/cat.py b/scripts/cat.py
new file mode 100755
index 0000000..5f628b6
--- /dev/null
+++ b/scripts/cat.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+import sys
+
+for filename in sys.argv[1:]:
+ with open(filename, 'r') as f:
+ sys.stdout.write(f.read())
diff --git a/scripts/dox_to_sphinx.py b/scripts/dox_to_sphinx.py
index b88a484..c3f7c44 100755
--- a/scripts/dox_to_sphinx.py
+++ b/scripts/dox_to_sphinx.py
@@ -649,4 +649,5 @@ if __name__ == "__main__":
ap.add_argument("index_xml_path", help="path index.xml from Doxygen")
ap.add_argument("output_dir", help="output directory")
+ print(sys.argv)
run(**vars(ap.parse_args(sys.argv[1:])))
diff --git a/test/meson.build b/test/meson.build
new file mode 100644
index 0000000..340a7dd
--- /dev/null
+++ b/test/meson.build
@@ -0,0 +1,33 @@
+basic_tests = [
+ 'realize',
+ 'redisplay',
+ 'show_hide',
+ 'stub_hints',
+ 'timer',
+ 'update',
+]
+
+gl_tests = [
+ 'gl_hints'
+]
+
+includes = [
+ '.',
+ '../include',
+]
+
+foreach test : basic_tests
+ test(test,
+ executable('test_' + test, 'test_@0@.c'.format(test),
+ include_directories: include_directories(includes),
+ dependencies: [pugl_dep, stub_backend_dep]))
+endforeach
+
+if opengl_dep.found()
+ foreach test : gl_tests
+ test(test,
+ executable('test_' + test, 'test_@0@.c'.format(test),
+ include_directories: include_directories(includes),
+ dependencies: [pugl_dep, gl_backend_dep]))
+ endforeach
+endif
diff --git a/waf b/waf
deleted file mode 100755
index 58d14c3..0000000
--- a/waf
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env python
-
-# Minimal waf script for projects that include waflib directly
-
-import sys
-import inspect
-import os
-
-try:
- from waflib import Context, Scripting
-except Exception as e:
- sys.stderr.write('error: Failed to import waf (%s)\n' % e)
- if os.path.exists('.git'):
- sys.stderr.write("Are submodules up to date? "
- "Try 'git submodule update --init --recursive'\n")
-
- sys.exit(1)
-
-
-def main():
- script_path = os.path.abspath(inspect.getfile(inspect.getmodule(main)))
- project_path = os.path.dirname(os.path.realpath(script_path))
- Scripting.waf_entry_point(os.getcwd(), Context.WAFVERSION, project_path)
-
-
-if __name__ == '__main__':
- main()
diff --git a/waflib b/waflib
deleted file mode 160000
-Subproject 9a097afe77c72723d317f9e0449a9e2ad8f1b44
diff --git a/wscript b/wscript
deleted file mode 100644
index 1dc95c1..0000000
--- a/wscript
+++ /dev/null
@@ -1,814 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import sys
-
-from waflib import Build, Logs, Options, TaskGen
-from waflib.extras import autowaf
-
-# Library and package version (UNIX style major, minor, micro)
-# major increment <=> incompatible changes
-# minor increment <=> compatible changes (additions)
-# micro increment <=> no interface changes
-PUGL_VERSION = '0.2.0'
-PUGL_MAJOR_VERSION = '0'
-
-# Mandatory waf variables
-APPNAME = 'pugl' # Package name for waf dist
-VERSION = PUGL_VERSION # Package version for waf dist
-top = '.' # Source directory
-out = 'build' # Build directory
-
-
-def options(ctx):
- ctx.load('compiler_c')
- ctx.load('compiler_cxx')
-
- opts = ctx.configuration_options()
- opts.add_option('--target', default=None, dest='target',
- help='target platform (e.g. "win32" or "darwin")')
-
- ctx.add_flags(
- opts,
- {'all-headers': 'install complete header implementation',
- 'no-vulkan': 'do not build Vulkan support',
- 'no-gl': 'do not build OpenGL support',
- 'no-cxx': 'do not build C++ examples',
- 'no-cairo': 'do not build Cairo support',
- 'no-static': 'do not build static library',
- 'no-shared': 'do not build shared library'})
-
- ctx.get_option_group('Test options').add_option(
- '--gui-tests', action='store_true', help='Run GUI tests')
-
-
-def configure(conf):
- conf.load('compiler_c', cache=True)
- if not Options.options.no_cxx:
- try:
- conf.load('compiler_cxx', cache=True)
- except Exception:
- pass
-
- conf.load('autowaf', cache=True)
- autowaf.set_c_lang(conf, 'c99')
- if 'COMPILER_CXX' in conf.env:
- autowaf.set_cxx_lang(conf, 'c++11')
-
- conf.env.TARGET_PLATFORM = Options.options.target or sys.platform
- platform = conf.env.TARGET_PLATFORM
-
- data_dir = '%s/%s' % (conf.env.DATADIR, 'pugl-%s' % PUGL_MAJOR_VERSION)
-
- if Options.options.strict:
- # Check for programs used by lint target
- conf.find_program("flake8", var="FLAKE8", mandatory=False)
- conf.find_program("clang-tidy", var="CLANG_TIDY", mandatory=False)
- conf.find_program("iwyu_tool", var="IWYU_TOOL", mandatory=False)
-
- if Options.options.ultra_strict:
- # All warnings enabled by autowaf, disable some we trigger
-
- autowaf.add_compiler_flags(conf.env, '*', {
- 'clang': [
- '-Wno-padded',
- '-Wno-reserved-id-macro',
- '-Wno-switch-enum',
- ],
- 'gcc': [
- '-Wno-inline',
- '-Wno-padded',
- '-Wno-suggest-attribute=const',
- '-Wno-suggest-attribute=malloc',
- '-Wno-suggest-attribute=pure',
- '-Wno-switch-enum',
- ],
- 'msvc': [
- '/wd4061', # enumerator in switch is not explicitly handled
- '/wd4514', # unreferenced inline function has been removed
- '/wd4710', # function not inlined
- '/wd4711', # function selected for automatic inline expansion
- '/wd4820', # padding added after construct
- '/wd4996', # POSIX name for this item is deprecated
- '/wd5045', # will insert Spectre mitigation for memory load
- ],
- })
-
- autowaf.add_compiler_flags(conf.env, 'c', {
- 'clang': [
- '-Wno-bad-function-cast',
- '-Wno-float-equal',
- '-Wno-implicit-fallthrough',
- ],
- 'gcc': [
- '-Wno-bad-function-cast',
- '-Wno-float-equal',
- '-Wno-pedantic',
- ],
- 'msvc': [
- '/wd4191', # unsafe conversion from type to type
- '/wd4706', # assignment within conditional expression
- '/wd4710', # function not inlined
- '/wd5045', # will insert Spectre mitigation for memory load
- ],
- })
-
- autowaf.add_compiler_flags(conf.env, 'cxx', {
- 'clang': [
- '-Wno-cast-align', # pugl_vulkan_cxx_demo
- '-Wno-documentation-unknown-command',
- '-Wno-old-style-cast',
- ],
- 'gcc': [
- '-Wno-cast-align', # pugl_vulkan_cxx_demo
- '-Wno-effc++',
- '-Wno-old-style-cast',
- '-Wno-suggest-final-methods',
- '-Wno-useless-cast',
- ],
- 'msvc': [
- '/wd4191', # unsafe conversion between function pointers
- '/wd4355', # 'this' used in base member initializer list
- '/wd4571', # structured exceptions (SEH) are no longer caught
- '/wd4623', # default constructor implicitly deleted
- '/wd4625', # copy constructor implicitly deleted
- '/wd4626', # assignment operator implicitly deleted
- '/wd4706', # assignment within conditional expression
- '/wd4868', # may not enforce left-to-right evaluation order
- '/wd5026', # move constructor implicitly deleted
- '/wd5027', # move assignment operator implicitly deleted
- '/wd5039', # pointer to throwing function passed to C function
- ],
- })
-
- # Add some platform-specific warning suppressions
- if conf.env.TARGET_PLATFORM == "win32":
- autowaf.add_compiler_flags(conf.env, '*', {
- 'gcc': ['-Wno-cast-function-type',
- '-Wno-conversion',
- '-Wno-format',
- '-Wno-suggest-attribute=format'],
- 'clang': ['-D_CRT_SECURE_NO_WARNINGS',
- '-Wno-format-nonliteral',
- '-Wno-nonportable-system-include-path'],
- })
- elif conf.env.TARGET_PLATFORM == 'darwin':
- autowaf.add_compiler_flags(conf.env, '*', {
- 'clang': ['-DGL_SILENCE_DEPRECATION',
- '-Wno-deprecated-declarations',
- '-Wno-direct-ivar-access'],
- 'gcc': ['-DGL_SILENCE_DEPRECATION',
- '-Wno-deprecated-declarations',
- '-Wno-direct-ivar-access'],
- })
-
- if Options.options.debug and not Options.options.no_coverage:
- conf.env.append_unique('CFLAGS', ['--coverage'])
- conf.env.append_unique('CXXFLAGS', ['--coverage'])
- conf.env.append_unique('LINKFLAGS', ['--coverage'])
-
- if conf.env.DOCS:
- conf.load('python')
- conf.load('sphinx')
- conf.find_program('doxygen', var='DOXYGEN')
-
- if not (conf.env.DOXYGEN and conf.env.SPHINX_BUILD):
- conf.env.DOCS = False
-
- sys_header = 'windows.h' if platform == 'win32' else ''
-
- if not Options.options.no_vulkan:
- vulkan_sdk = os.environ.get('VULKAN_SDK', None)
- vulkan_cflags = ''
- if vulkan_sdk:
- vk_include_path = os.path.join(vulkan_sdk, 'Include')
- vulkan_cflags = conf.env.CPPPATH_ST % vk_include_path
-
- # Check for Vulkan header (needed for backends)
- conf.check(features='c cxx',
- cflags=vulkan_cflags,
- cxxflags=vulkan_cflags,
- header_name=sys_header + ' vulkan/vulkan.h',
- uselib_store='VULKAN',
- mandatory=False)
-
- if conf.env.BUILD_TESTS and conf.env.HAVE_VULKAN:
- # Check for Vulkan library and shader compiler
- # The library is needed by pugl_vulkan_demo.c which has no loader
- vulkan_linkflags = ''
- if vulkan_sdk:
- vk_lib_path = os.path.join(vulkan_sdk, 'Lib')
- vulkan_linkflags = conf.env.LIBPATH_ST % vk_lib_path
-
- # The Vulkan library has a different name on Windows
- for l in ['vulkan', 'vulkan-1']:
- if conf.check(lib=l,
- uselib_store='VULKAN_LIB',
- cflags=vulkan_cflags,
- linkflags=vulkan_linkflags,
- mandatory=False):
- break
-
- validator_name = 'glslangValidator'
- if vulkan_sdk:
- vk_bin_path = os.path.join(vulkan_sdk, 'bin')
- validator_name = os.path.join(vk_bin_path, 'glslangValidator')
-
- conf.find_program(validator_name, var='GLSLANGVALIDATOR')
-
- # Check for base system libraries needed on some systems
- conf.check_cc(lib='pthread', uselib_store='PTHREAD', mandatory=False)
- conf.check_cc(lib='m', uselib_store='M', mandatory=False)
- conf.check_cc(lib='dl', uselib_store='DL', mandatory=False)
-
- # Check for "native" platform dependencies
- conf.env.HAVE_GL = False
- if platform == 'darwin':
- conf.check_cc(framework_name='Cocoa', framework='Cocoa',
- uselib_store='COCOA')
- conf.check_cc(framework_name='Corevideo', framework='Corevideo',
- uselib_store='COREVIDEO')
- if not Options.options.no_gl:
- conf.check_cc(framework_name='OpenGL', uselib_store='GL',
- mandatory=False)
- conf.env.HAVE_GL = conf.env.FRAMEWORK_GL
-
- elif platform == 'win32':
- conf.check_cc(lib='gdi32', uselib_store='GDI32')
- conf.check_cc(lib='user32', uselib_store='USER32')
- if not Options.options.no_gl:
- conf.check_cc(lib='opengl32', uselib_store='GL', mandatory=False)
- conf.env.HAVE_GL = conf.env.LIB_GL
-
- else:
- conf.check_cc(lib='X11', uselib_store='X11')
-
- xsync_fragment = """#include <X11/Xlib.h>
- #include <X11/extensions/sync.h>
- int main(void) { XSyncQueryExtension(0, 0, 0); return 0; }"""
- if conf.check_cc(fragment=xsync_fragment,
- uselib_store='XSYNC',
- lib='Xext',
- mandatory=False,
- msg='Checking for function XSyncQueryExtension'):
- conf.define('HAVE_XSYNC', 1)
-
- if conf.check_cc(lib='Xcursor',
- uselib_store='XCURSOR',
- mandatory=False):
- conf.define('HAVE_XCURSOR', 1)
-
- if conf.check_cc(lib='Xrandr',
- uselib_store='XRANDR',
- mandatory=False):
- conf.define('HAVE_XRANDR', 1)
-
- if not Options.options.no_gl:
- glx_fragment = """#include <GL/glx.h>
- int main(void) { glXSwapBuffers(0, 0); return 0; }"""
-
- conf.check_cc(lib='GLX', uselib_store='GLX', mandatory=False)
- conf.check_cc(lib='GL', uselib_store='GL', mandatory=False)
- conf.check_cc(fragment=glx_fragment,
- lib='GLX' if conf.env.LIB_GLX else 'GL',
- mandatory=False,
- msg='Checking for GLX')
- conf.env.HAVE_GL = conf.env.LIB_GL or conf.env.LIB_GLX
-
- # Check for Cairo via pkg-config
- if not Options.options.no_cairo:
- autowaf.check_pkg(conf, 'cairo',
- uselib_store = 'CAIRO',
- atleast_version = '1.0.0',
- system = True,
- mandatory = False)
-
- conf.env.update({
- 'BUILD_SHARED': not Options.options.no_shared,
- 'BUILD_STATIC': conf.env.BUILD_TESTS or not Options.options.no_static,
- 'BUILD_STRICT_HEADER_TEST': Options.options.strict,
- 'PUGL_MAJOR_VERSION': PUGL_MAJOR_VERSION,
- })
-
- if conf.env.TARGET_PLATFORM == 'win32':
- conf.env.PUGL_PLATFORM = 'win'
- elif conf.env.TARGET_PLATFORM == 'darwin':
- conf.env.PUGL_PLATFORM = 'mac'
- else:
- conf.env.PUGL_PLATFORM = 'x11'
-
- conf.define('PUGL_DATA_DIR', data_dir)
-
- autowaf.set_lib_env(conf, 'pugl', PUGL_VERSION,
- lib='pugl_' + conf.env.PUGL_PLATFORM)
-
- autowaf.set_lib_env(conf, 'pugl_gl', PUGL_VERSION,
- lib='pugl_%s_gl' % conf.env.PUGL_PLATFORM)
-
- autowaf.display_summary(
- conf,
- {"Build static library": bool(conf.env.BUILD_STATIC),
- "Build shared library": bool(conf.env.BUILD_SHARED),
- "Cairo support": bool(conf.env.HAVE_CAIRO),
- "OpenGL support": bool(conf.env.HAVE_GL),
- "Vulkan support": bool(conf.env.HAVE_VULKAN)})
-
-
-def _build_pc_file(bld,
- name,
- desc,
- target,
- libname,
- deps={},
- requires=[],
- cflags=[]):
- "Builds a pkg-config file for a library"
- env = bld.env
- prefix = env.PREFIX
- xprefix = os.path.dirname(env.LIBDIR)
- if libname is not None:
- libname += '-%s' % PUGL_MAJOR_VERSION
-
- uselib = deps.get('uselib', [])
- pkg_deps = [l for l in uselib if 'PKG_' + l.lower() in env]
- lib_deps = [l for l in uselib if 'PKG_' + l.lower() not in env]
- lib = deps.get('lib', []) + [libname] if libname is not None else []
-
- link_flags = [env.LIB_ST % l for l in lib]
- for l in lib_deps:
- link_flags += [env.LIB_ST % l for l in env['LIB_' + l]]
- for f in deps.get('framework', []):
- link_flags += ['-framework', f]
-
- bld(features='subst',
- source='pugl.pc.in',
- target='%s-%s.pc' % (target, PUGL_MAJOR_VERSION),
- install_path=os.path.join(env.LIBDIR, 'pkgconfig'),
-
- PREFIX=prefix,
- EXEC_PREFIX='${prefix}' if xprefix == prefix else xprefix,
- LIBDIR='${exec_prefix}/' + os.path.basename(env.LIBDIR),
- INCLUDEDIR=env.INCLUDEDIR.replace(prefix, '${prefix}', 1),
-
- NAME=name,
- DESCRIPTION=desc,
- PUGL_MAJOR_VERSION=PUGL_MAJOR_VERSION,
- REQUIRES=' '.join(requires + [p.lower() for p in pkg_deps]),
- LIBS=' '.join(link_flags),
- CFLAGS=' '.join(cflags))
-
-
-gl_tests = ['gl_hints']
-
-basic_tests = [
- 'clipboard',
- 'realize',
- 'redisplay',
- 'show_hide',
- 'stub_hints',
- 'timer',
- 'update',
-]
-
-tests = gl_tests + basic_tests
-
-
-def concatenate(task):
- """Task to concatenate all input files into the output file"""
- with open(task.outputs[0].abspath(), 'w') as out:
- for filename in task.inputs:
- with open(filename.abspath(), 'r') as source:
- for line in source:
- out.write(line)
-
-
-def build(bld):
- # C Headers
- includedir = '${INCLUDEDIR}/pugl-%s/pugl' % PUGL_MAJOR_VERSION
- bld.install_files(includedir, bld.path.ant_glob('include/pugl/*.h'))
-
- if 'COMPILER_CXX' in bld.env:
- # C++ Headers
- includedirxx = '${INCLUDEDIR}/puglxx-%s/pugl' % PUGL_MAJOR_VERSION
- bld.install_files(includedirxx,
- bld.path.ant_glob('bindings/cxx/include/pugl/*.hpp'))
- bld.install_files(includedirxx,
- bld.path.ant_glob('bindings/cxx/include/pugl/*.ipp'))
-
- # Library dependencies of pugl libraries (for building examples)
- deps = {}
-
- data_dir = os.path.join(bld.env.DATADIR, 'pugl-%s' % PUGL_MAJOR_VERSION)
-
- def build_pugl_lib(name, **kwargs):
- deps[name] = {}
- for k in ('lib', 'framework', 'uselib'):
- deps[name][k] = kwargs.get(k, [])
-
- args = kwargs.copy()
- args.update({'includes': ['include'],
- 'export_includes': ['include'],
- 'install_path': '${LIBDIR}',
- 'vnum': PUGL_VERSION})
-
- flags = []
- if not bld.env.MSVC_COMPILER:
- flags = ['-fvisibility=hidden']
- if bld.env.TARGET_PLATFORM != 'win32':
- flags = ['-fPIC']
-
- if bld.env.BUILD_SHARED:
- bld(features = 'c cshlib',
- name = name,
- target = 'pugl_%s-%s' % (name, PUGL_MAJOR_VERSION),
- defines = ['PUGL_INTERNAL'],
- cflags = flags,
- linkflags = flags,
- **args)
-
- if bld.env.BUILD_STATIC:
- bld(features = 'c cstlib',
- name = 'pugl_%s_static' % name,
- target = 'pugl_%s-%s' % (name, PUGL_MAJOR_VERSION),
- defines = ['PUGL_STATIC', 'PUGL_INTERNAL', 'PUGL_DISABLE_DEPRECATED'],
- cflags = flags,
- linkflags = flags,
- **args)
-
- def build_platform(platform, **kwargs):
- build_pugl_lib(platform, **kwargs)
- _build_pc_file(bld, 'Pugl', 'Pugl GUI library core',
- 'pugl', 'pugl_%s' % platform,
- deps=kwargs,
- cflags=['-I${includedir}/pugl-%s' % PUGL_MAJOR_VERSION])
-
- def build_backend(platform, backend, **kwargs):
- name = '%s_%s' % (platform, backend)
- label = 'OpenGL' if backend == 'gl' else backend.title()
- build_pugl_lib(name, **kwargs)
- _build_pc_file(bld, 'Pugl %s' % label,
- 'Pugl GUI library with %s backend' % label,
- 'pugl-%s' % backend, 'pugl_' + name,
- deps=kwargs,
- requires=['pugl-%s' % PUGL_MAJOR_VERSION],
- cflags=['-I${includedir}/pugl-%s' % PUGL_MAJOR_VERSION])
-
- lib_source = ['src/implementation.c']
- if bld.env.TARGET_PLATFORM == 'win32':
- platform = 'win'
- build_platform('win',
- uselib=['GDI32', 'USER32'],
- source=lib_source + ['src/win.c'])
-
- build_backend('win', 'stub',
- uselib=['GDI32', 'USER32'],
- source=['src/win_stub.c'])
-
- if bld.env.HAVE_GL:
- build_backend('win', 'gl',
- uselib=['GDI32', 'USER32', 'GL'],
- source=['src/win_gl.c'])
-
- if bld.env.HAVE_VULKAN:
- build_backend('win', 'vulkan',
- uselib=['GDI32', 'USER32', 'VULKAN'],
- source=['src/win_vulkan.c', 'src/win_stub.c'])
-
- if bld.env.HAVE_CAIRO:
- build_backend('win', 'cairo',
- uselib=['CAIRO', 'GDI32', 'USER32'],
- source=['src/win_cairo.c', 'src/win_stub.c'])
-
- elif bld.env.TARGET_PLATFORM == 'darwin':
- platform = 'mac'
- build_platform('mac',
- framework=['Cocoa', 'Corevideo'],
- source=lib_source + ['src/mac.m'])
-
- build_backend('mac', 'stub',
- framework=['Cocoa', 'Corevideo'],
- source=['src/mac_stub.m'])
-
- if bld.env.HAVE_GL:
- build_backend('mac', 'gl',
- framework=['Cocoa', 'Corevideo', 'OpenGL'],
- source=['src/mac_gl.m'])
-
- if bld.env.HAVE_VULKAN:
- build_backend('mac', 'vulkan',
- framework=['Cocoa', 'QuartzCore'],
- source=['src/mac_vulkan.m'])
-
- if bld.env.HAVE_CAIRO:
- build_backend('mac', 'cairo',
- framework=['Cocoa', 'Corevideo'],
- uselib=['CAIRO'],
- source=['src/mac_cairo.m'])
- else:
- platform = 'x11'
- build_platform('x11',
- uselib=['M', 'X11', 'XSYNC', 'XCURSOR', 'XRANDR'],
- source=lib_source + ['src/x11.c'])
-
- build_backend('x11', 'stub',
- uselib=['X11'],
- source=['src/x11_stub.c'])
-
- if bld.env.HAVE_GL:
- glx_lib = 'GLX' if bld.env.LIB_GLX else 'GL'
- build_backend('x11', 'gl',
- uselib=[glx_lib, 'X11'],
- source=['src/x11_gl.c'])
-
- if bld.env.HAVE_VULKAN:
- build_backend('x11', 'vulkan',
- uselib=['DL', 'X11'],
- source=['src/x11_vulkan.c', 'src/x11_stub.c'])
-
- if bld.env.HAVE_CAIRO:
- build_backend('x11', 'cairo',
- uselib=['CAIRO', 'X11'],
- source=['src/x11_cairo.c', 'src/x11_stub.c'])
-
- if 'COMPILER_CXX' in bld.env:
- _build_pc_file(
- bld, 'Pugl C++',
- 'C++ bindings for the Pugl GUI library',
- 'puglxx',
- None,
- requires=['pugl-%s' % PUGL_MAJOR_VERSION],
- cflags=['-I${includedir}/puglxx-%s' % PUGL_MAJOR_VERSION])
-
- bld.add_group()
-
- def build_example(prog, source, platform, backend, **kwargs):
- lang = 'cxx' if source[0].endswith('.cpp') else 'c'
-
- includes = ['.'] + (['bindings/cxx/include'] if lang == 'cxx' else [])
-
- use = ['pugl_%s_static' % platform,
- 'pugl_%s_%s_static' % (platform, backend)]
-
- target = 'examples/' + prog
- if bld.env.TARGET_PLATFORM == 'darwin':
- target = '{0}.app/Contents/MacOS/{0}'.format(prog)
-
- bld(features = 'subst',
- source = 'resources/Info.plist.in',
- target = '{}.app/Contents/Info.plist'.format(prog),
- includes = includes,
- install_path = '',
- NAME = prog)
-
- backend_lib = platform + '_' + backend
- for k in ('lib', 'framework', 'uselib'):
- kwargs.update({k: (kwargs.get(k, []) +
- deps.get(platform, {}).get(k, []) +
- deps.get(backend_lib, {}).get(k, []))})
-
- kwargs['defines'] = kwargs.get('defines', []) + ['PUGL_STATIC']
-
- bld(features = '%s %sprogram' % (lang, lang),
- source = source,
- target = target,
- includes = includes,
- use = use,
- install_path = bld.env.BINDIR,
- **kwargs)
-
- if bld.env.BUILD_TESTS:
- for s in [
- 'header_330.glsl',
- 'header_420.glsl',
- 'rect.frag',
- 'rect.vert',
- ]:
- # Copy shaders to build directory for example programs
- bld(features = 'subst',
- is_copy = True,
- source = 'examples/shaders/%s' % s,
- target = 'examples/shaders/%s' % s,
- install_path = os.path.join(data_dir, 'shaders'))
-
- if bld.env.HAVE_GL:
- glad_cflags = [] if bld.env.MSVC_COMPILER else ['-Wno-pedantic']
- build_example('pugl_embed_demo', ['examples/pugl_embed_demo.c'],
- platform, 'gl', uselib=['GL', 'M'])
- build_example('pugl_window_demo', ['examples/pugl_window_demo.c'],
- platform, 'gl', uselib=['GL', 'M'])
- build_example('pugl_cursor_demo', ['examples/pugl_cursor_demo.c'],
- platform, 'gl', uselib=['GL', 'M'])
- build_example('pugl_print_events',
- ['examples/pugl_print_events.c'],
- platform, 'stub')
- build_example('pugl_shader_demo',
- ['examples/pugl_shader_demo.c',
- 'examples/file_utils.c',
- 'examples/glad/glad.c'],
- platform, 'gl',
- cflags=glad_cflags,
- uselib=['DL', 'GL', 'M'])
-
- for test in gl_tests:
- bld(features = 'c cprogram',
- source = 'test/test_%s.c' % test,
- target = 'test/test_%s' % test,
- install_path = '',
- defines = ['PUGL_STATIC'],
- use = ['pugl_%s_static' % platform,
- 'pugl_%s_gl_static' % platform],
- uselib = deps[platform]['uselib'] + ['GL'])
-
- if bld.env.HAVE_VULKAN and 'GLSLANGVALIDATOR' in bld.env:
- for s in ['rect.vert', 'rect.frag']:
- complete = bld.path.get_bld().make_node(
- 'shaders/%s' % s.replace('.', '.vulkan.'))
- bld(rule = concatenate,
- source = ['examples/shaders/header_420.glsl',
- 'examples/shaders/%s' % s],
- target = complete)
-
- cmd = bld.env.GLSLANGVALIDATOR[0] + " -V -o ${TGT} ${SRC}"
- bld(rule = cmd,
- source = complete,
- target = 'examples/shaders/%s.spv' % s,
- install_path = os.path.join(data_dir, 'shaders'))
-
- build_example('pugl_vulkan_demo',
- ['examples/pugl_vulkan_demo.c'],
- platform,
- 'vulkan', uselib=['M', 'VULKAN', 'VULKAN_LIB'])
-
- if bld.env.CXX:
- build_example('pugl_vulkan_cxx_demo',
- ['examples/pugl_vulkan_cxx_demo.cpp',
- 'examples/file_utils.c'],
- platform, 'vulkan',
- defines=['PUGL_STATIC', 'PUGL_DISABLE_DEPRECATED'],
- uselib=['DL', 'M', 'PTHREAD', 'VULKAN'])
-
- if bld.env.HAVE_CAIRO:
- build_example('pugl_cairo_demo', ['examples/pugl_cairo_demo.c'],
- platform, 'cairo',
- uselib=['M', 'CAIRO'])
-
- for test in basic_tests:
- bld(features = 'c cprogram',
- source = 'test/test_%s.c' % test,
- target = 'test/test_%s' % test,
- install_path = '',
- defines = ['PUGL_STATIC'],
- use = ['pugl_%s_static' % platform,
- 'pugl_%s_stub_static' % platform,
- 'pugl_%s_gl_static' % platform],
- uselib = deps[platform]['uselib'] + ['CAIRO'])
-
- if bld.env.BUILD_STRICT_HEADER_TEST:
- # Make a hyper strict warning environment for checking API headers
- strict_env = bld.env.derive()
- autowaf.remove_all_warning_flags(strict_env)
- autowaf.enable_all_warnings(strict_env)
- autowaf.set_warnings_as_errors(strict_env)
- autowaf.add_compiler_flags(strict_env, '*', {
- 'clang': ['-Wno-padded'],
- 'gcc': ['-Wno-padded', '-Wno-suggest-attribute=const'],
- 'msvc': [
- '/wd4514', # unreferenced inline function has been removed
- '/wd4820', # padding added after construct
- ],
- })
- autowaf.add_compiler_flags(strict_env, 'cxx', {
- 'clang': ['-Wno-documentation-unknown-command'],
- 'msvc': [
- '/wd4355', # 'this' used in base member initializer list
- '/wd4571', # structured exceptions are no longer caught
- ],
- })
-
- # Check that C headers build with (almost) no warnings
- bld(features = 'c cprogram',
- source = 'test/test_build.c',
- target = 'test/test_build_c',
- install_path = '',
- env = strict_env,
- use = ['pugl_%s_static' % platform],
- uselib = deps[platform]['uselib'] + ['CAIRO'])
-
- # Check that C++ headers build with (almost) no warnings
- bld(features = 'cxx cxxprogram',
- source = 'test/test_build.cpp',
- target = 'test/test_build_cpp',
- install_path = '',
- env = strict_env,
- includes = ['bindings/cxx/include'],
- use = ['pugl_%s_static' % platform],
- uselib = deps[platform]['uselib'] + ['CAIRO'])
-
- if bld.env.CXX and bld.env.HAVE_GL:
- build_example('pugl_cxx_demo', ['examples/pugl_cxx_demo.cpp'],
- platform, 'gl',
- defines=['PUGL_DISABLE_DEPRECATED'],
- uselib=['GL', 'M'])
-
- if bld.env.DOCS:
- bld.recurse('doc/c')
- bld.recurse('doc/cpp')
-
-
-def test(tst):
- if tst.options.gui_tests:
- with tst.group('gui') as check:
- for test in basic_tests:
- check(['test/test_%s' % test])
-
- if tst.env.HAVE_GL:
- for test in gl_tests:
- check(['test/test_%s' % test])
-
-
-class LintContext(Build.BuildContext):
- fun = cmd = 'lint'
-
-
-def lint(ctx):
- "checks code for style issues"
- import glob
- import json
- import subprocess
-
- st = 0
-
- if "FLAKE8" in ctx.env:
- Logs.info("Running flake8")
- st = subprocess.call([ctx.env.FLAKE8[0],
- "wscript",
- "--ignore",
- "E221,W504,E251,E241,E741"])
- else:
- Logs.warn("Not running flake8")
-
- if "IWYU_TOOL" in ctx.env:
- Logs.info("Running include-what-you-use")
- cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build", "--",
- "-Xiwyu", "--check_also=*.hpp",
- "-Xiwyu", "--check_also=examples/*.hpp",
- "-Xiwyu", "--check_also=examples/*",
- "-Xiwyu", "--check_also=pugl/*.h",
- "-Xiwyu", "--check_also=bindings/cxx/include/pugl/*.*",
- "-Xiwyu", "--check_also=src/*.c",
- "-Xiwyu", "--check_also=src/*.h",
- "-Xiwyu", "--check_also=src/*.m"]
- output = subprocess.check_output(cmd).decode('utf-8')
- if 'error: ' in output:
- sys.stdout.write(output)
- st += 1
- else:
- Logs.warn("Not running include-what-you-use")
-
- if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CC[0]:
- Logs.info("Running clang-tidy")
- with open('build/compile_commands.json', 'r') as db:
- commands = json.load(db)
- files = [c['file'] for c in commands
- if os.path.basename(c['file']) != 'glad.c']
-
- c_files = [os.path.join('build', f)
- for f in files if f.endswith('.c')]
-
- c_files += glob.glob('include/pugl/*.h')
- c_files += glob.glob('src/implementation.h')
-
- cpp_files = [os.path.join('build', f)
- for f in files if f.endswith('.cpp')]
-
- cpp_files += glob.glob('bindings/cxx/include/pugl/*')
-
- c_files = list(map(os.path.abspath, c_files))
- cpp_files = list(map(os.path.abspath, cpp_files))
-
- procs = []
- for c_file in c_files:
- cmd = [ctx.env.CLANG_TIDY[0], "--quiet", "-p=.", c_file]
- procs += [subprocess.Popen(cmd, cwd="build")]
-
- for cpp_file in cpp_files:
- cmd = [ctx.env.CLANG_TIDY[0],
- '--header-filter=".*"',
- "--quiet",
- "-p=.", cpp_file]
- procs += [subprocess.Popen(cmd, cwd="build")]
-
- for proc in procs:
- stdout, stderr = proc.communicate()
- st += proc.returncode
- else:
- Logs.warn("Not running clang-tidy")
-
- if st != 0:
- sys.exit(st)
-
-
-# Alias .m files to be compiled like .c files, gcc will do the right thing.
-@TaskGen.extension('.m')
-def m_hook(self, node):
- return self.create_compiled_task('c', node)