From c411b29b6d5cc5ecba788e4e8d30b1ab792a811d Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 09:13:53 -0700 Subject: dependencies/misc: Fix typing of curses_factory --- mesonbuild/dependencies/misc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 47694af..23619b7 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -32,7 +32,7 @@ from .base import ( if T.TYPE_CHECKING: from ..environment import Environment, MachineChoice - from .base import DependencyType # noqa: F401 + from .base import DependencyType, Dependency # noqa: F401 @factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE}) @@ -406,8 +406,8 @@ class ShadercDependency(ExternalDependency): @factory_methods({DependencyMethods.PKGCONFIG}) def curses_factory(env: 'Environment', for_machine: 'MachineChoice', - kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']: - candidates = [] # type: T.List['DependencyType'] + kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: + candidates = [] # type: T.List[T.Callable[[], Dependency]] if DependencyMethods.PKGCONFIG in methods: pkgconfig_files = ['ncurses', 'ncursesw'] -- cgit v1.1 From 16d3513df68a7d214c2759a43886a9de8f701024 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 09:53:00 -0700 Subject: docs/Dependencies Add missing curses documentation --- docs/markdown/Dependencies.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index efd8728..f458afe 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -615,6 +615,16 @@ on these OSes to link with the bundled version. *New in 0.54.0* the `system` method. +## Curses + +*(Since 0.54.0)* + +Curses (and ncurses) are a cross platform pain in the butt. Meson wraps up +these dependencies in the `curses` dependency. This covers both `ncurses` +(preferred) and other curses implementations. + +`method` may be `auto` or `pkg-config` +
1: They may appear to be case-insensitive, if the underlying file system happens to be case-insensitive. -- cgit v1.1 From 354c1c1d09e906d2a62635e41516ac1f08648530 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 09:16:17 -0700 Subject: dependency/misc: change lookup order for curses pkg-config look for (in order): ncursesw, ncurses, curses. --- mesonbuild/dependencies/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 23619b7..c270758 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -410,7 +410,7 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', candidates = [] # type: T.List[T.Callable[[], Dependency]] if DependencyMethods.PKGCONFIG in methods: - pkgconfig_files = ['ncurses', 'ncursesw'] + pkgconfig_files = ['ncursesw', 'ncurses', 'curses'] for pkg in pkgconfig_files: candidates.append(functools.partial(PkgConfigDependency, pkg, env, kwargs)) -- cgit v1.1 From 7d11d7cf68f5a0379ef3b50b853cea4a3ceb0636 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 09:48:48 -0700 Subject: dependencies/curses: Add support for using the ncurses config tools These are mostly duplicated with pkg-config, but maybe someone has one but not another, and they're easy to turn on with the ConfigToolDependency. --- docs/markdown/Dependencies.md | 4 +++- .../snippets/curses-dependency-improvements.md | 4 ++++ mesonbuild/dependencies/misc.py | 21 ++++++++++++++++++++- test cases/frameworks/31 curses/meson.build | 2 +- test cases/frameworks/31 curses/meson_options.txt | 6 ++++++ test cases/frameworks/31 curses/test.json | 10 ++++++++++ 6 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 docs/markdown/snippets/curses-dependency-improvements.md create mode 100644 test cases/frameworks/31 curses/meson_options.txt create mode 100644 test cases/frameworks/31 curses/test.json diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index f458afe..eccfe0a 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -623,7 +623,9 @@ Curses (and ncurses) are a cross platform pain in the butt. Meson wraps up these dependencies in the `curses` dependency. This covers both `ncurses` (preferred) and other curses implementations. -`method` may be `auto` or `pkg-config` +`method` may be `auto`, `pkg-config`, or `config-tool` + +*New in 0.56.0* The `config-tool` method.
1: They may appear to be case-insensitive, if the diff --git a/docs/markdown/snippets/curses-dependency-improvements.md b/docs/markdown/snippets/curses-dependency-improvements.md new file mode 100644 index 0000000..bd1d001 --- /dev/null +++ b/docs/markdown/snippets/curses-dependency-improvements.md @@ -0,0 +1,4 @@ +## Improvements for the builtin curses dependency + +This method has been extended to use config-tools for lookup as well as +pkg-config. diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index c270758..c1e17d7 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -404,7 +404,23 @@ class ShadercDependency(ExternalDependency): return [DependencyMethods.SYSTEM, DependencyMethods.PKGCONFIG] -@factory_methods({DependencyMethods.PKGCONFIG}) +class CursesConfigToolDependency(ConfigToolDependency): + + """Use the curses config tools.""" + + tool = 'curses-config' + # ncurses5.4-config is for macOS Catalina + tools = ['ncursesw6-config', 'ncursesw5-config', 'ncurses6-config', 'ncurses5-config', 'ncurses5.4-config'] + + def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None): + super().__init__(name, env, kwargs, language) + if not self.is_found: + return + self.compile_args = self.get_config_value(['--cflags'], 'compile_args') + self.link_args = self.get_config_value(['--libs'], 'link_args') + + +@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL}) def curses_factory(env: 'Environment', for_machine: 'MachineChoice', kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: candidates = [] # type: T.List[T.Callable[[], Dependency]] @@ -414,6 +430,9 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', for pkg in pkgconfig_files: candidates.append(functools.partial(PkgConfigDependency, pkg, env, kwargs)) + if DependencyMethods.CONFIG_TOOL in methods: + candidates.append(functools.partial(CursesConfigToolDependency, 'curses', env, kwargs)) + return candidates diff --git a/test cases/frameworks/31 curses/meson.build b/test cases/frameworks/31 curses/meson.build index 21483fb..66e0957 100644 --- a/test cases/frameworks/31 curses/meson.build +++ b/test cases/frameworks/31 curses/meson.build @@ -1,6 +1,6 @@ project('curses', 'c') -curses = dependency('curses', required: false) +curses = dependency('curses', required: false, method : get_option('method')) if not curses.found() error('MESON_SKIP_TEST: Curses library not found') endif diff --git a/test cases/frameworks/31 curses/meson_options.txt b/test cases/frameworks/31 curses/meson_options.txt new file mode 100644 index 0000000..3a587f4 --- /dev/null +++ b/test cases/frameworks/31 curses/meson_options.txt @@ -0,0 +1,6 @@ +option( + 'method', + type : 'combo', + choices : ['pkg-config', 'config-tool'], + value : 'pkg-config', +) diff --git a/test cases/frameworks/31 curses/test.json b/test cases/frameworks/31 curses/test.json new file mode 100644 index 0000000..0de1f73 --- /dev/null +++ b/test cases/frameworks/31 curses/test.json @@ -0,0 +1,10 @@ +{ + "matrix": { + "options": { + "method": [ + { "val": "pkg-config" }, + { "val": "config-tool" } + ] + } + } +} -- cgit v1.1 From cb6ccf2632c3b09237b2bfe04687fa5d8b4c88ab Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 10:36:37 -0700 Subject: dependencies/zlib: Fix header detection has_header returns a tuple of (found: bool, cached: bool), so `if has_header` will always return true because the tuple is non-empty. We need to check if the found value is true or not. --- mesonbuild/dependencies/dev.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index 67d7e65..99c5c07 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -480,7 +480,7 @@ class ZlibSystemDependency(ExternalDependency): for lib in libs: l = self.clib_compiler.find_library(lib, environment, []) h = self.clib_compiler.has_header('zlib.h', '', environment, dependencies=[self]) - if l and h: + if l and h[0]: self.is_found = True self.link_args = l break -- cgit v1.1 From 5aee8567b8c0ec3d242424bdc88a32f3303e61c4 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 10:40:13 -0700 Subject: dependencies/curses: Add a system dependency That calls find_library and has_header in conjunction to look for curses implementations that are baked into the system without any other find method. --- docs/markdown/Dependencies.md | 4 +- .../snippets/curses-dependency-improvements.md | 4 +- mesonbuild/dependencies/misc.py | 59 +++++++++++++++++++++- test cases/frameworks/31 curses/meson_options.txt | 2 +- test cases/frameworks/31 curses/test.json | 3 +- 5 files changed, 65 insertions(+), 7 deletions(-) diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index eccfe0a..a8ada1d 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -623,9 +623,9 @@ Curses (and ncurses) are a cross platform pain in the butt. Meson wraps up these dependencies in the `curses` dependency. This covers both `ncurses` (preferred) and other curses implementations. -`method` may be `auto`, `pkg-config`, or `config-tool` +`method` may be `auto`, `pkg-config`, `config-tool`, or `system`. -*New in 0.56.0* The `config-tool` method. +*New in 0.56.0* The `config-tool` and `system` methods.
1: They may appear to be case-insensitive, if the diff --git a/docs/markdown/snippets/curses-dependency-improvements.md b/docs/markdown/snippets/curses-dependency-improvements.md index bd1d001..237da4c 100644 --- a/docs/markdown/snippets/curses-dependency-improvements.md +++ b/docs/markdown/snippets/curses-dependency-improvements.md @@ -1,4 +1,4 @@ ## Improvements for the builtin curses dependency -This method has been extended to use config-tools for lookup as well as -pkg-config. +This method has been extended to use config-tools, and a fallback to +find_library for lookup as well as pkg-config. diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index c1e17d7..08747ce 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -420,7 +420,61 @@ class CursesConfigToolDependency(ConfigToolDependency): self.link_args = self.get_config_value(['--libs'], 'link_args') -@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL}) +class CursesSystemDependency(ExternalDependency): + + """Curses dependency the hard way. + + This replaces hand rolled find_library() and has_header() calls. We + provide this for portability reasons, there are a large number of curses + implementations, and the differences between them can be very annoying. + """ + + def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]): + super().__init__(name, env, kwargs) + + candidates = [ + ('ncursesw', ['ncursesw/ncurses.h', 'ncurses.h']), + ('ncurses', ['ncurses/ncurses.h', 'ncurses/curses.h', 'ncurses.h']), + ('curses', ['curses.h']), + ] + + # Not sure how else to elegently break out of both loops + for lib, headers in candidates: + l = self.clib_compiler.find_library(lib, env, []) + if l: + for header in headers: + h = self.clib_compiler.has_header(header, '', env) + if h[0]: + self.is_found = True + self.link_args = l + # Not sure how to find version for non-ncurses curses + # implementations. The one in illumos/OpenIndiana + # doesn't seem to have a version defined in the header. + if lib.startswith('ncurses'): + v, _ = self.clib_compiler.get_define('NCURSES_VERSION', '#include <{}>'.format(header), env, [], [self]) + self.version = v.strip('"') + + # Check the version if possible, emit a wraning if we can't + req = kwargs.get('version') + if req: + if self.version: + self.is_found = mesonlib.version_compare(self.version, req) + else: + mlog.warning('Cannot determine version of curses to compare against.') + + if self.is_found: + mlog.debug('Curses library:', l) + mlog.debug('Curses header:', header) + break + if self.is_found: + break + + @staticmethod + def get_methods() -> T.List[DependencyMethods]: + return [DependencyMethods.SYSTEM] + + +@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM}) def curses_factory(env: 'Environment', for_machine: 'MachineChoice', kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List[T.Callable[[], 'Dependency']]: candidates = [] # type: T.List[T.Callable[[], Dependency]] @@ -433,6 +487,9 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', if DependencyMethods.CONFIG_TOOL in methods: candidates.append(functools.partial(CursesConfigToolDependency, 'curses', env, kwargs)) + if DependencyMethods.SYSTEM in methods: + candidates.append(functools.partial(CursesSystemDependency, 'curses', env, kwargs)) + return candidates diff --git a/test cases/frameworks/31 curses/meson_options.txt b/test cases/frameworks/31 curses/meson_options.txt index 3a587f4..e294e83 100644 --- a/test cases/frameworks/31 curses/meson_options.txt +++ b/test cases/frameworks/31 curses/meson_options.txt @@ -1,6 +1,6 @@ option( 'method', type : 'combo', - choices : ['pkg-config', 'config-tool'], + choices : ['pkg-config', 'config-tool', 'system'], value : 'pkg-config', ) diff --git a/test cases/frameworks/31 curses/test.json b/test cases/frameworks/31 curses/test.json index 0de1f73..3995695 100644 --- a/test cases/frameworks/31 curses/test.json +++ b/test cases/frameworks/31 curses/test.json @@ -3,7 +3,8 @@ "options": { "method": [ { "val": "pkg-config" }, - { "val": "config-tool" } + { "val": "config-tool" }, + { "val": "system" } ] } } -- cgit v1.1 From 19f2b3d58372907fa3b7f55352a744357683f6b3 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 18 Sep 2020 10:51:37 -0700 Subject: tests/curses: Extend to test versions This is mostly important for the system dependency where we need to roll the version check ourselves. --- test cases/frameworks/31 curses/meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test cases/frameworks/31 curses/meson.build b/test cases/frameworks/31 curses/meson.build index 66e0957..796a0d8 100644 --- a/test cases/frameworks/31 curses/meson.build +++ b/test cases/frameworks/31 curses/meson.build @@ -1,9 +1,13 @@ project('curses', 'c') -curses = dependency('curses', required: false, method : get_option('method')) +curses = dependency('curses', required: false, method : get_option('method'), version : '>= 0') if not curses.found() error('MESON_SKIP_TEST: Curses library not found') endif exec = executable('basic', 'main.c', dependencies: curses) # didn't run the test because in general graphics fail on CI + +# this should fail +not_found = dependency('curses', required: false, method : get_option('method'), version : '> 1000000') +assert(not_found.found() == false) -- cgit v1.1 From e873e64b401ede9fdcf09a388f7a12010d321dbb Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Wed, 23 Sep 2020 23:08:02 +0800 Subject: dependencies/curses: Add way to testing curses on msys2. --- azure-pipelines.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f0e238d..bd36aaa 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -150,15 +150,18 @@ jobs: gccx86ninja: MSYSTEM: MINGW32 MSYS2_ARCH: i686 + MSYS2_CURSES: ncurses compiler: gcc gccx64ninja: MSYSTEM: MINGW64 MSYS2_ARCH: x86_64 + MSYS2_CURSES: pdcurses MESON_RSP_THRESHOLD: 0 compiler: gcc clangx64ninja: MSYSTEM: MINGW64 MSYS2_ARCH: x86_64 + MSYS2_CURSES: compiler: clang variables: MSYS2_ROOT: $(System.Workfolder)\msys64 @@ -184,6 +187,7 @@ jobs: mingw-w64-$(MSYS2_ARCH)-python3-setuptools ^ mingw-w64-$(MSYS2_ARCH)-python3-pip ^ %TOOLCHAIN% + if not "%MSYS2_CURSES%" == "" ( %MSYS2_ROOT%\usr\bin\pacman --noconfirm --needed -S mingw-w64-$(MSYS2_ARCH)-$(MSYS2_CURSES) ) %MSYS2_ROOT%\usr\bin\bash -lc "python3 -m pip --disable-pip-version-check install gcovr jsonschema pefile" displayName: Install Dependencies - script: | -- cgit v1.1 From 9a4750976417afd7449eb16622d65d80dcc875ac Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Thu, 24 Sep 2020 00:17:12 +0800 Subject: dependencies/curses: Add support for pdcurses On win32 there is pdcurses, so we detect it first, because python depends on ncursesw, so if we don't want to use ncursesw, we should make sure pdcurses detect before ncursesw --- mesonbuild/dependencies/misc.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 08747ce..2824421 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -433,6 +433,7 @@ class CursesSystemDependency(ExternalDependency): super().__init__(name, env, kwargs) candidates = [ + ('pdcurses', ['pdcurses/curses.h']), ('ncursesw', ['ncursesw/ncurses.h', 'ncurses.h']), ('ncurses', ['ncurses/ncurses.h', 'ncurses/curses.h', 'ncurses.h']), ('curses', ['curses.h']), @@ -453,6 +454,10 @@ class CursesSystemDependency(ExternalDependency): if lib.startswith('ncurses'): v, _ = self.clib_compiler.get_define('NCURSES_VERSION', '#include <{}>'.format(header), env, [], [self]) self.version = v.strip('"') + if lib.startswith('pdcurses'): + v_major, _ = self.clib_compiler.get_define('PDC_VER_MAJOR', '#include <{}>'.format(header), env, [], [self]) + v_minor, _ = self.clib_compiler.get_define('PDC_VER_MINOR', '#include <{}>'.format(header), env, [], [self]) + self.version = '{}.{}'.format(v_major, v_minor) # Check the version if possible, emit a wraning if we can't req = kwargs.get('version') @@ -480,7 +485,7 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', candidates = [] # type: T.List[T.Callable[[], Dependency]] if DependencyMethods.PKGCONFIG in methods: - pkgconfig_files = ['ncursesw', 'ncurses', 'curses'] + pkgconfig_files = ['pdcurses', 'ncursesw', 'ncurses', 'curses'] for pkg in pkgconfig_files: candidates.append(functools.partial(PkgConfigDependency, pkg, env, kwargs)) -- cgit v1.1 From a3106776a681201b166d019a3cf27cfe07f30a87 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Tue, 29 Sep 2020 15:00:51 -0700 Subject: dependencies/curses: don't try ncurses-config or system dependency on windows with msys ncurses-config returns a unix style path (currently, though it's been fixed upstream), which the compilers don't understand, so we can't do that. Additionally, while the system search does work, there's missing include directories that need to be added. --- mesonbuild/dependencies/misc.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 2824421..15055aa 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -489,11 +489,15 @@ def curses_factory(env: 'Environment', for_machine: 'MachineChoice', for pkg in pkgconfig_files: candidates.append(functools.partial(PkgConfigDependency, pkg, env, kwargs)) - if DependencyMethods.CONFIG_TOOL in methods: - candidates.append(functools.partial(CursesConfigToolDependency, 'curses', env, kwargs)) - - if DependencyMethods.SYSTEM in methods: - candidates.append(functools.partial(CursesSystemDependency, 'curses', env, kwargs)) + # There are path handling problems with these methods on msys, and they + # don't apply to windows otherwise (cygwin is handled seperately from + # windows) + if not env.machines[for_machine].is_windows(): + if DependencyMethods.CONFIG_TOOL in methods: + candidates.append(functools.partial(CursesConfigToolDependency, 'curses', env, kwargs)) + + if DependencyMethods.SYSTEM in methods: + candidates.append(functools.partial(CursesSystemDependency, 'curses', env, kwargs)) return candidates -- cgit v1.1