diff options
48 files changed, 2257 insertions, 872 deletions
diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b2babe71..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "waflib"] - path = waflib - url = ../autowaf.git diff --git a/bundles/MonoEffect.ingen/manifest.ttl b/bundles/MonoEffect.ingen/manifest.ttl deleted file mode 100644 index 4484811a..00000000 --- a/bundles/MonoEffect.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<MonoEffect.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <MonoEffect.ttl> . diff --git a/bundles/MonoInstrument.ingen/manifest.ttl b/bundles/MonoInstrument.ingen/manifest.ttl deleted file mode 100644 index a65a5341..00000000 --- a/bundles/MonoInstrument.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<MonoInstrument.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <MonoInstrument.ttl> . diff --git a/bundles/StereoEffect.ingen/manifest.ttl b/bundles/StereoEffect.ingen/manifest.ttl deleted file mode 100644 index 5c55ef41..00000000 --- a/bundles/StereoEffect.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<StereoEffect.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <StereoEffect.ttl> . diff --git a/bundles/StereoInstrument.ingen/manifest.ttl b/bundles/StereoInstrument.ingen/manifest.ttl deleted file mode 100644 index d4cc271d..00000000 --- a/bundles/StereoInstrument.ingen/manifest.ttl +++ /dev/null @@ -1,16 +0,0 @@ -@prefix atom: <http://lv2plug.in/ns/ext/atom#> . -@prefix patch: <http://lv2plug.in/ns/ext/patch#> . -@prefix doap: <http://usefulinc.com/ns/doap#> . -@prefix ingen: <http://drobilla.net/ns/ingen#> . -@prefix lv2: <http://lv2plug.in/ns/lv2core#> . -@prefix midi: <http://lv2plug.in/ns/ext/midi#> . -@prefix owl: <http://www.w3.org/2002/07/owl#> . -@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . -@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . -@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . - -<StereoInstrument.ttl> - lv2:prototype ingen:GraphPrototype ; - a ingen:Graph , - lv2:Plugin ; - rdfs:seeAlso <StereoInstrument.ttl> . diff --git a/bundles/MonoEffect.ingen/MonoEffect.ttl b/bundles/ingen.lv2/MonoEffect.ttl index 45f55ad5..45f55ad5 100644 --- a/bundles/MonoEffect.ingen/MonoEffect.ttl +++ b/bundles/ingen.lv2/MonoEffect.ttl diff --git a/bundles/MonoInstrument.ingen/MonoInstrument.ttl b/bundles/ingen.lv2/MonoInstrument.ttl index f8a8595d..f8a8595d 100644 --- a/bundles/MonoInstrument.ingen/MonoInstrument.ttl +++ b/bundles/ingen.lv2/MonoInstrument.ttl diff --git a/bundles/StereoEffect.ingen/StereoEffect.ttl b/bundles/ingen.lv2/StereoEffect.ttl index fff6ffce..fff6ffce 100644 --- a/bundles/StereoEffect.ingen/StereoEffect.ttl +++ b/bundles/ingen.lv2/StereoEffect.ttl diff --git a/bundles/StereoInstrument.ingen/StereoInstrument.ttl b/bundles/ingen.lv2/StereoInstrument.ttl index 84c756c1..84c756c1 100644 --- a/bundles/StereoInstrument.ingen/StereoInstrument.ttl +++ b/bundles/ingen.lv2/StereoInstrument.ttl diff --git a/bundles/ingen.lv2/manifest.ttl b/bundles/ingen.lv2/manifest.ttl index 12d3621a..616933a5 100644 --- a/bundles/ingen.lv2/manifest.ttl +++ b/bundles/ingen.lv2/manifest.ttl @@ -41,3 +41,27 @@ internals:Note internals:Transport a ingen:Plugin ; rdfs:seeAlso <internals.ttl> . + +<MonoEffect.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <MonoEffect.ttl> . + +<MonoInstrument.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <MonoInstrument.ttl> . + +<StereoEffect.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <StereoEffect.ttl> . + +<StereoInstrument.ttl> + a ingen:Graph , + lv2:Plugin ; + lv2:prototype ingen:GraphPrototype ; + rdfs:seeAlso <StereoInstrument.ttl> . diff --git a/bundles/ingen.lv2/meson.build b/bundles/ingen.lv2/meson.build new file mode 100644 index 00000000..c01f4110 --- /dev/null +++ b/bundles/ingen.lv2/meson.build @@ -0,0 +1,44 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +data_files = files( + 'MonoEffect.ttl', + 'MonoInstrument.ttl', + 'StereoEffect.ttl', + 'StereoInstrument.ttl', + 'errors.ttl', + 'ingen.ttl', + 'internals.ttl', + 'manifest.ttl', +) + +# Install bundle +install_data(data_files, install_dir: lv2dir / 'ingen.lv2') + +# Ontology documentation +lv2specgen_py = find_program('lv2specgen.py', required: get_option('docs')) +if lv2specgen_py.found() + ingen_html = custom_target( + 'ingen.html', + input: files('ingen.ttl'), + command: [ + lv2specgen_py, + '@INPUT@', + '@OUTPUT@', + '--copy-style', + '--instances', + '--list-email', 'ingen@drobilla.net', + '--list-page', 'http://lists.drobilla.net/listinfo.cgi/ingen-drobilla.net', + '--prefix', 'ingen', + ], + install: true, + install_dir: lv2dir / 'ingen.lv2', + output: 'ingen.html', + ) + + # TODO: Fix lv2specgen so third-party documentation is properly styled + install_data( + files('style.css'), + install_dir: lv2dir / 'ingen.lv2', + ) +endif diff --git a/bundles/ingen.lv2/style.css b/bundles/ingen.lv2/style.css new file mode 100644 index 00000000..fca399e3 --- /dev/null +++ b/bundles/ingen.lv2/style.css @@ -0,0 +1,805 @@ +@import "./pygments.css"; + +/* Generic page style */ + +html { + background: #FFF; + color: #222; +} + +body { + font-family: "DejaVu Sans", "SF Pro Text", Verdana, sans-serif; + font-style: normal; + line-height: 1.6em; + margin-left: auto; + margin-right: auto; + max-width: 60em; + padding: 1em; +} + +h1 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 2.38em; + font-weight: 600; + line-height: 1.41em; + margin: 0 0 0.25em; +} + +h2 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.68em; + font-weight: 600; + line-height: 1.3em; + margin: 1.25em 0 0.5em; +} + +h3 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.41em; + font-weight: 600; + line-height: 1.19em; + margin: 1.25em 0 0.5em; +} + +h4 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1.19em; + font-weight: 600; + line-height: 1.09em; + margin: 1.25em 0 0.5em; +} + +h5, h6 { + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + font-size: 1em; + font-weight: 600; + line-height: 1em; + margin: 1.25em 0 0.5em; +} + +a { + color: #546E00; + text-decoration: none; +} + +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: #222; +} + +a:link { + color: #546E00; + text-decoration: none; +} + +a:visited { + color: #546E00; +} + +a:hover { + text-decoration: underline; +} + +h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link { + color: #222; +} + +h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited { + color: #222; +} + +img { + border: 0; +} + +p { + margin: 0.5em 0; +} + +blockquote { + border-left: 1px solid #CCC; + margin-left: 1em; + padding-left: 1em; +} + +pre, code, kbd, samp { + color: #444; + font-family: "DejaVu Sans Mono", "SF Mono", Consolas, monospace; + margin: 1em 0; + white-space: pre; +} + +ul, ol { + margin: 0 0 0.5em; + padding-top: 0; +} + +dt { + font-weight: 600; + margin: 0.75em 0 0.125em; +} + +dt::after { + content: ": "; + margin-right: 0.5em; +} + +hr { + background-color: #EEE; + border: 0; + color: #666; + height: 1px; + margin-bottom: 1.5ex; + margin-top: 1.5ex; +} + +table { + border-collapse: collapse; + border-spacing: 1em 1em; + border-style: hidden; + border: 0; + margin: 0; +} + +th { + border: 1px solid #EEE; + padding: 0.25em 0.5em; + text-align: left; +} + +table tbody tr th { + text-align: left; +} + +td { + border: 1px solid #EEE; + padding: 0.25em 0.5em; + vertical-align: top; +} + +caption { + caption-side: bottom; + font-size: small; + font-style: italic; + margin: 0.75em 0; +} + +footer { + color: #444; + font-size: small; +} + +/* Specgen style */ + +#titlebox { + display: inline-block; + max-width: 60%; + left: 0; + top: 0; +} + +#metabox { + display: inline-block; + font-size: x-small; + font-family: "DejaVu Sans Condensed", Helvetica, Arial, sans-serif; + position: absolute; + right: 0; + bottom: 0.25em; + color: #666; + font-style: italic; +} + +#meta { + border-style: hidden; +} + +#meta tr, #meta th, #meta td { + border: 0; + font-weight: normal; + padding: 0 0 0.125em; + background-color: transparent; +} + +#meta th { + padding-right: 0.5em; + text-align: right; +} + +#meta th::after { + content: ": "; +} + +#subtitle { + font-size: small; +} + +#shortdesc { + padding: 0; + margin: 0 0 0.5em; + font-style: italic; + color: #666; + display: inline-block; +} + +#logo { + height: 63px; + margin-left: 1em; + margin-top: 10px; + width: 100px; +} + +#titlesep { + color: #EEE; +} + +#content-body { + border-bottom: 0; + display: block; + font-size: 75%; + left: 0; + margin-left: 2em; + min-width: 660px; + padding: 3px 10px 0 0; + position: absolute; + top: 63px; + width: 93.9%; + z-index: 0; +} + +#menu { + font-size: 75%; + margin-bottom: 5px; + padding: 0; + width: 16em; +} + +#menu ul { + border: 0; + list-style: none; + margin: 0; + padding: 0; +} + +#menu a { + text-decoration: none; +} + +#menu ul.level-one a { + background-color: #F5F5F5; + border: 1px solid #DADADA; + color: #4B5A6A; + display: block; + margin: 0 0 4px 1.4em; + padding: 2px 2px 2px 4px; + text-transform: uppercase; + width: 13.4em !important; +} + +#menu ul.level-two a { + background: none; + background-color: transparent; + border: 0; + border-top: 1px solid #DDD; + color: #3C4B7B; + display: block; + margin: 0 3em 0 1.5em; + padding: 0.1em; + text-transform: none; + width: 11em !important; +} + +#menu ul.level-three a { + border: 0; + color: #5E72A5; + display: block; + font-size: 95%; + margin: 0 3em 0 1.8em; + padding: 0.1em 0.1em 0.1em 1em; + width: 10em !important; +} + +#menu ul.level-one a:hover, +#menu ul.level-two a:hover, +#menu ul.level-three a:hover { + color: #000; + text-decoration: underline; +} + +#menu ul.level-one a.selected { + background-color: #FFF; + border-left: 3px solid #FFDB4C; + color: #000; +} + +#menu ul.level-two a:visited { + color: #4C3B5B; +} + +#menu ul.level-two li:first-child a { + border-top: 0; +} + +#menu ul.level-one ul.level-two a.selected { + background-color: #FFF; + border-left: 0; + color: #000; + font-weight: 700; +} + +#menu li ul { + margin-bottom: 7px; +} + +#menu ul.level-three li.selected a.selected { + color: #000; + font-weight: 400; +} + +#menu ul.level-three { + margin-top: 5px; +} + +#searchbox { + font-weight: 700; + position: absolute; + right: 0; + text-align: right; + top: 0; + vertical-align: middle; + white-space: nowrap; + width: 28.1em; +} + +#search { + color: #A38E60; + padding: 5px 5px 0 0; +} + +#search .input-text { + background-color: #FFF; + border: 1px solid #C4CCCC; + font-size: 116%; + font-weight: 400; + margin-top: 3px; + vertical-align: top; + width: 11em; +} + +#search .input-button { + background-color: #F8F7F7; + border-bottom: 1px solid #6F7777; + border-left: 1px solid #C4CCCC; + border-right: 1px solid #6F7777; + border-top: 1px solid #C4CCCC; + color: #234; + font-weight: 700; + margin: 3px 0.4em 0; + padding: 0 0.2em; + vertical-align: text-top; +} + +input.formbutton { + background-color: #F8F7F7; + border-bottom: 1px solid #6F7777; + border-left: 1px solid #C4CCCC; + border-right: 1px solid #6F7777; + border-top: 1px solid #C4CCCC; + color: #234; + font-weight: 700; + vertical-align: text-top; +} + +.formtextinput { + background-color: #FFF; + border: 1px solid #C4CCCC; + font-size: 116%; + font-weight: 400; + vertical-align: top; +} + +#content table { + clear: right; +} + +.content-section { + margin-top: 15px; +} + +.content-section h1 { + margin: 0 0 10px; +} + +.content-section p { + margin: 0 0 5px; + padding-left: 12px; +} + +.content-section .pubdate { + color: #696969; + margin: 0 0 8px; + padding: 0 0 0 12px; +} + +#footer { + bottom: 0; + clear: both; + font-size: x-small; + margin: 2em 0 0; + padding: 0; + color: #888; +} + +#searchbox a.reference, #searchbox span.reference { + color: #339; + font-size: 85%; + font-weight: 400; + position: absolute; + right: 8.3em; + text-decoration: none; + top: 2.9em; +} + +#topbar { + line-height: 1em; + border-bottom: 1px solid #EEE; +} + +@media print { + #topbar { + color: #000; + margin: 0.25em auto; + padding: 0.25em 0.5em 0.5em; + max-width: 60em; + position: relative; + } + + #contentsbox { + display: none; + } + + #topbar a, #title a, #topbar a:visited, #title a:visited { + color: #000; + } + + #contents { + display: none; + } +} + +@media screen { + #topbar { + margin: 0.25em auto; + padding: 0; + max-width: 60em; + position: relative; + } + + #contentsbox { + color: #546E00; + font-size: small; + margin: 0 0 1.5em; + } + + #contents { + display: inline; + padding: 0; + } + + #contents li { + display: inline; + list-style-type: none; + margin-left: 0; + margin-right: 0.5em; + padding: 0.25ex 0.25ex 0.25ex 0; + } +} + +#content { + clear: both; + padding: 0; + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.section { + clear: right; + padding: 0 0 1.5em; +} + +.category { + font-size: small; + color: #AAA; + float: right; + vertical-align: bottom; + padding: 0; + margin: 0; + padding-right: 0.25em; +} + +.label { + font-style: italic; + margin-top: 0.25em; + color: #666; +} + +table.index { + border: 0; + line-height: 1.5em; + margin-top: 2em; +} + +.index ul { + padding-left: 1.25em; + margin-left: 0; + list-style-type: circle; +} + +.index ul li { + padding-left: 0; + color: #888; +} + +.prop { + margin: 0; + padding: 0; +} + +.description { + margin-top: 0; + margin-bottom: 0.75em; +} + +.blankdesc, .blankdef { + border-spacing: 0; + margin: 0; + padding-left: 0; + padding-right: 0; +} + +.blankdesc tbody tr td, .blankdef { + border: 0 !important; +} + +.blankdesc td { + padding-right: 0.5em; +} + +.blankdesc tbody tr td:first-child { + border-left: 1px solid #BBB; + text-align: right; +} + +.terminfo, .restriction { + border-collapse: collapse; + border-spacing: 0; + font-size: small; + color: #666; + border-radius: 0; + border-bottom-left-radius: 6px; +} + +table.terminfo { + border-top: 0; + border-collapse: collapse; + margin: -1px 0 2em 2em; + padding: 0.25em 0; + float: right; + border-bottom: 1px solid #EEE; + border-left: 1px solid #EEE; + border-bottom-left-radius: 6px; + max-width: 50%; + line-height: 1.4em; + min-width: 25%; +} + +table.terminfo td { + padding: 0 0.5em; +} + +.restriction { + border-style: hidden; + margin: 0 0 0.5ex; + padding: 0; + vertical-align: text-top; +} + +.restriction td { + vertical-align: text-top; +} + +.terminfo th { + padding: 0 0.5em; + text-align: right; + vertical-align: top; +} + +.specterm { + border: 0; + margin: 0; + padding: 1em 0; + clear: both; +} + +.specterm h3 { + display: inline-block; + margin-bottom: 0.25em; + width: 80%; +} + +.spectermtype { + color: #888; + display: inline-block; + font-size: small; + font-style: italic; + box-sizing: border-box; + margin: 0; + padding: 0 0.25em 0 0; + text-align: right; + vertical-align: bottom; + width: 20%; +} + +.spectermbody { + border-top: 1px solid #EEE; + padding: 0; +} + +.spectermbody .description .comment > p:first-child { + color: #444; + font-style: italic; + margin-bottom: 0.75em; +} + +dl { + margin: 0; + padding: 0; +} + +div.head { + margin-bottom: 1em; +} + +div.head h1 { + clear: both; + margin-top: 2em; +} + +div.head table { + margin-left: 2em; + margin-top: 2em; +} + +#menu li { + display: inline; +} + +.error { + color: #990A1B; +} + +.warning { + color: #7B6000; +} + +.success { + color: #546E00; +} + +.highlight, .codehilite { + margin-left: 2em; +} + +/* Dark mode */ +@media (prefers-color-scheme: dark) { + /* Dark generic page style */ + + html { + background: #222; + color: #DDD; + } + + a { + color: #B4C342; + } + + a:link { + color: #B4C342; + } + + a:visited { + color: #B4C342; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + color: #DDD; + } + + h1 a:link, h2 a:link, h3 a:link, h4 a:link, h5 a:link, h6 a:link { + color: #DDD; + } + + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited { + color: #DDD; + } + + blockquote { + border-left: 1px solid #444; + } + + pre, code, kbd, samp { + color: #DDD; + } + + hr { + background-color: #333; + border: 0; + color: #666; + } + + th { + border: 1px solid #444; + } + + td { + border: 1px solid #444; + } + + footer { + color: #BBB; + } + + /* Dark specgen style */ + + #metabox { + color: #999; + } + + #shortdesc { + color: #999; + } + + #titlesep { + color: #444; + } + + .terminfo, .restriction { + color: #999; + } + + table.terminfo { + border-bottom: 1px solid #444; + border-left: 1px solid #444; + } + + .spectermbody { + border-top: 1px solid #444; + } + + .spectermbody .description .comment > p:first-child { + color: #BBB; + } + + .error { + color: #DC322F; + } + + .warning { + color: #B58900; + } + + .success { + color: #859900; + } + + #topbar { + border-bottom: 1px solid #444; + } +} + +/* Hard black for dark mode on mobile (since it's likely to be an OLED screen) */ +@media only screen and (hover: none) and (pointer: coarse) and (prefers-color-scheme: dark) { + html { + background: #000; + color: #CCC; + } +} diff --git a/bundles/meson.build b/bundles/meson.build new file mode 100644 index 00000000..2d02d953 --- /dev/null +++ b/bundles/meson.build @@ -0,0 +1,4 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +subdir('ingen.lv2') diff --git a/icons/meson.build b/icons/meson.build new file mode 100644 index 00000000..93a97bc8 --- /dev/null +++ b/icons/meson.build @@ -0,0 +1,23 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +png_icon_sizes = [ + '16x16', + '22x22', + '24x24', + '32x32', + '48x48', + '64x64', + '128x128', + '256x256', +] + +icons_dir = get_option('prefix') / get_option('datadir') / 'icons' / 'hicolor' + +install_data('scalable/ingen.svg', + install_dir: icons_dir / 'scalable' / 'apps') + +foreach size : png_icon_sizes + install_data(files(size / 'ingen.png'), + install_dir: icons_dir / size / 'apps') +endforeach diff --git a/include/ingen/FilePath.hpp b/include/ingen/FilePath.hpp index 392b336a..6f0266a7 100644 --- a/include/ingen/FilePath.hpp +++ b/include/ingen/FilePath.hpp @@ -26,8 +26,12 @@ #include <string> #include <utility> -#if defined(_WIN32) && !defined(__CYGWIN__) -#define USE_WINDOWS_FILE_PATHS 1 +#ifndef USE_WINDOWS_FILE_PATHS +# if defined(_WIN32) && !defined(__CYGWIN__) +# define USE_WINDOWS_FILE_PATHS 1 +# else +# define USE_WINDOWS_FILE_PATHS 0 +# endif #endif namespace ingen { @@ -41,7 +45,7 @@ namespace ingen { class INGEN_API FilePath { public: -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS using value_type = wchar_t; static constexpr value_type preferred_separator = L'\\'; #else diff --git a/include/ingen/filesystem.hpp b/include/ingen/filesystem.hpp index abe7684e..5e64cc8c 100644 --- a/include/ingen/filesystem.hpp +++ b/include/ingen/filesystem.hpp @@ -17,9 +17,6 @@ #ifndef INGEN_FILESYSTEM_HPP #define INGEN_FILESYSTEM_HPP -#define _BSD_SOURCE 1 -#define _DEFAULT_SOURCE 1 - #include "ingen/FilePath.hpp" #ifdef _WIN32 diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..619d2189 --- /dev/null +++ b/meson.build @@ -0,0 +1,206 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +project('ingen', 'cpp', + version: '0.5.1', + license: 'GPLv3+', + meson_version: '>= 0.56.0', + default_options: [ + 'b_ndebug=if-release', + 'buildtype=release', + 'cpp_std=c++14', + ]) + +ingen_src_root = meson.current_source_dir() +ingen_build_root = meson.current_build_dir() +major_version = meson.project_version().split('.')[0] +versioned_name = '@0@-@1@'.format(meson.project_name(), major_version) + +####################### +# Compilers and Flags # +####################### + +# Required tools +cpp = meson.get_compiler('cpp') + +# Set global warning flags +if get_option('strict') and not meson.is_subproject() + subdir('meson/warnings') +endif + +# Set global warning suppressions +subdir('meson/suppressions') +add_project_arguments(cpp_suppressions, language: ['cpp']) + +########################## +# LV2 Path Configuration # +########################## + +lv2dir = get_option('lv2dir') +if lv2dir == '' + prefix = get_option('prefix') + if target_machine.system() == 'darwin' and prefix == '/' + lv2dir = '/Library/Audio/Plug-Ins/LV2' + elif target_machine.system() == 'haiku' and prefix == '/' + lv2dir = '/boot/common/add-ons/lv2' + elif target_machine.system() == 'windows' and prefix == 'C:/' + lv2dir = 'C:/Program Files/Common/LV2' + else + lv2dir = prefix / get_option('libdir') / 'lv2' + endif +endif + +########################## +# Platform Configuration # +########################## + +# TODO: Distinguish modules from libraries and move modules to a subdirectory +ingen_data_dir = get_option('prefix') / get_option('datadir') / 'ingen' # / versioned_name +ingen_module_dir = get_option('prefix') / get_option('libdir') # / versioned_name + +platform_defines = [ + '-DINGEN_DATA_DIR="@0@"'.format(ingen_data_dir), + '-DINGEN_MODULE_DIR="@0@"'.format(ingen_module_dir), + '-DINGEN_VERSION="@0@"'.format(meson.project_version()), +] + +if host_machine.system() == 'darwin' + platform_defines += [ + '-D_DARWIN_C_SOURCE', + '-D_POSIX_C_SOURCE=200809L', + ] +elif host_machine.system() == 'windows' + platform_defines += [ + '-DINGEN_NO_POSIX', + ] +elif host_machine.system() in ['gnu', 'linux'] + platform_defines += [ + '-D_POSIX_C_SOURCE=200809L', + '-D_XOPEN_SOURCE=600', + ] +endif + +socket_code = '''#include <sys/socket.h> +int main(void) { return socket(AF_UNIX, SOCK_STREAM, 0); }''' + +have_socket = cpp.compiles(socket_code, + args: platform_defines, + name: 'socket') + +platform_defines += ['-DHAVE_SOCKET=@0@'.format(have_socket.to_int())] + +####################### +# Common Dependencies # +####################### + +boost_dep = dependency('boost') +thread_dep = dependency('threads') + +serd_dep = dependency('serd-0', + version: '>= 0.30.4', + fallback: ['serd', 'serd_dep']) + +sord_dep = dependency('sord-0', + version: '>= 0.16.0', + fallback: ['sord', 'sord_dep']) + +sratom_dep = dependency('sratom-0', + version: '>= 0.6.0', + fallback: ['sratom', 'sratom_dep']) + +suil_dep = dependency('suil-0', + version: '>= 0.10.0', + fallback: ['suil', 'suil_dep']) + +lv2_dep = dependency('lv2', + version: '>= 1.18.0', + fallback: ['lv2', 'lv2_dep']) + +lilv_dep = dependency('lilv-0', + version: '>= 0.24.0', + fallback: ['lilv', 'lilv_dep']) + +raul_dep = dependency('raul-2', + version: '>= 2.0.0', + fallback: ['raul', 'raul_dep']) + +####################### +# Driver Dependencies # +####################### + +portaudio_dep = dependency('portaudio-2.0', + version: '>= 2.0.0', + include_type: 'system', + required: get_option('portaudio')) + +jack_dep = dependency('jack', + version: '>= 0.120.0', + include_type: 'system', + required: get_option('jack')) + +jack_port_rename_code = '''#include <jack/jack.h> +int main(void) { return !!&jack_port_rename; }''' + +platform_defines += '-DHAVE_JACK_PORT_RENAME=@0@'.format( + cpp.compiles(jack_port_rename_code, + args: platform_defines, + dependencies: [jack_dep], + name: 'jack_port_rename').to_int()) + +############# +# Libraries # +############# + +# Set appropriate arguments for building against the library type +subdir('meson/library') +if get_option('default_library') == 'static' + add_project_arguments(['-DINGEN_STATIC'], language: ['cpp']) +endif + +subdir('src') + +######################## +# Programs and Scripts # +######################## + +executable( + 'ingen', + files('src/ingen/ingen.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep, raul_dep, serd_dep], + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, +) + +install_man(files('doc/ingen.1')) + +subdir('scripts') + +######## +# Data # +######## + +install_data( + files('src/ingen/ingen.desktop'), + install_dir: get_option('datadir') / 'applications', +) + +subdir('bundles') +subdir('icons') + +######### +# Tests # +######### + +subdir('tests') + +if not meson.is_subproject() + summary('Install prefix', get_option('prefix')) + + summary('Data', ingen_data_dir) + summary('Executables', get_option('prefix') / get_option('bindir')) + summary('LV2 bundles', lv2dir) + summary('Man pages', get_option('prefix') / get_option('mandir')) + summary('Modules', ingen_module_dir) +endif diff --git a/meson/library/meson.build b/meson/library/meson.build new file mode 100644 index 00000000..e9c472d8 --- /dev/null +++ b/meson/library/meson.build @@ -0,0 +1,31 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +# General definitions for building libraries. +# +# These are essentially workarounds for Meson/Windows/MSVC. Unfortunately, +# Meson's default_library option doesn't support shared and static builds very +# well. In particular, it's often necessary to define different symbols for +# static and shared builds of libraries so that symbols can be exported. To +# work around this, default_library=both isn't supported on Windows. On other +# platforms with GCC-like compilers, we can support both because symbols can +# safely be exported in the same way (giving them default visibility) in both +# static and shared builds. + +default_library = get_option('default_library') +host_system = host_machine.system() + +# Abort on Windows with default_library=both +if host_system == 'windows' and default_library == 'both' + error('default_library=both is not supported on Windows') +endif + +# Set library_suffix to the suffix for libraries +if host_system == 'windows' and default_library == 'shared' + # Meson appends a version to the name only for DLLs, which leads to + # inconsistent library names, like `mylib-1-1`. So, provide no suffix to + # ultimately get the same name as on other platforms, like `mylib-1`. + library_suffix = '' +else + library_suffix = '-@0@'.format(meson.project_version().split('.')[0]) +endif diff --git a/meson/suppressions/meson.build b/meson/suppressions/meson.build new file mode 100644 index 00000000..71b915b7 --- /dev/null +++ b/meson/suppressions/meson.build @@ -0,0 +1,104 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +# Project-specific warning suppressions. +# +# This should be used in conjunction with the generic "warnings" sibling that +# enables all reasonable warnings for the compiler. It lives here just to keep +# the top-level meson.build more readable. + +####### +# C++ # +####### + +if is_variable('cpp') + cpp_suppressions = [] + + if get_option('strict') + if cpp.get_id() == 'clang' + cpp_suppressions = [ + '-Wno-c++17-extensions', + '-Wno-cast-align', + '-Wno-cast-qual', + '-Wno-documentation-unknown-command', + '-Wno-exit-time-destructors', + '-Wno-float-conversion', + '-Wno-float-equal', + '-Wno-format-nonliteral', + '-Wno-global-constructors', + '-Wno-implicit-float-conversion', + '-Wno-implicit-int-conversion', + '-Wno-nullability-extension', + '-Wno-nullable-to-nonnull-conversion', + '-Wno-padded', + '-Wno-reserved-id-macro', + '-Wno-shadow-field', + '-Wno-shorten-64-to-32', + '-Wno-sign-conversion', + '-Wno-switch-enum', + '-Wno-unreachable-code', + '-Wno-unused-parameter', + '-Wno-vla', + '-Wno-vla-extension', + '-Wno-weak-vtables', + ] + + if host_machine.system() in ['darwin', 'freebsd'] + cpp_suppressions += [ + '-Wno-comma', # boost + '-Wno-deprecated-copy', # boost + '-Wno-disabled-macro-expansion', # boost + '-Wno-documentation', # JACK + '-Wno-documentation-deprecated-sync', # JACK + '-Wno-extra-semi-stmt', # boost + '-Wno-old-style-cast', # boost + '-Wno-redundant-parens', # boost + '-Wno-suggest-destructor-override', # boost + '-Wno-suggest-override', # boost + '-Wno-unused-template', # boost + '-Wno-zero-as-null-pointer-constant', # boost + ] + endif + + elif cpp.get_id() == 'gcc' + cpp_suppressions = [ + '-Wno-abi-tag', + '-Wno-alloc-zero', + '-Wno-cast-align', + '-Wno-cast-qual', + '-Wno-conditionally-supported', + '-Wno-conversion', + '-Wno-effc++', + '-Wno-float-conversion', + '-Wno-float-equal', + '-Wno-format', + '-Wno-format-nonliteral', + '-Wno-format-truncation', + '-Wno-inline', + '-Wno-multiple-inheritance', + '-Wno-null-dereference', + '-Wno-old-style-cast', + '-Wno-padded', + '-Wno-redundant-tags', + '-Wno-sign-conversion', + '-Wno-stack-protector', + '-Wno-strict-overflow', + '-Wno-suggest-attribute=const', + '-Wno-suggest-attribute=format', + '-Wno-suggest-attribute=pure', + '-Wno-suggest-final-methods', + '-Wno-suggest-final-types', + '-Wno-suggest-override', + '-Wno-switch-default', + '-Wno-switch-enum', + '-Wno-unreachable-code', + '-Wno-unused-const-variable', + '-Wno-unused-parameter', + '-Wno-useless-cast', + '-Wno-vla', + ] + endif + endif + + cpp_suppressions = cpp.get_supported_arguments(cpp_suppressions) +endif diff --git a/meson/warnings/meson.build b/meson/warnings/meson.build new file mode 100644 index 00000000..fcf06ec8 --- /dev/null +++ b/meson/warnings/meson.build @@ -0,0 +1,188 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +# General code to enable approximately all warnings in GCC 12, clang, and MSVC. +# +# This is trivial for clang and MSVC, but GCC doesn't have an "everything" +# option, so we need to enable everything we want explicitly. Wall is assumed, +# but Wextra is not, for stability. +# +# These are collected from common.opt and c.opt in the GCC source, and manually +# curated with the help of the GCC documentation. Warnings that are +# application-specific, historical, or about compatibility between specific +# language revisions are omitted. The intent here is to have roughly the same +# meaning as clang's Weverything: extremely strict, but general. Specifically +# omitted are: +# +# General: +# +# 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 +# +# Build specific: +# +# Wpoison-system-directories +# +# C++ Specific: +# +# Wc++0x-compat +# Wc++1z-compat +# Wc++2a-compat +# Wctad-maybe-unsupported +# Wnamespaces +# Wtemplates + +gcc_common_warnings = [ + '-Walloc-zero', + '-Walloca', + '-Wanalyzer-too-complex', + '-Warith-conversion', + '-Warray-bounds=2', + '-Wattribute-alias=2', + '-Wbidi-chars=ucn', + '-Wcast-align=strict', + '-Wcast-function-type', + '-Wcast-qual', + '-Wclobbered', + '-Wconversion', + '-Wdate-time', + '-Wdisabled-optimization', + '-Wdouble-promotion', + '-Wduplicated-branches', + '-Wduplicated-cond', + '-Wempty-body', + '-Wendif-labels', + '-Wfloat-equal', + '-Wformat-overflow=2', + '-Wformat-signedness', + '-Wformat-truncation=2', + '-Wformat=2', + '-Wignored-qualifiers', + '-Wimplicit-fallthrough=3', + '-Winit-self', + '-Winline', + '-Winvalid-pch', + '-Wlogical-op', + '-Wmissing-declarations', + '-Wmissing-field-initializers', + '-Wmissing-include-dirs', + '-Wmultichar', + '-Wnormalized=nfc', + '-Wnull-dereference', + '-Wopenacc-parallelism', + '-Woverlength-strings', + '-Wpacked', + '-Wpacked-bitfield-compat', + '-Wpadded', + '-Wpointer-arith', + '-Wredundant-decls', + '-Wshadow', + '-Wshift-negative-value', + '-Wshift-overflow=2', + '-Wstack-protector', + '-Wstrict-aliasing=3', + '-Wstrict-overflow=5', + '-Wstring-compare', + '-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', + '-Wtrampolines', + '-Wtrivial-auto-var-init', + '-Wtype-limits', + '-Wundef', + '-Wuninitialized', + '-Wunsafe-loop-optimizations', + '-Wunused', + '-Wunused-const-variable=2', + '-Wunused-macros', + '-Wvector-operation-performance', + '-Wvla', + '-Wwrite-strings', +] + +####### +# C++ # +####### + +if is_variable('cpp') + all_cpp_warnings = [] + + if cpp.get_id() == 'clang' + all_cpp_warnings += [ + '-Weverything', + '-Wno-c++98-compat', + '-Wno-c++98-compat-pedantic' + ] + + if not meson.is_cross_build() + all_cpp_warnings += [ + '-Wno-poison-system-directories', + ] + endif + + 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', + '-Wdelete-non-virtual-dtor', + '-Wdeprecated', + '-Wdeprecated-copy', + '-Wdeprecated-copy-dtor', + '-Wdeprecated-enum-enum-conversion', + '-Wdeprecated-enum-float-conversion', + '-Weffc++', + '-Wexpansion-to-defined', + '-Wextra-semi', + '-Wimport', + '-Winvalid-imported-macros', + '-Wmismatched-tags', + '-Wmultiple-inheritance', + '-Wnoexcept', + '-Wnoexcept-type', + '-Wnon-virtual-dtor', + '-Wold-style-cast', + '-Woverloaded-virtual', + '-Wplacement-new=2', + '-Wredundant-move', + '-Wredundant-tags', + '-Wregister', + '-Wsign-compare', + '-Wsign-promo', + '-Wsized-deallocation', + '-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'] + endif + + all_cpp_warnings = cpp.get_supported_arguments(all_cpp_warnings) + add_global_arguments(all_cpp_warnings, language: ['cpp']) +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..624285f1 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,26 @@ +option('bindings_py', type: 'feature', value: 'auto', yield: true, + description: 'Build Python bindings') + +option('checks', type: 'boolean', value: true, yield: true, + description: 'Check for features with the build system') + +option('docs', type: 'feature', value: 'auto', yield: true, + description: 'Build documentation') + +option('gui', type: 'feature', value: 'auto', yield: true, + description: 'Build GUI') + +option('jack', type: 'feature', value: 'auto', yield: true, + description: 'Build JACK audio and MIDI support') + +option('lv2dir', type: 'string', value: '', yield: true, + description: 'LV2 bundle installation directory') + +option('portaudio', type: 'feature', value: 'auto', yield: true, + description: 'Build PortAudio driver') + +option('strict', type: 'boolean', value: false, yield: true, + description: 'Enable ultra-strict warnings') + +option('title', type: 'string', value: 'Ingen', + description: 'Project title') diff --git a/scripts/meson.build b/scripts/meson.build new file mode 100644 index 00000000..10ae15d5 --- /dev/null +++ b/scripts/meson.build @@ -0,0 +1,22 @@ +# Copyright 2020-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +scripts = files( + 'ingenams', + 'ingenish', +) + +foreach script : scripts + install_data( + script, + install_dir: get_option('bindir'), + install_mode: 'rwxr-xr-x', + ) +endforeach + +pymod = import('python') +py = pymod.find_installation('python3', required: get_option('bindings_py')) + +if py.found() + py.install_sources(files('ingen.py')) +endif diff --git a/src/ColorContext.cpp b/src/ColorContext.cpp index ac797518..827395f2 100644 --- a/src/ColorContext.cpp +++ b/src/ColorContext.cpp @@ -17,7 +17,7 @@ #include "ingen/ColorContext.hpp" #include "ingen_config.h" -#ifdef HAVE_ISATTY +#if USE_ISATTY # include <unistd.h> #else inline int isatty(int fd) { return 0; } diff --git a/src/FilePath.cpp b/src/FilePath.cpp index d16c133c..f8da196e 100644 --- a/src/FilePath.cpp +++ b/src/FilePath.cpp @@ -26,7 +26,7 @@ template <typename Char> static bool is_sep(const Char chr) { -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS return chr == L'/' || chr == preferred_separator; #else return chr == '/'; @@ -98,7 +98,7 @@ FilePath::operator+=(boost::basic_string_view<value_type> sv) FilePath FilePath::root_name() { -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS if (_str.length() >= 2 && _str[0] >= 'A' && _str[0] <= 'Z' && _str[1] == ':') { return FilePath(_str.substr(0, 2)); @@ -111,7 +111,7 @@ FilePath::root_name() FilePath FilePath::root_directory() const { -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS const auto name = root_name().string(); return name.empty() ? Path() : Path(name + preferred_separator); #endif @@ -122,7 +122,7 @@ FilePath::root_directory() const FilePath FilePath::root_path() const { -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS const auto name = root_name(); return name.empty() ? FilePath() : name / root_directory(); #endif @@ -180,7 +180,7 @@ FilePath::extension() const bool FilePath::is_absolute() const { -#ifdef USE_WINDOWS_FILE_PATHS +#if USE_WINDOWS_FILE_PATHS return !root_name().empty(); #else return !root_directory().empty(); diff --git a/src/client/meson.build b/src/client/meson.build new file mode 100644 index 00000000..b77211d2 --- /dev/null +++ b/src/client/meson.build @@ -0,0 +1,50 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +################ +# Dependencies # +################ + +sigcpp_dep = dependency('sigc++-2.0', include_type: 'system') + +########## +# Module # +########## + +client_sources = files( + 'BlockModel.cpp', + 'ClientStore.cpp', + 'GraphModel.cpp', + 'ObjectModel.cpp', + 'PluginModel.cpp', + 'PluginUI.cpp', + 'PortModel.cpp', + 'ingen_client.cpp', +) + +client_dependencies = [ + boost_dep, + ingen_dep, + lilv_dep, + lv2_dep, + raul_dep, + sigcpp_dep, + suil_dep, +] + +libingen_client = shared_library( + 'ingen_client', + client_sources, + cpp_args: cpp_suppressions + platform_defines + ['-DINGEN_CLIENT_INTERNAL'], + dependencies: client_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, +) + +ingen_client_dep = declare_dependency( + dependencies: client_dependencies, + link_with: libingen_client, +) diff --git a/src/client/wscript b/src/client/wscript deleted file mode 100644 index d63fb56c..00000000 --- a/src/client/wscript +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - includes = ['../../', '../../include'], - export_includes = ['../../include'], - name = 'libingen_client', - target = 'ingen_client', - install_path = '${LIBDIR}', - use = 'libingen', - uselib = 'GLIBMM LV2 LILV SUIL RAUL SERD SORD SIGCPP') - - obj.source = ''' - BlockModel.cpp - ClientStore.cpp - GraphModel.cpp - ObjectModel.cpp - PluginModel.cpp - PluginUI.cpp - PortModel.cpp - ingen_client.cpp - ''' diff --git a/src/gui/GraphBox.cpp b/src/gui/GraphBox.cpp index f994d47c..ee3013b1 100644 --- a/src/gui/GraphBox.cpp +++ b/src/gui/GraphBox.cpp @@ -27,6 +27,7 @@ #include "ThreadedLoader.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" +#include "ingen_config.h" #include "ganv/canvas.h" #include "ingen/Atom.hpp" @@ -87,8 +88,8 @@ #include <sigc++/functors/mem_fun.h> #include <sigc++/signal.h> -#ifdef HAVE_WEBKIT -#include <webkit/webkit.h> +#if USE_WEBKIT +# include <webkit/webkit.h> #endif #include <cassert> @@ -449,7 +450,7 @@ GraphBox::set_documentation(const std::string& doc, bool html) _doc_scrolledwindow->hide(); return; } -#ifdef HAVE_WEBKIT +#if USE_WEBKIT WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new()); webkit_web_view_load_html_string(view, doc.c_str(), ""); Gtk::Widget* widget = Gtk::manage(Glib::wrap(GTK_WIDGET(view))); diff --git a/src/gui/MessagesWindow.cpp b/src/gui/MessagesWindow.cpp index 2e0fdb61..9127ad61 100644 --- a/src/gui/MessagesWindow.cpp +++ b/src/gui/MessagesWindow.cpp @@ -18,6 +18,7 @@ #include "App.hpp" #include "Window.hpp" +#include "ingen_config.h" #include "ingen/URIs.hpp" #include "lv2/urid/urid.h" @@ -102,7 +103,7 @@ MessagesWindow::log(LV2_URID type, const char* fmt, va_list args) { std::lock_guard<std::mutex> lock(_mutex); -#ifdef HAVE_VASPRINTF +#if USE_VASPRINTF char* buf = nullptr; const int len = vasprintf(&buf, fmt, args); #else diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp index fe111572..1dbd1cd9 100644 --- a/src/gui/NodeModule.cpp +++ b/src/gui/NodeModule.cpp @@ -25,6 +25,7 @@ #include "SubgraphModule.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" +#include "ingen_config.h" #include "ganv/Port.hpp" #include "ingen/Atom.hpp" @@ -531,7 +532,7 @@ NodeModule::on_selected(gboolean selected) if (selected && win->documentation_is_visible()) { std::string doc; bool html = false; -#ifdef HAVE_WEBKIT +#if USE_WEBKIT html = true; #endif if (block()->plugin_model()) { diff --git a/src/gui/Port.cpp b/src/gui/Port.cpp index 65b415e3..87cb3ef1 100644 --- a/src/gui/Port.cpp +++ b/src/gui/Port.cpp @@ -24,6 +24,7 @@ #include "Style.hpp" #include "WidgetFactory.hpp" #include "WindowFactory.hpp" +#include "ingen_config.h" #include "rgba.hpp" #include "ingen/Atom.hpp" @@ -551,7 +552,7 @@ Port::on_selected(gboolean b) GraphWindow* win = _app.window_factory()->parent_graph_window(block); if (win && win->documentation_is_visible() && block->plugin_model()) { bool html = false; -#ifdef HAVE_WEBKIT +#if USE_WEBKIT html = true; #endif const std::string& doc = block->plugin_model()->port_documentation( diff --git a/src/gui/WindowFactory.cpp b/src/gui/WindowFactory.cpp index 153fb4f6..ae396b61 100644 --- a/src/gui/WindowFactory.cpp +++ b/src/gui/WindowFactory.cpp @@ -14,8 +14,11 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include "WindowFactory.hpp" + #include "App.hpp" #include "GraphBox.hpp" +#include "GraphView.hpp" #include "GraphWindow.hpp" #include "LoadGraphWindow.hpp" #include "LoadPluginWindow.hpp" @@ -23,7 +26,6 @@ #include "PropertiesWindow.hpp" #include "RenameWindow.hpp" #include "WidgetFactory.hpp" -#include "WindowFactory.hpp" #include "ingen/Log.hpp" #include "ingen/client/BlockModel.hpp" diff --git a/src/gui/ingen_gui.ui b/src/gui/ingen_gui.ui.in index 9e751064..9e751064 100644 --- a/src/gui/ingen_gui.ui +++ b/src/gui/ingen_gui.ui.in diff --git a/src/gui/meson.build b/src/gui/meson.build new file mode 100644 index 00000000..64192b28 --- /dev/null +++ b/src/gui/meson.build @@ -0,0 +1,163 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +################ +# Dependencies # +################ + +gui_defines = platform_defines + +glibmm_dep = dependency('glibmm-2.4', + version: '>= 2.14.0', + include_type: 'system', + required: get_option('gui')) + +gthread_dep = dependency('gthread-2.0', + version: '>= 2.14.0', + include_type: 'system', + required: get_option('gui')) + +gtkmm_dep = dependency('gtkmm-2.4', + version: '>= 2.14.0', + include_type: 'system', + required: get_option('gui')) + +ganv_dep = dependency('ganv-1', + version: '>= 1.5.2', + fallback: ['ganv', 'ganv_dep'], + required: get_option('gui')) + +webkit_dep = dependency('webkit-1.0', + version: '>= 1.4.0', + include_type: 'system', + required: false) + +build_gui = (glibmm_dep.found() and + gthread_dep.found() and + gtkmm_dep.found() and + ganv_dep.found()) + +if webkit_dep.found() + gui_defines += ['-DHAVE_WEBKIT=1'] +else + gui_defines += ['-DHAVE_WEBKIT=0'] +endif + +########## +# Module # +########## + +if build_gui + gui_sources = files( + 'App.cpp', + 'Arc.cpp', + 'BreadCrumbs.cpp', + 'ConnectWindow.cpp', + 'GraphBox.cpp', + 'GraphCanvas.cpp', + 'GraphPortModule.cpp', + 'GraphTreeWindow.cpp', + 'GraphView.cpp', + 'GraphWindow.cpp', + 'LoadGraphWindow.cpp', + 'LoadPluginWindow.cpp', + 'MessagesWindow.cpp', + 'NewSubgraphWindow.cpp', + 'NodeMenu.cpp', + 'NodeModule.cpp', + 'ObjectMenu.cpp', + 'PluginMenu.cpp', + 'Port.cpp', + 'PortMenu.cpp', + 'PropertiesWindow.cpp', + 'RDFS.cpp', + 'RenameWindow.cpp', + 'Style.cpp', + 'SubgraphModule.cpp', + 'ThreadedLoader.cpp', + 'URIEntry.cpp', + 'WidgetFactory.cpp', + 'WindowFactory.cpp', + 'ingen_gui.cpp', + ) + + gui_dependencies = [ + boost_dep, + ganv_dep, + glibmm_dep, + gthread_dep, + gtkmm_dep, + ingen_client_dep, + ingen_dep, + lilv_dep, + raul_dep, + sigcpp_dep, + suil_dep, + thread_dep, + webkit_dep, + ] + + gui_suppressions = [] + if cpp.get_id() == 'clang' + gui_suppressions += [ + '-Wno-reserved-identifier', # Ganv + ] + endif + + gui_suppressions = cpp.get_supported_arguments(gui_suppressions) + gui_suppressions += cpp_suppressions + + gui_args = gui_suppressions + gui_defines + ['-DINGEN_GUI_INTERNAL'] + + libingen_gui = shared_library( + 'ingen_gui', + gui_sources, + cpp_args: gui_args, + dependencies: gui_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) + + ingen_gui_dep = declare_dependency( + dependencies: gui_dependencies, + link_with: libingen_gui, + ) + + ########## + # LV2 UI # + ########## + + ingen_gui_lv2 = shared_library( + 'ingen_gui_lv2', + files('ingen_gui_lv2.cpp'), + cpp_args: gui_args, + dependencies: [ingen_gui_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: lv2dir / 'ingen.lv2', + ) + + ############### + # Shared Data # + ############### + + config = configuration_data() + config.set('INGEN_VERSION', meson.project_version()) + + configure_file(configuration: config, + input: files('ingen_gui.ui.in'), + output: 'ingen_gui.ui', + install: true, + install_dir: ingen_data_dir) + + configure_file(copy: true, + input: files('ingen_style.rc'), + output: '@PLAINNAME@', + install: true, + install_dir: ingen_data_dir) +endif diff --git a/src/gui/wscript b/src/gui/wscript deleted file mode 100644 index f2471933..00000000 --- a/src/gui/wscript +++ /dev/null @@ -1,127 +0,0 @@ -#!/usr/bin/env python - -import waflib.Utils as Utils -import waflib.Options as Options - - -def options(ctx): - opt = ctx.configuration_options() - opt.add_option('--light-theme', action='store_true', dest='light_theme', - help='use light coloured theme') - - -def configure(conf): - conf.check_pkg('glibmm-2.4 >= 2.14.0', - uselib_store='GLIBMM', - system=True, - mandatory=False) - conf.check_pkg('gthread-2.0 >= 2.14.0', - uselib_store='GTHREAD', - system=True, - mandatory=False) - conf.check_pkg('gtkmm-2.4 >= 2.14.0', - uselib_store='GTKMM', - system=True, - mandatory=False) - conf.check_pkg('ganv-1 >= 1.5.4', - uselib_store='GANV', - mandatory=False) - if not Options.options.no_webkit: - conf.check_pkg('webkit-1.0 >= 1.4.0', - uselib_store='WEBKIT', - system=True, - mandatory=False) - - if conf.env.HAVE_GANV and conf.env.HAVE_GTKMM: - conf.env.INGEN_BUILD_GUI = 1 - - if Options.options.light_theme: - conf.define('INGEN_USE_LIGHT_THEME', 1) - - -def build(bld): - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - export_includes = ['../../include'], - includes = ['../../', '../../include'], - name = 'libingen_gui', - target = 'ingen_gui', - install_path = '${LIBDIR}', - use = 'libingen libingen_client', - uselib = ''' - GANV - GLADEMM - GLIBMM - GNOMECANVAS - GTKMM - LILV - LV2 - RAUL - SIGCPP - SERD - SORD - SRATOM - SOUP - SUIL - WEBKIT - ''') - - obj.source = ''' - App.cpp - Arc.cpp - BreadCrumbs.cpp - ConnectWindow.cpp - GraphBox.cpp - GraphCanvas.cpp - GraphPortModule.cpp - GraphTreeWindow.cpp - GraphView.cpp - GraphWindow.cpp - LoadGraphWindow.cpp - LoadPluginWindow.cpp - MessagesWindow.cpp - NewSubgraphWindow.cpp - NodeMenu.cpp - NodeModule.cpp - ObjectMenu.cpp - PluginMenu.cpp - Port.cpp - PortMenu.cpp - PropertiesWindow.cpp - RDFS.cpp - RenameWindow.cpp - Style.cpp - SubgraphModule.cpp - ThreadedLoader.cpp - URIEntry.cpp - WidgetFactory.cpp - WindowFactory.cpp - ingen_gui.cpp - ''' - - # XML UI definition - bld(features = 'subst', - source = 'ingen_gui.ui', - target = '../../ingen_gui.ui', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755, - INGEN_VERSION = bld.env.INGEN_VERSION) - - # Gtk style - bld(features = 'subst', - is_copy = True, - source = 'ingen_style.rc', - target = '../../ingen_style.rc', - install_path = '${DATADIR}/ingen', - chmod = Utils.O755) - - # LV2 UI - obj = bld(features = 'cxx cxxshlib', - cflags = ['-fvisibility=hidden'], - source = 'ingen_gui_lv2.cpp', - includes = ['.', '../../', '../../include'], - name = 'ingen_gui_lv2', - target = 'ingen_gui_lv2', - install_path = '${LV2DIR}/ingen.lv2/', - use = 'libingen libingen_gui', - uselib = 'LV2 SERD SORD SRATOM LILV RAUL GLIBMM GTKMM') diff --git a/src/include/ingen_config.h b/src/include/ingen_config.h new file mode 100644 index 00000000..6d5f36e0 --- /dev/null +++ b/src/include/ingen_config.h @@ -0,0 +1,216 @@ +// Copyright 2021-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +/* + Configuration header that defines reasonable defaults at compile time. + + This allows compile-time configuration from the command line, while still + allowing the source to be built "as-is" without any configuration. The idea + is to support an advanced build system with configuration checks, while still + allowing the code to be simply "thrown at a compiler" with features + determined from the compiler or system headers. Everything can be + overridden, so it should never be necessary to edit this file to build + successfully. + + To ensure that all configure checks are performed, the build system can + define INGEN_NO_DEFAULT_CONFIG to disable defaults. In this case, it must + define all HAVE_FEATURE symbols below to 1 or 0 to enable or disable + features. Any missing definitions will generate a compiler warning. + + To ensure that this header is always included properly, all code that uses + configuration variables includes this header and checks their value with #if + (not #ifdef). Variables like USE_FEATURE are internal and should never be + defined on the command line. +*/ + +#ifndef INGEN_CONFIG_H +#define INGEN_CONFIG_H + +// Define version unconditionally so a warning will catch a mismatch +#define INGEN_VERSION "0.5.1" + +#if !defined(INGEN_NO_DEFAULT_CONFIG) + +// We need unistd.h to check _POSIX_VERSION +# ifndef INGEN_NO_POSIX +# ifdef __has_include +# if __has_include(<unistd.h>) +# include <unistd.h> +# endif +# elif defined(__unix__) +# include <unistd.h> +# endif +# endif + +// POSIX.1-2001: fileno() +# ifndef HAVE_FILENO +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_FILENO 1 +# else +# define HAVE_FILENO 0 +# endif +# endif + +// POSIX.1-2001: isatty() +# ifndef HAVE_ISATTY +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_ISATTY 1 +# else +# define HAVE_ISATTY 0 +# endif +# endif + +// POSIX.1-2001: posix_memalign() +# ifndef HAVE_POSIX_MEMALIGN +# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L +# define HAVE_POSIX_MEMALIGN 1 +# else +# define HAVE_POSIX_MEMALIGN 0 +# endif +# endif + +// BSD and GNU: vasprintf() +# ifndef HAVE_VASPRINTF +# if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +# define HAVE_VASPRINTF 1 +# else +# define HAVE_VASPRINTF 0 +# endif +# endif + +// JACK +# ifndef HAVE_JACK +# ifdef __has_include +# if __has_include("jack/jack.h") +# define HAVE_JACK 1 +# else +# define HAVE_JACK 0 +# endif +# else +# define HAVE_JACK 0 +# endif +# endif + +// JACK metadata API +# ifndef HAVE_JACK_METADATA +# ifdef __has_include +# if __has_include("jack/metadata.h") +# define HAVE_JACK_METADATA 1 +# else +# define HAVE_JACK_METADATA 0 +# endif +# else +# define HAVE_JACK_METADATA 0 +# endif +# endif + +// JACK jack_port_rename() function +# ifndef HAVE_JACK_PORT_RENAME +# define HAVE_JACK_PORT_RENAME HAVE_JACK +# endif + +// BSD sockets +# ifndef HAVE_SOCKET +# ifdef __has_include +# if __has_include("sys/socket.h") +# define HAVE_SOCKET 1 +# else +# define HAVE_SOCKET 0 +# endif +# else +# define HAVE_SOCKET 0 +# endif +# endif + +// Webkit +# ifndef HAVE_WEBKIT +# ifdef __has_include +# if __has_include(<webkit/webkit.h>) +# define HAVE_WEBKIT 1 +# else +# define HAVE_WEBKIT 0 +# endif +# else +# define HAVE_WEBKIT 0 +# endif +# endif + +// Installation directories +# ifndef INGEN_DATA_DIR +# define INGEN_DATA_DIR "/usr/local/share/ingen" +# endif +# ifndef INGEN_MODULE_DIR +# define INGEN_MODULE_DIR "/usr/local/lib/ingen" +# endif +# ifndef INGEN_BUNDLE_DIR +# define INGEN_BUNDLE_DIR "/usr/local/lib/lv2/ingen.lv2" +# endif + +#endif // !defined(INGEN_NO_DEFAULT_CONFIG) + +/* + Make corresponding USE_FEATURE defines based on the HAVE_FEATURE defines from + above or the command line. The code checks for these using #if (not #ifdef), + so there will be an undefined warning if it checks for an unknown feature, + and this header is always required by any code that checks for features, even + if the build system defines them all. +*/ + +#if defined(HAVE_FILENO) +# define USE_FILENO HAVE_FILENO +#else +# define USE_FILENO 0 +#endif + +#if defined(HAVE_ISATTY) +# define USE_ISATTY HAVE_ISATTY +#else +# define USE_ISATTY 0 +#endif + +#if defined(HAVE_POSIX_MEMALIGN) +# define USE_POSIX_MEMALIGN HAVE_POSIX_MEMALIGN +#else +# define USE_POSIX_MEMALIGN 0 +#endif + +#if defined(HAVE_SOCKET) +# define USE_SOCKET HAVE_SOCKET +#else +# define USE_SOCKET 0 +#endif + +#if defined(HAVE_VASPRINTF) +# define USE_VASPRINTF HAVE_VASPRINTF +#else +# define USE_VASPRINTF 0 +#endif + +#if defined(HAVE_WEBKIT) +# define USE_WEBKIT HAVE_WEBKIT +#else +# define USE_WEBKIT 0 +#endif + +#if defined(HAVE_JACK_METADATA) +# define USE_JACK_METADATA HAVE_JACK_METADATA +#else +# define USE_JACK_METADATA 0 +#endif + +#if defined(HAVE_JACK_PORT_TYPE_GET_BUFFER_SIZE) +# define USE_JACK_PORT_TYPE_GET_BUFFER_SIZE \ + HAVE_JACK_PORT_TYPE_GET_BUFFER_SIZE +#else +# define USE_JACK_PORT_TYPE_GET_BUFFER_SIZE 0 +#endif + +#if defined(HAVE_JACK_PORT_RENAME) +# define USE_JACK_PORT_RENAME HAVE_JACK_PORT_RENAME +#else +# define USE_JACK_PORT_RENAME 0 +#endif + +#define INGEN_BUNDLED 0 + +#endif // INGEN_CONFIG_H diff --git a/src/ingen/ingen.cpp b/src/ingen/ingen.cpp index c7c3ef74..68ac2d7b 100644 --- a/src/ingen/ingen.cpp +++ b/src/ingen/ingen.cpp @@ -31,7 +31,7 @@ #include "raul/Symbol.hpp" #include "serd/serd.h" -#ifdef HAVE_SOCKET +#if USE_SOCKET #include "ingen/client/SocketClient.hpp" #endif @@ -134,7 +134,7 @@ run(int argc, char** argv) world->engine()->listen(); } -#ifdef HAVE_SOCKET +#if USE_SOCKET client::SocketClient::register_factories(*world); #endif diff --git a/src/meson.build b/src/meson.build new file mode 100644 index 00000000..25dc2fae --- /dev/null +++ b/src/meson.build @@ -0,0 +1,65 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +sources = files( + 'AtomReader.cpp', + 'AtomWriter.cpp', + 'ClashAvoider.cpp', + 'ColorContext.cpp', + 'Configuration.cpp', + 'FilePath.cpp', + 'Forge.cpp', + 'LV2Features.cpp', + 'Library.cpp', + 'Log.cpp', + 'Parser.cpp', + 'Resource.cpp', + 'Serialiser.cpp', + 'Store.cpp', + 'StreamWriter.cpp', + 'TurtleWriter.cpp', + 'URI.cpp', + 'URIMap.cpp', + 'URIs.cpp', + 'World.cpp', + 'runtime_paths.cpp' +) + +if have_socket + sources += files('SocketReader.cpp', 'SocketWriter.cpp') +endif + +ingen_deps = [ + boost_dep, + lilv_dep, + lv2_dep, + raul_dep, + serd_dep, + sord_dep, + sratom_dep, + thread_dep, +] + +ingen_include_dirs = include_directories('../include', 'include') + +libingen = shared_library( + 'ingen' + library_suffix, + sources, + cpp_args: cpp_suppressions + platform_defines, + dependencies: ingen_deps, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + version: meson.project_version(), +) + +ingen_dep = declare_dependency( + dependencies: ingen_deps, + include_directories: include_directories('../include'), + link_with: libingen, +) + +subdir('server') +subdir('client') +subdir('gui') diff --git a/src/runtime_paths.cpp b/src/runtime_paths.cpp index 38eb681f..b5723e94 100644 --- a/src/runtime_paths.cpp +++ b/src/runtime_paths.cpp @@ -70,7 +70,7 @@ set_bundle_path_from_code(void (*function)()) Dl_info dli; dladdr(reinterpret_cast<void*>(function), &dli); -#ifdef BUNDLE +#if INGEN_BUNDLED char bin_loc[PATH_MAX]; realpath(dli.dli_fname, bin_loc); #else @@ -117,7 +117,7 @@ data_file_path(const std::string& name) std::vector<FilePath> ingen_module_dirs() { -#ifdef BUNDLE +#if INGEN_BUNDLED const FilePath default_dir = FilePath(bundle_path) / INGEN_MODULE_DIR; #else const FilePath default_dir = INGEN_MODULE_DIR; @@ -186,7 +186,7 @@ data_dirs() std::vector<FilePath> paths = system_data_dirs(); const FilePath user_dir = user_data_dir(); -#ifdef BUNDLE +#if INGEN_BUNDLED paths.insert(paths.begin(), bundle_path / INGEN_DATA_DIR); #endif diff --git a/src/server/Buffer.cpp b/src/server/Buffer.cpp index deb167d9..7e14c354 100644 --- a/src/server/Buffer.cpp +++ b/src/server/Buffer.cpp @@ -19,6 +19,7 @@ #include "BufferFactory.hpp" #include "Engine.hpp" #include "RunContext.hpp" +#include "ingen_config.h" #include "ingen/Atom.hpp" #include "ingen/Log.hpp" @@ -432,7 +433,7 @@ Buffer::update_value_buffer(SampleCount offset) void* Buffer::aligned_alloc(size_t size) { -#ifdef HAVE_POSIX_MEMALIGN +#if USE_POSIX_MEMALIGN void* buf = nullptr; if (!posix_memalign(static_cast<void**>(&buf), 16, size)) { memset(buf, 0, size); diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp index b48b291f..5817bf6b 100644 --- a/src/server/Engine.cpp +++ b/src/server/Engine.cpp @@ -39,7 +39,7 @@ #include "events/CreateGraph.hpp" #include "ingen_config.h" -#ifdef HAVE_SOCKET +#if USE_SOCKET #include "SocketListener.hpp" #endif @@ -187,7 +187,7 @@ Engine::~Engine() void Engine::listen() { -#ifdef HAVE_SOCKET +#if USE_SOCKET _listener = std::make_unique<SocketListener>(*this); #endif } diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp index f03689cb..69b84fb3 100644 --- a/src/server/JackDriver.cpp +++ b/src/server/JackDriver.cpp @@ -44,7 +44,7 @@ #include <jack/midiport.h> #include <jack/transport.h> -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA #include "jackey.h" #include <jack/metadata.h> #endif @@ -271,7 +271,7 @@ JackDriver::rename_port(const raul::Path& old_path, { EnginePort* eport = get_port(old_path); if (eport) { -#ifdef HAVE_JACK_PORT_RENAME +#if USE_JACK_PORT_RENAME jack_port_rename(_client, static_cast<jack_port_t*>(eport->handle()), new_path.substr(1).c_str()); @@ -287,7 +287,7 @@ JackDriver::port_property(const raul::Path& path, const URI& uri, const Atom& value) { -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA EnginePort* eport = get_port(path); if (eport) { const auto* const jport = @@ -303,7 +303,7 @@ JackDriver::port_property_internal(const jack_port_t* jport, const URI& uri, const Atom& value) { -#ifdef HAVE_JACK_METADATA +#if USE_JACK_METADATA if (uri == _engine.world().uris().lv2_name) { jack_set_property(_client, jack_port_uuid(jport), JACK_METADATA_PRETTY_NAME, value.ptr<char>(), "text/plain"); diff --git a/src/server/meson.build b/src/server/meson.build new file mode 100644 index 00000000..b25bc084 --- /dev/null +++ b/src/server/meson.build @@ -0,0 +1,135 @@ +# Copyright 2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +########## +# Module # +########## + +server_sources = files( + 'ArcImpl.cpp', + 'BlockFactory.cpp', + 'BlockImpl.cpp', + 'Broadcaster.cpp', + 'Buffer.cpp', + 'BufferFactory.cpp', + 'ClientUpdate.cpp', + 'CompiledGraph.cpp', + 'ControlBindings.cpp', + 'DuplexPort.cpp', + 'Engine.cpp', + 'EventWriter.cpp', + 'GraphImpl.cpp', + 'InputPort.cpp', + 'InternalBlock.cpp', + 'InternalPlugin.cpp', + 'LV2Block.cpp', + 'LV2Plugin.cpp', + 'NodeImpl.cpp', + 'PortImpl.cpp', + 'PostProcessor.cpp', + 'PreProcessor.cpp', + 'RunContext.cpp', + 'SocketListener.cpp', + 'Task.cpp', + 'UndoStack.cpp', + 'Worker.cpp', + 'events/Connect.cpp', + 'events/Copy.cpp', + 'events/CreateBlock.cpp', + 'events/CreateGraph.cpp', + 'events/CreatePort.cpp', + 'events/Delete.cpp', + 'events/Delta.cpp', + 'events/Disconnect.cpp', + 'events/DisconnectAll.cpp', + 'events/Get.cpp', + 'events/Mark.cpp', + 'events/Move.cpp', + 'events/SetPortValue.cpp', + 'events/Undo.cpp', + 'ingen_engine.cpp', + 'internals/BlockDelay.cpp', + 'internals/Controller.cpp', + 'internals/Note.cpp', + 'internals/Time.cpp', + 'internals/Trigger.cpp', + 'mix.cpp', +) + +server_dependencies = [ + boost_dep, + ingen_dep, + lilv_dep, + raul_dep, + serd_dep, + sord_dep, + sratom_dep, + thread_dep, +] + +server_include_dirs = include_directories( + '.', + '../../include', + '../include', +) + +libingen_server = shared_library( + 'ingen_server', + server_sources, + cpp_args: cpp_suppressions + platform_defines + ['-DINGEN_SERVER_INTERNAL'], + dependencies: server_dependencies, + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: server_include_dirs, + install: true, + install_dir: ingen_module_dir, +) + +ingen_server_dep = declare_dependency( + dependencies: server_dependencies, + link_with: libingen_server, +) + +########### +# Drivers # +########### + +if jack_dep.found() + shared_module( + 'ingen_jack', + files('JackDriver.cpp', 'ingen_jack.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, jack_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) +endif + +if portaudio_dep.found() + shared_module( + 'ingen_portaudio', + files('PortAudioDriver.cpp', 'ingen_portaudio.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, portaudio_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: ingen_module_dir, + ) +endif + +shared_module( + 'ingen_lv2', + files('ingen_lv2.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_server_dep, lv2_dep], + gnu_symbol_visibility: 'hidden', + implicit_include_directories: false, + include_directories: ingen_include_dirs, + install: true, + install_dir: lv2dir / 'ingen.lv2', +) diff --git a/src/server/wscript b/src/server/wscript deleted file mode 100644 index 5fdf4583..00000000 --- a/src/server/wscript +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - core_source = ''' - ArcImpl.cpp - BlockFactory.cpp - BlockImpl.cpp - Broadcaster.cpp - Buffer.cpp - BufferFactory.cpp - CompiledGraph.cpp - ClientUpdate.cpp - ControlBindings.cpp - DuplexPort.cpp - Engine.cpp - EventWriter.cpp - GraphImpl.cpp - InputPort.cpp - InternalBlock.cpp - InternalPlugin.cpp - LV2Block.cpp - LV2Plugin.cpp - NodeImpl.cpp - PortImpl.cpp - PostProcessor.cpp - PreProcessor.cpp - RunContext.cpp - SocketListener.cpp - Task.cpp - UndoStack.cpp - Worker.cpp - events/Connect.cpp - events/Copy.cpp - events/CreateBlock.cpp - events/CreateGraph.cpp - events/CreatePort.cpp - events/Delete.cpp - events/Delta.cpp - events/Disconnect.cpp - events/DisconnectAll.cpp - events/Get.cpp - events/Mark.cpp - events/Move.cpp - events/SetPortValue.cpp - events/Undo.cpp - ingen_engine.cpp - internals/BlockDelay.cpp - internals/Controller.cpp - internals/Note.cpp - internals/Time.cpp - internals/Trigger.cpp - mix.cpp - ''' - - core_libs = 'LV2 LILV RAUL SERD SORD SRATOM' - - bld(features = 'cxx cxxshlib', - source = core_source, - export_includes = ['../../include'], - includes = ['.', '../..', '../../include'], - name = 'libingen_server', - target = 'ingen_server', - install_path = '${LIBDIR}', - use = 'libingen libingen_socket', - uselib = core_libs, - cxxflags = bld.env.PTHREAD_CFLAGS + bld.env.INGEN_TEST_CXXFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS + bld.env.INGEN_TEST_LINKFLAGS) - - if bld.env.HAVE_JACK: - bld(features = 'cxx cxxshlib', - source = 'JackDriver.cpp ingen_jack.cpp', - includes = ['.', '../../', '../../include'], - name = 'libingen_jack', - target = 'ingen_jack', - install_path = '${LIBDIR}', - use = 'libingen_server', - uselib = core_libs + ' JACK', - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) - - if bld.env.HAVE_PORTAUDIO: - bld(features = 'cxx cxxshlib', - source = 'PortAudioDriver.cpp ingen_portaudio.cpp', - includes = ['.', '../../', '../../include'], - name = 'libingen_portaudio', - target = 'ingen_portaudio', - install_path = '${LIBDIR}', - use = 'libingen_server', - uselib = core_libs + ' PORTAUDIO', - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) - - # Ingen LV2 wrapper - if bld.env.INGEN_BUILD_LV2: - bld(features = 'cxx cxxshlib', - source = ' ingen_lv2.cpp ', - cflags = ['-fvisibility=hidden'], - includes = ['../../', '../../include'], - name = 'libingen_lv2', - target = 'ingen_lv2', - install_path = '${LV2DIR}/ingen.lv2/', - use = 'libingen libingen_server', - uselib = core_libs, - cxxflags = ['-fvisibility=hidden'] + bld.env.PTHREAD_CFLAGS, - linkflags = bld.env.PTHREAD_LINKFLAGS) diff --git a/src/wscript b/src/wscript deleted file mode 100644 index a2f576da..00000000 --- a/src/wscript +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - - -def build(bld): - sources = [ - 'AtomReader.cpp', - 'AtomWriter.cpp', - 'ClashAvoider.cpp', - 'ColorContext.cpp', - 'Configuration.cpp', - 'FilePath.cpp', - 'Forge.cpp', - 'LV2Features.cpp', - 'Library.cpp', - 'Log.cpp', - 'Parser.cpp', - 'Resource.cpp', - 'Serialiser.cpp', - 'Store.cpp', - 'StreamWriter.cpp', - 'TurtleWriter.cpp', - 'URI.cpp', - 'URIMap.cpp', - 'URIs.cpp', - 'World.cpp', - 'runtime_paths.cpp' - ] - if bld.is_defined('HAVE_SOCKET'): - sources += ['SocketReader.cpp', 'SocketWriter.cpp'] - - lib = [] - if bld.is_defined('HAVE_LIBDL'): - lib += ['dl'] - - bld(features = 'cxx cxxshlib', - source = sources, - export_includes = ['../include'], - includes = ['.', '..', '../include'], - name = 'libingen', - target = 'ingen-%s' % bld.env.INGEN_MAJOR_VERSION, - vnum = bld.env.INGEN_VERSION, - install_path = '${LIBDIR}', - lib = lib, - uselib = 'LV2 LILV RAUL SERD SORD SRATOM', - cxxflags = (['-fvisibility=hidden'] + - bld.env.PTHREAD_CFLAGS + bld.env.INGEN_TEST_CXXFLAGS), - linkflags = bld.env.PTHREAD_LINKFLAGS + bld.env.INGEN_TEST_LINKFLAGS) diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..64623719 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,112 @@ +# Copyright 2019-2022 David Robillard <d@drobilla.net> +# SPDX-License-Identifier: CC0-1.0 OR GPL-3.0-or-later + +############## +# Unit Tests # +############## + +unit_tests = [ + 'FilePath', +] + +foreach test : unit_tests + test( + test, + executable( + test, + files('tst_@0@.cpp'.format(test)), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], + ), + suite: 'unit', + ) +endforeach + +##################### +# Integration Tests # +##################### + +ingen_test = executable( + 'ingen_test', + files('ingen_test.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +ingen_bench = executable( + 'ingen_bench', + files('ingen_bench.cpp'), + cpp_args: cpp_suppressions + platform_defines, + dependencies: [ingen_dep], +) + +empty_manifest = files('empty.ingen/manifest.ttl') +empty_main = files('empty.ingen/main.ttl') + +integration_tests = [ + 'connect_disconnect_node_node', + 'connect_disconnect_node_patch', + 'connect_disconnect_patch_patch', + 'copy_node', + 'create_delete_node', + 'create_delete_patch', + 'create_delete_poly_patch', + 'create_delete_port', + 'disconnect_all_node', + 'disconnect_all_port', + 'duplicate_node', + 'enable_graph', + 'get_engine', + 'get_node', + 'get_patch', + 'get_plugin', + 'get_plugins', + 'get_port', + 'load_graph', + 'move_node', + 'move_port', + 'move_root_port', + 'poly', + 'put_audio_in', + 'save_graph', + 'set_graph_poly', + 'set_patch_port_value', +] + +test_env = environment( + { + 'INGEN_MODULE_PATH': ':'.join( + [ + ingen_build_root / 'src', + ingen_build_root / 'src' / 'client', + ingen_build_root / 'src' / 'gui', + ingen_build_root / 'src' / 'server', + ], + ), + 'LV2_PATH': ':'.join( + [ + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'lv2dir', + pkgconfig: 'lv2dir', + ), + lv2_dep.get_variable( + default_value: lv2dir, + internal: 'plugindir', + pkgconfig: 'plugindir', + ) + ], + ), + }) + +foreach test : integration_tests + test( + test, + ingen_test, + env: test_env, + args: [ + '--load', empty_manifest, + '--execute', files(test + '.ttl'), + ], + ) +endforeach @@ -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(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 b600c928b221a001faeab7bd92786d0b25714bc diff --git a/wscript b/wscript deleted file mode 100644 index 1c6b07dc..00000000 --- a/wscript +++ /dev/null @@ -1,443 +0,0 @@ -#!/usr/bin/env python - -import os - -from waflib import Build, Logs, Options, Utils -from waflib.extras import autowaf - -# Package version -INGEN_VERSION = '0.5.1' -INGEN_MAJOR_VERSION = '0' - -# Mandatory waf variables -APPNAME = 'ingen' # Package name for waf dist -VERSION = INGEN_VERSION # Package version for waf dist -top = '.' # Source directory -out = 'build' # Build directory - -line_just = 47 - - -def options(ctx): - ctx.load('compiler_cxx') - ctx.load('python') - ctx.load('lv2') - ctx.recurse('src/gui') - opt = ctx.configuration_options() - - opt.add_option('--data-dir', type='string', dest='datadir', - help='ingen data install directory [default: PREFIX/share/ingen]') - opt.add_option('--module-dir', type='string', dest='moduledir', - help='ingen module install directory [default: PREFIX/lib/ingen]') - - ctx.add_flags( - opt, - {'no-gui': 'do not build GUI', - 'no-client': 'do not build client library (or GUI)', - 'no-jack': 'do not build jack backend (for ingen.lv2 only)', - 'no-plugin': 'do not build ingen.lv2 plugin', - 'no-python': 'do not install Python bindings', - 'no-webkit': 'do not use webkit to display plugin documentation', - 'no-socket': 'do not build Socket interface', - 'debug-urids': 'print a trace of URI mapping', - 'portaudio': 'build PortAudio backend'}) - - -def configure(conf): - conf.load('compiler_cxx', cache=True) - conf.load('lv2', cache=True) - if not Options.options.no_python: - conf.load('python', cache=True) - - conf.load('autowaf', cache=True) - autowaf.set_cxx_lang(conf, 'c++14') - - 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: - autowaf.add_compiler_flags(conf.env, 'cxx', { - 'clang': [ - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-documentation-unknown-command', - '-Wno-exit-time-destructors', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-format-nonliteral', - '-Wno-global-constructors', - '-Wno-implicit-float-conversion', - '-Wno-implicit-int-conversion', - '-Wno-nullability-extension', - '-Wno-nullable-to-nonnull-conversion', - '-Wno-padded', - '-Wno-reserved-id-macro', - '-Wno-shadow-field', - '-Wno-shorten-64-to-32', - '-Wno-sign-conversion', - '-Wno-switch-enum', - '-Wno-unreachable-code', - '-Wno-unused-parameter', - '-Wno-vla', - '-Wno-vla-extension', - '-Wno-weak-vtables', - ], - 'gcc': [ - '-Wno-cast-align', - '-Wno-cast-qual', - '-Wno-conditionally-supported', - '-Wno-conversion', - '-Wno-effc++', - '-Wno-float-conversion', - '-Wno-float-equal', - '-Wno-format', - '-Wno-format-nonliteral', - '-Wno-multiple-inheritance', - '-Wno-padded', - '-Wno-sign-conversion', - '-Wno-stack-protector', - '-Wno-suggest-attribute=format', - '-Wno-suggest-override', - '-Wno-switch-enum', - '-Wno-unreachable-code', - '-Wno-unused-parameter', - '-Wno-useless-cast', - '-Wno-vla', - ], - }) - - conf.check_cxx(header_name='boost/intrusive/slist.hpp') - - conf.check_pkg('lv2 >= 1.16.0', uselib_store='LV2') - conf.check_pkg('lilv-0 >= 0.21.5', uselib_store='LILV') - conf.check_pkg('suil-0 >= 0.8.7', uselib_store='SUIL') - conf.check_pkg('sratom-0 >= 0.4.6', uselib_store='SRATOM') - conf.check_pkg('raul-1 >= 1.1.0', uselib_store='RAUL') - conf.check_pkg('serd-0 >= 0.30.3', uselib_store='SERD', mandatory=False) - conf.check_pkg('sord-0 >= 0.12.0', uselib_store='SORD', mandatory=False) - - conf.check_pkg('portaudio-2.0', - uselib_store = 'PORTAUDIO', - system = True, - mandatory = False) - - conf.check_pkg('sigc++-2.0', - uselib_store = 'SIGCPP', - system = True, - mandatory = False) - - conf.check_function('cxx', 'posix_memalign', - defines = '_POSIX_C_SOURCE=200809L', - header_name = 'stdlib.h', - define_name = 'HAVE_POSIX_MEMALIGN', - return_type = 'int', - arg_types = 'void**,size_t,size_t', - mandatory = False) - - conf.check_function('cxx', 'isatty', - header_name = 'unistd.h', - defines = '_POSIX_C_SOURCE=200809L', - define_name = 'HAVE_ISATTY', - return_type = 'int', - arg_types = 'int', - mandatory = False) - - conf.check_function('cxx', 'vasprintf', - header_name = 'stdio.h', - defines = '_GNU_SOURCE=1', - define_name = 'HAVE_VASPRINTF', - return_type = 'int', - arg_types = 'char**,const char*,va_list', - mandatory = False) - - conf.check(define_name = 'HAVE_LIBDL', - lib = 'dl', - mandatory = False) - - if not Options.options.no_socket: - conf.check_function('cxx', 'socket', - header_name = 'sys/socket.h', - define_name = 'HAVE_SOCKET', - return_type = 'int', - arg_types = 'int,int,int', - mandatory = False) - - if not Options.options.no_python: - conf.check_python_version((2, 4, 0), mandatory=False) - - if not Options.options.no_plugin: - conf.env.INGEN_BUILD_LV2 = 1 - - if not Options.options.no_jack: - conf.check_pkg('jack >= 0.120.0', - uselib_store = 'JACK', - system = True, - mandatory = False) - - conf.check_function('cxx', 'jack_set_property', - header_name = 'jack/metadata.h', - define_name = 'HAVE_JACK_METADATA', - uselib = 'JACK', - return_type = 'int', - arg_types = '''jack_client_t*, - jack_uuid_t, - const char*, - const char*, - const char*''', - mandatory = False) - conf.check_function('cxx', 'jack_port_rename', - header_name = 'jack/jack.h', - define_name = 'HAVE_JACK_PORT_RENAME', - uselib = 'JACK', - return_type = 'int', - arg_types = 'jack_client_t*,jack_port_t*,const char*', - mandatory = False) - - if Options.options.debug_urids: - conf.define('INGEN_DEBUG_URIDS', 1) - - conf.env.INGEN_TEST_LINKFLAGS = [] - conf.env.INGEN_TEST_CXXFLAGS = [] - if conf.env.BUILD_TESTS: - if not conf.env.NO_COVERAGE: - conf.env.INGEN_TEST_CXXFLAGS += ['--coverage'] - conf.env.INGEN_TEST_LINKFLAGS += ['--coverage'] - - conf.env.PTHREAD_CFLAGS = [] - conf.env.PTHREAD_LINKFLAGS = [] - if conf.check(cflags=['-pthread'], mandatory=False): - conf.env.PTHREAD_CFLAGS = ['-pthread'] - if conf.check(linkflags=['-pthread'], mandatory=False): - if not (conf.env.DEST_OS == 'darwin' and conf.env.CXX_NAME == 'clang'): - conf.env.PTHREAD_LINKFLAGS += ['-pthread'] - if conf.check(linkflags=['-lpthread'], mandatory=False): - conf.env.PTHREAD_LINKFLAGS += ['-lpthread'] - - conf.define('INGEN_SHARED', 1) - conf.define('INGEN_VERSION', INGEN_VERSION) - - if conf.env.HAVE_SIGCPP and not Options.options.no_client: - conf.env.INGEN_BUILD_CLIENT = 1 - else: - Options.options.no_gui = True - - if not Options.options.no_gui: - conf.recurse('src/gui') - - conf.env.INGEN_MAJOR_VERSION = INGEN_MAJOR_VERSION - - conf.define('INGEN_DATA_DIR', os.path.join(conf.env.DATADIR, 'ingen')) - conf.define('INGEN_MODULE_DIR', conf.env.LIBDIR) - conf.define('INGEN_BUNDLE_DIR', os.path.join(conf.env.LV2DIR, 'ingen.lv2')) - - autowaf.set_lib_env(conf, 'ingen', INGEN_VERSION) - conf.run_env.append_unique('XDG_DATA_DIRS', [str(conf.path.get_bld())]) - for i in ['src', 'modules']: - conf.run_env.append_unique(autowaf.lib_path_name, [str(conf.build_path(i))]) - for i in ['src/client', 'src/server', 'src/gui']: - conf.run_env.append_unique('INGEN_MODULE_PATH', [str(conf.build_path(i))]) - - conf.write_config_header('ingen_config.h', remove=False) - - autowaf.display_summary( - conf, - {'GUI': bool(conf.env.INGEN_BUILD_GUI), - 'HTML plugin doc support': bool(conf.env.HAVE_WEBKIT), - 'PortAudio driver': bool(conf.env.HAVE_PORTAUDIO), - 'Jack driver': bool(conf.env.HAVE_JACK), - 'Jack metadata support': conf.is_defined('HAVE_JACK_METADATA'), - 'LV2 plugin driver': bool(conf.env.INGEN_BUILD_LV2), - 'LV2 bundle': conf.env.INGEN_BUNDLE_DIR, - 'LV2 plugin support': bool(conf.env.HAVE_LILV), - 'Socket interface': conf.is_defined('HAVE_SOCKET')}) - - -unit_tests = ['tst_FilePath'] - - -def build(bld): - opts = Options.options - opts.datadir = opts.datadir or bld.env.PREFIX + 'share' - opts.moduledir = opts.moduledir or bld.env.PREFIX + 'lib/ingen' - - # Headers - for i in ['', 'client']: - bld.install_files('${INCLUDEDIR}/ingen/%s' % i, - bld.path.ant_glob('ingen/%s/*' % i)) - - # Python modules - if bld.env.PYTHONDIR: - bld.install_files('${PYTHONDIR}/', 'scripts/ingen.py') - - # Modules - bld.recurse('src') - bld.recurse('src/server') - - if bld.env.INGEN_BUILD_CLIENT: - bld.recurse('src/client') - - if bld.env.INGEN_BUILD_GUI: - bld.recurse('src/gui') - - # Program - bld(features = 'c cxx cxxprogram', - source = 'src/ingen/ingen.cpp', - target = 'ingen', - includes = ['.', 'include'], - use = 'libingen', - uselib = 'SERD SORD SRATOM RAUL LILV LV2', - install_path = '${BINDIR}') - - # Test program - if bld.env.BUILD_TESTS: - for i in ['ingen_test', 'ingen_bench'] + unit_tests: - bld(features = 'cxx cxxprogram', - source = 'tests/%s.cpp' % i, - target = 'tests/%s' % i, - includes = ['.', 'include'], - use = 'libingen', - uselib = 'SERD SORD SRATOM RAUL LILV LV2', - install_path = '', - cxxflags = bld.env.INGEN_TEST_CXXFLAGS, - linkflags = bld.env.INGEN_TEST_LINKFLAGS) - - bld.install_files('${DATADIR}/applications', 'src/ingen/ingen.desktop') - bld.install_files('${BINDIR}', 'scripts/ingenish', chmod=Utils.O755) - bld.install_files('${BINDIR}', 'scripts/ingenams', chmod=Utils.O755) - - # Code documentation - autowaf.build_dox(bld, 'INGEN', INGEN_VERSION, top, out) - - # Ontology documentation - if bld.env.DOCS: - bld(rule='lv2specgen.py ${SRC} ${TGT} -i -p ingen --copy-style --list-email ingen@drobilla.net --list-page http://lists.drobilla.net/listinfo.cgi/ingen-drobilla.net', - source = 'bundles/ingen.lv2/ingen.ttl', - target = 'ingen.lv2/ingen.html') - - # Man page - bld.install_files('${MANDIR}/man1', 'doc/ingen.1') - - # Icons - icon_dir = os.path.join(bld.env.DATADIR, 'icons', 'hicolor') - icon_sizes = [16, 22, 24, 32, 48, 64, 128, 256] - for s in icon_sizes: - d = '%dx%d' % (s, s) - bld.install_as( - os.path.join(icon_dir, d, 'apps', 'ingen.png'), - os.path.join('icons', d, 'ingen.png')) - - bld.install_as( - os.path.join(icon_dir, 'scalable', 'apps', 'ingen.svg'), - os.path.join('icons', 'scalable', 'ingen.svg')) - - bld.install_files('${LV2DIR}/ingen.lv2/', - bld.path.ant_glob('bundles/ingen.lv2/*')) - - # Install template graph bundles - for c in ['Stereo', 'Mono']: - for t in ['Effect', 'Instrument']: - bundle = '%s%s.ingen' % (c, t) - bld.install_files('${LV2DIR}/%s/' % bundle, - bld.path.ant_glob('bundles/%s/*' % bundle)) - - bld.add_post_fun(autowaf.run_ldconfig) - - -class LintContext(Build.BuildContext): - fun = cmd = 'lint' - - -def lint(ctx): - "checks code for style issues" - import subprocess - import sys - - st = 0 - - if "FLAKE8" in ctx.env: - Logs.info("Running flake8") - for i in ["src/client/wscript", - "src/gui/wscript", - "src/server/wscript", - "src/wscript", - "scripts/ingen.py", - "scripts/ingenish", - "scripts/ingenams", - "wscript"]: - st += subprocess.call([ctx.env.FLAKE8[0], - "--ignore", "E221,W504,E251,E501", - i]) - else: - Logs.warn("Not running flake8") - - if "CLANG_TIDY" in ctx.env and "clang" in ctx.env.CXX[0]: - Logs.info("Running clang-tidy") - - import json - - with open('build/compile_commands.json', 'r') as db: - commands = json.load(db) - files = [c['file'] for c in commands] - - for step_files in zip(*(iter(files),) * Options.options.jobs): - procs = [] - for f in step_files: - cmd = [ctx.env.CLANG_TIDY[0], '--quiet', '-p=.', f] - procs += [subprocess.Popen(cmd, cwd='build')] - - for proc in procs: - proc.communicate() - st += proc.returncode - else: - Logs.warn("Not running clang-tidy") - - if "IWYU_TOOL" in ctx.env: - Logs.info("Running include-what-you-use") - cmd = [ctx.env.IWYU_TOOL[0], "-o", "clang", "-p", "build"] - 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 st != 0: - Logs.warn("Lint checks failed") - sys.exit(st) - - -def upload_docs(ctx): - # Ontology documentation - os.system('rsync -avz -e ssh bundles/ingen.lv2/ingen.ttl drobilla@drobilla.net:~/drobilla.net/ns/') - os.system('rsync -avz -e ssh build/ingen.lv2/ingen.html drobilla@drobilla.net:~/drobilla.net/ns/') - os.system('rsync -avz -e ssh build/ingen.lv2/style.css drobilla@drobilla.net:~/drobilla.net/ns/') - - # Doxygen documentation - os.system('rsync -ravz --delete -e ssh build/doc/html/* drobilla@drobilla.net:~/drobilla.net/docs/ingen/') - - -def test(tst): - with tst.group('unit') as check: - for i in unit_tests: - check(['./tests/' + i]) - - with tst.group('integration') as check: - empty = tst.src_path('tests/empty.ingen') - empty_main = os.path.join(empty, 'main.ttl') - for i in tst.path.ant_glob('tests/*.ttl'): - base = os.path.basename(i.abspath().replace('.ttl', '')) - - # Run test - check(['./tests/ingen_test', - '--load', empty, - '--execute', os.path.relpath(i.abspath(), os.getcwd())]) - - # Check undo output for changes - check.file_equals(empty_main, base + '.undo.ingen/main.ttl') - - # Check redo output for changes - check.file_equals(base + '.out.ingen/main.ttl', - base + '.redo.ingen/main.ttl') |