From 69d5d2adde1d13578a94e8b1934235987cf9b2bd Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 6 Jan 2021 23:53:33 +0100 Subject: Switch to Meson --- .gitignore | 2 - .gitlab-ci.yml | 114 +++--- .gitmodules | 3 - README.md | 6 +- doc/_static/meson.build | 2 + doc/c/Doxyfile | 30 -- doc/c/Doxyfile.in | 28 ++ doc/c/api/meson.build | 5 + doc/c/meson.build | 44 +++ doc/c/wscript | 45 --- doc/c/xml/meson.build | 19 + doc/conf.py.in | 6 +- doc/cpp/Doxyfile | 40 --- doc/cpp/Doxyfile.in | 32 ++ doc/cpp/api/meson.build | 5 + doc/cpp/meson.build | 43 +++ doc/cpp/wscript | 44 --- doc/cpp/xml/meson.build | 21 ++ doc/meson.build | 18 + examples/meson.build | 80 +++++ examples/shaders/meson.build | 35 ++ meson.build | 439 +++++++++++++++++++++++ meson/meson.build | 196 +++++++++++ meson_options.txt | 20 ++ scripts/cat.py | 7 + scripts/dox_to_sphinx.py | 1 + test/meson.build | 33 ++ waf | 27 -- waflib | 1 - wscript | 814 ------------------------------------------- 30 files changed, 1106 insertions(+), 1054 deletions(-) create mode 100644 doc/_static/meson.build delete mode 100644 doc/c/Doxyfile create mode 100644 doc/c/Doxyfile.in create mode 100644 doc/c/api/meson.build create mode 100644 doc/c/meson.build delete mode 100644 doc/c/wscript create mode 100644 doc/c/xml/meson.build delete mode 100644 doc/cpp/Doxyfile create mode 100644 doc/cpp/Doxyfile.in create mode 100644 doc/cpp/api/meson.build create mode 100644 doc/cpp/meson.build delete mode 100644 doc/cpp/wscript create mode 100644 doc/cpp/xml/meson.build create mode 100644 doc/meson.build create mode 100644 examples/meson.build create mode 100644 examples/shaders/meson.build create mode 100644 meson.build create mode 100644 meson/meson.build create mode 100644 meson_options.txt create mode 100755 scripts/cat.py create mode 100644 test/meson.build delete mode 100755 waf delete mode 160000 waflib delete mode 100644 wscript 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 deleted file mode 100644 index e16cd28..0000000 --- a/doc/c/Doxyfile +++ /dev/null @@ -1,30 +0,0 @@ -PROJECT_NAME = Pugl -PROJECT_BRIEF = "A minimal portable API for embeddable GUIs" - -QUIET = YES -WARN_AS_ERROR = YES -WARN_IF_UNDOCUMENTED = NO -WARN_NO_PARAMDOC = NO - -JAVADOC_AUTOBRIEF = YES - -CASE_SENSE_NAMES = YES -HIDE_IN_BODY_DOCS = YES -REFERENCES_LINK_SOURCE = NO - -GENERATE_HTML = NO -GENERATE_LATEX = NO -GENERATE_XML = YES -XML_PROGRAMLISTING = NO -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 - -OUTPUT_DIRECTORY = . diff --git a/doc/c/Doxyfile.in b/doc/c/Doxyfile.in new file mode 100644 index 0000000..96bbf63 --- /dev/null +++ b/doc/c/Doxyfile.in @@ -0,0 +1,28 @@ +PROJECT_NAME = Pugl +PROJECT_BRIEF = "A minimal portable API for embeddable GUIs" + +QUIET = YES +WARN_AS_ERROR = YES +WARN_IF_UNDOCUMENTED = NO +WARN_NO_PARAMDOC = NO + +JAVADOC_AUTOBRIEF = YES + +FULL_PATH_NAMES = NO +CASE_SENSE_NAMES = YES +HIDE_IN_BODY_DOCS = YES +REFERENCES_LINK_SOURCE = NO + +GENERATE_HTML = NO +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = NO +SHOW_FILES = NO + +MACRO_EXPANSION = YES +PREDEFINED = PUGL_API PUGL_DISABLE_DEPRECATED PUGL_CONST_API= PUGL_CONST_FUNC= + +STRIP_FROM_PATH = @PUGL_SRCDIR@ +INPUT = @PUGL_HEADERS@ + +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 deleted file mode 100644 index 517ba05..0000000 --- a/doc/cpp/Doxyfile +++ /dev/null @@ -1,40 +0,0 @@ -PROJECT_NAME = Pugl -PROJECT_BRIEF = "A minimal portable API for embeddable GUIs" - -QUIET = YES -WARN_AS_ERROR = YES -WARN_IF_UNDOCUMENTED = NO -WARN_NO_PARAMDOC = NO - -JAVADOC_AUTOBRIEF = YES - -CASE_SENSE_NAMES = YES -EXCLUDE_SYMBOLS = pugl::detail -EXTRACT_LOCAL_CLASSES = NO -EXTRACT_PRIVATE = NO -HIDE_IN_BODY_DOCS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_UNDOC_MEMBERS = YES -REFERENCES_LINK_SOURCE = NO - -GENERATE_HTML = NO -GENERATE_LATEX = NO -GENERATE_XML = YES -XML_PROGRAMLISTING = NO -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 - -OUTPUT_DIRECTORY = . diff --git a/doc/cpp/Doxyfile.in b/doc/cpp/Doxyfile.in new file mode 100644 index 0000000..889ac0b --- /dev/null +++ b/doc/cpp/Doxyfile.in @@ -0,0 +1,32 @@ +PROJECT_NAME = Pugl +PROJECT_BRIEF = "A minimal portable API for embeddable GUIs" + +QUIET = YES +WARN_AS_ERROR = YES +WARN_IF_UNDOCUMENTED = NO +WARN_NO_PARAMDOC = NO + +JAVADOC_AUTOBRIEF = YES + +CASE_SENSE_NAMES = YES +EXCLUDE_SYMBOLS = pugl::detail +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_PRIVATE = NO +HIDE_IN_BODY_DOCS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_UNDOC_MEMBERS = YES +REFERENCES_LINK_SOURCE = NO + +GENERATE_HTML = NO +GENERATE_LATEX = NO +GENERATE_XML = YES +XML_PROGRAMLISTING = NO +SHOW_FILES = NO + +MACRO_EXPANSION = YES +PREDEFINED = PUGL_API PUGL_DISABLE_DEPRECATED PUGL_CONST_API= PUGL_CONST_FUNC= + +STRIP_FROM_PATH = @PUGL_SRCDIR@ +INPUT = @PUGL_HEADERS@ + +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 + #include + 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 index 9a097af..0000000 --- a/waflib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9a097afe77c72723d317f9e0449a9e2ad8f1b442 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 - #include - 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 - 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) -- cgit v1.2.1