diff options
30 files changed, 481 insertions, 115 deletions
diff --git a/.travis.yml b/.travis.yml index dd5cebb..bd8d48c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: before_install: - python ./skip_ci.py --base-branch-env=TRAVIS_BRANCH --is-pull-env=TRAVIS_PULL_REQUEST - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install qt llvm; fi # # Run one macOS build without pkg-config available, and the other (unity=on) with pkg-config - if [[ "$TRAVIS_OS_NAME" == "osx" && "$MESON_ARGS" =~ .*unity=on.* ]]; then brew install pkg-config; fi # Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219 @@ -62,4 +62,5 @@ script: withgit \ /bin/sh -c "cd /root && mkdir -p tools; wget -c http://nirbheek.in/files/binaries/ninja/linux-amd64/ninja -O /root/tools/ninja; chmod +x /root/tools/ninja; CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX PATH=/root/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py $RUN_TESTS_ARGS -- $MESON_ARGS && chmod -R a+rwX .coverage" fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi + # Ensure that llvm is added after $PATH, otherwise the clang from that llvm install will be used instead of the native apple clang. + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:/usr/local/opt/qt/bin:$PATH:$(brew --prefix llvm)/bin MESON_FIXED_NINJA=1 ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi @@ -10,6 +10,8 @@ build system. [](https://travis-ci.org/mesonbuild/meson) [](https://ci.appveyor.com/project/mesonbuild/meson) [](https://codecov.io/gh/mesonbuild/meson/branch/master) +[](https://lgtm.com/projects/g/mesonbuild/meson/context:python) +[](https://lgtm.com/projects/g/mesonbuild/meson/alerts) #### Dependencies diff --git a/ciimage/Dockerfile b/ciimage/Dockerfile index 326013b..ac59ca9 100644 --- a/ciimage/Dockerfile +++ b/ciimage/Dockerfile @@ -12,7 +12,8 @@ RUN apt-get -y update && apt-get -y upgrade \ && apt-get -y install qt4-linguist-tools \ && apt-get -y install python-dev \ && apt-get -y install libomp-dev openssh-client \ -&& apt-get -y install -y clang libclang-dev llvm-dev flex \ +&& apt-get -y install clang libclang-dev llvm-dev flex \ +&& apt-get -y install libgcrypt11-dev \ && apt-get -y install gdc ldc \ && python3 -m pip install hotdoc codecov \ && dub fetch urld \ diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index 55352aa..55d82a5 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -119,4 +119,8 @@ compiler being used: The default values of `c_winlibs` and `cpp_winlibs` are in compiler-specific argument forms, but the libraries are: kernel32, user32, gdi32, winspool, -shell32, ole32, oleaut32, uuid, comdlg32, advapi32 +shell32, ole32, oleaut32, uuid, comdlg32, advapi32. + +c_args, cpp_args, c_link_args, and cpp_link_args only affect native builds, +when cross compiling they will not be applied to binaries or libraries +targeting the host system, only those being run on the build system. diff --git a/docs/markdown/D.md b/docs/markdown/D.md index 15de2f7..2b0eaac 100644 --- a/docs/markdown/D.md +++ b/docs/markdown/D.md @@ -14,15 +14,21 @@ project('myapp', 'd') executable('myapp', 'app.d') ``` -## Compiling different versions +## [Conditional compilation](https://dlang.org/spec/version.html) -If you are using the [version()](https://dlang.org/spec/version.html) feature for conditional compilation, +If you are using the [version()](https://dlang.org/spec/version.html#version-specification) feature for conditional compilation, you can use it using the `d_module_versions` target property: ```meson project('myapp', 'd') executable('myapp', 'app.d', d_module_versions: ['Demo', 'FeatureA']) ``` +For debugging, [debug()](https://dlang.org/spec/version.html#debug) conditions are compiled automatically in debug builds, and extra identifiers can be added with the `d_debug` argument: +```meson +project('myapp', 'd') +executable('myapp', 'app.d', d_debug: [3, 'DebugFeatureA']) +``` + ## Using embedded unittests If you are using embedded [unittest functions](https://dlang.org/spec/unittest.html), your source code needs diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md index 08ff1e2..c853677 100644 --- a/docs/markdown/Dependencies.md +++ b/docs/markdown/Dependencies.md @@ -165,15 +165,16 @@ wmf_dep = dependency('libwmf', method : 'config-tool') ## Dependencies using config tools [CUPS](#cups), [LLVM](#llvm), [pcap](#pcap), [WxWidgets](#wxwidgets), -[libwmf](#libwmf), and GnuStep either do not provide pkg-config +[libwmf](#libwmf), [GCrypt](#libgcrypt), and GnuStep either do not provide pkg-config modules or additionally can be detected via a config tool -(cups-config, llvm-config, etc). Meson has native support for these +(cups-config, llvm-config, libgcrypt-config, etc). Meson has native support for these tools, and they can be found like other dependencies: ```meson pcap_dep = dependency('pcap', version : '>=1.0') cups_dep = dependency('cups', version : '>=1.4') llvm_dep = dependency('llvm', version : '>=4.0') +libgcrypt_dep = dependency('libgcrypt', version: '>= 1.8') ``` ## AppleFrameworks @@ -309,6 +310,12 @@ The `language` keyword may used. `method` may be `auto`, `config-tool` or `pkg-config`. +## libgcrypt + +*(added 0.49.0)* + +`method` may be `auto`, `config-tool` or `pkg-config`. + ## Python3 Python3 is handled specially by meson: diff --git a/docs/markdown/Qt5-module.md b/docs/markdown/Qt5-module.md index f59b6ec..9542a81 100644 --- a/docs/markdown/Qt5-module.md +++ b/docs/markdown/Qt5-module.md @@ -9,8 +9,9 @@ This method takes the following keyword arguments: - `moc_headers`, `moc_sources`, `ui_files`, `qresources`, which define the files that require preprocessing with `moc`, `uic` and `rcc` - `include_directories`, the directories to add to header search path for `moc` (optional) - `moc_extra_arguments`, any additional arguments to `moc` (optional). Available since v0.44.0. + - `uic_extra_arguments`, any additional arguments to `uic` (optional). Available since v0.49.0. - `dependencies`, dependency objects needed by moc. Available since v0.48.0. - + It returns an opaque object that should be passed to a main build target. ## compile_translations (since v0.44.0) diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 7902f19..3bd2bfa 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -537,7 +537,8 @@ be passed to [shared and static libraries](#library). - `d_import_dirs` list of directories to look in for string imports used in the D programming language - `d_unittest`, when set to true, the D modules are compiled in debug mode -- `d_module_versions` list of module versions set when compiling D sources +- `d_module_versions` list of module version identifiers set when compiling D sources +- `d_debug` list of module debug identifiers set when compiling D sources The list of `sources`, `objects`, and `dependencies` is always flattened, which means you can freely nest and add lists while diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md index ccdcb34..39ec1cd 100644 --- a/docs/markdown/Reference-tables.md +++ b/docs/markdown/Reference-tables.md @@ -65,6 +65,11 @@ set in the cross file. Any cpu family not listed in the above list is not guaranteed to remain stable in future releases. +Those porting from autotools should note that meson does not add +endianness to the name of the cpu_family. For example, autotools +will call little endian PPC64 "ppc64le", meson will not, you must +also check the `.endian()` value of the machine for this information. + ## Operating system names These are provided by the `.system()` method call. diff --git a/docs/markdown/Release-notes-for-0.49.0.md b/docs/markdown/Release-notes-for-0.49.0.md index b294ad5..bdf5769 100644 --- a/docs/markdown/Release-notes-for-0.49.0.md +++ b/docs/markdown/Release-notes-for-0.49.0.md @@ -15,3 +15,8 @@ whose contents should look like this: A short description explaining the new feature and how it should be used. +## Libgcrypt dependency now supports libgcrypt-config + +Earlier, `dependency('libgcrypt')` could only detect the library with pkg-config +files. Now, if pkg-config files are not found, Meson will look for +`libgcrypt-config` and if it's found, will use that to find the library. diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index 0977921..2e977b2 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -85,9 +85,9 @@ slightly different wrap file. ```ini [wrap-git] -directory=samplesubproject -url=https://github.com/jpakkane/samplesubproject.git -revision=head +directory = samplesubproject +url = https://github.com/jpakkane/samplesubproject.git +revision = head ``` The format is straightforward. The only thing to note is the revision @@ -106,14 +106,14 @@ these cases you can specify the upload URL by adding the following at the end of your wrap file: ```ini -push-url=git@git.example.com:projects/someproject.git # Supported since version 0.37.0 +push-url = git@git.example.com:projects/someproject.git # Supported since version 0.37.0 ``` If the git repo contains submodules, you can tell Meson to clone them automatically by adding the following *(since 0.48.0)*: ```ini -clone-recursive=true +clone-recursive = true ``` ## Using wrapped projects @@ -121,12 +121,12 @@ clone-recursive=true To use a subproject simply do this in your top level `meson.build`. ```meson -foobar_sp = subproject('foobar') +foobar_proj = subproject('foobar') ``` Usually dependencies consist of some header files plus a library to -link against. To do this you would declare this internal dependency -like this: +link against. To do this in a project so it can be used as a subproject you +would declare this internal dependency like this: ```meson foobar_dep = declare_dependency(link_with : mylib, @@ -137,7 +137,7 @@ Then in your main project you would use them like this: ```meson executable('toplevel_exe', 'prog.c', - dependencies : foobar_sp.get_variable('foobar_dep')) + dependencies : foobar_proj.get_variable('foobar_dep')) ``` Note that the subproject object is *not* used as the dependency, but @@ -160,10 +160,10 @@ available. foobar_dep = dependency('foobar', required : false) if not foobar_dep.found() - foobar_subproj = subproject('foobar') + foobar_proj = subproject('foobar') # the subproject defines an internal dependency with # the command declare_dependency(). - foobar_dep = foobar_subproj.get_variable('foobar_dep') + foobar_dep = foobar_proj.get_variable('foobar_dep') endif executable('toplevel_exe', 'prog.c', diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 0e7e8e0..78c2877 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -361,6 +361,7 @@ class Backend: @staticmethod def _libdir_is_system(libdir, compilers, env): + libdir = os.path.normpath(libdir) for cc in compilers.values(): if libdir in cc.get_library_dirs(env): return True diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index b0fcfa4..11f8bb8 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -786,6 +786,7 @@ class XCodeBackend(backends.Backend): self.write_line('PRODUCT_NAME = %s;' % product_name) self.write_line('SECTORDER_FLAGS = "";') self.write_line('SYMROOT = "%s";' % symroot) + self.write_build_setting_line('SYSTEM_HEADER_SEARCH_PATHS', [self.environment.get_build_dir()]) self.write_line('USE_HEADERMAP = NO;') self.write_build_setting_line('WARNING_CFLAGS', ['-Wmost', '-Wno-four-char-constants', '-Wno-unknown-pragmas']) self.indent_level -= 1 @@ -860,16 +861,29 @@ class XCodeBackend(backends.Backend): self.write_line('};') self.ofile.write('/* End XCConfigurationList section */\n') - def write_build_setting_line(self, flag_name, flag_values): + def write_build_setting_line(self, flag_name, flag_values, explicit=False): if flag_values: - self.write_line('%s = (' % flag_name) - self.indent_level += 1 - for value in flag_values: - self.write_line('"%s",' % value) - self.indent_level -= 1 - self.write_line(');') + if len(flag_values) == 1: + value = flag_values[0] + if (' ' in value): + # If path contains spaces surround it with double colon + self.write_line('%s = "\\"%s\\"";' % (flag_name, value)) + else: + self.write_line('"%s",' % value) + else: + self.write_line('%s = (' % flag_name) + self.indent_level += 1 + for value in flag_values: + if (' ' in value): + # If path contains spaces surround it with double colon + self.write_line('"\\"%s\\"",' % value) + else: + self.write_line('"%s",' % value) + self.indent_level -= 1 + self.write_line(');') else: - self.write_line('%s = "";' % flag_name) + if explicit: + self.write_line('%s = "";' % flag_name) def generate_prefix(self): self.ofile.write('// !$*UTF8*$!\n{\n') diff --git a/mesonbuild/build.py b/mesonbuild/build.py index eb0e294..ee99806 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -37,6 +37,7 @@ lang_arg_kwargs = set([ 'd_import_dirs', 'd_unittest', 'd_module_versions', + 'd_debug', 'fortran_args', 'java_args', 'objc_args', @@ -737,9 +738,12 @@ just like those detected with the dependency() function.''') dfeature_unittest = kwargs.get('d_unittest', False) if dfeature_unittest: dfeatures['unittest'] = dfeature_unittest - dfeature_versions = kwargs.get('d_module_versions', None) + dfeature_versions = kwargs.get('d_module_versions', []) if dfeature_versions: dfeatures['versions'] = dfeature_versions + dfeature_debug = kwargs.get('d_debug', []) + if dfeature_debug: + dfeatures['debug'] = dfeature_debug if 'd_import_dirs' in kwargs: dfeature_import_dirs = extract_as_list(kwargs, 'd_import_dirs', unholder=True) for d in dfeature_import_dirs: diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 7c6a43b..73721e4 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -217,7 +217,7 @@ class CCompiler(Compiler): paths = [] for p in pathstr.split(sep): p = Path(p) - if p.exists(): + if p.exists() and p.resolve().as_posix() not in paths: paths.append(p.resolve().as_posix()) return tuple(paths) @@ -232,8 +232,34 @@ class CCompiler(Compiler): return () @functools.lru_cache() - def get_library_dirs(self, env): - return self.get_compiler_dirs(env, 'libraries') + def get_library_dirs(self, env, elf_class = None): + dirs = self.get_compiler_dirs(env, 'libraries') + if elf_class is None or elf_class == 0: + return dirs + + # if we do have an elf class for 32-bit or 64-bit, we want to check that + # the directory in question contains libraries of the appropriate class. Since + # system directories aren't mixed, we only need to check one file for each + # directory and go by that. If we can't check the file for some reason, assume + # the compiler knows what it's doing, and accept the directory anyway. + retval = [] + for d in dirs: + files = [f for f in os.listdir(d) if f.endswith('.so') and os.path.isfile(os.path.join(d, f))] + # if no files, accept directory and move on + if len(files) == 0: + retval.append(d) + continue + file_to_check = os.path.join(d, files[0]) + with open(file_to_check, 'rb') as fd: + header = fd.read(5) + # if file is not an ELF file, it's weird, but accept dir + # if it is elf, and the class matches, accept dir + if header[1:4] != b'ELF' or int(header[4]) == elf_class: + retval.append(d) + # at this point, it's an ELF file which doesn't match the + # appropriate elf_class, so skip this one + pass + return tuple(retval) @functools.lru_cache() def get_program_dirs(self, env): @@ -935,6 +961,13 @@ class CCompiler(Compiler): return f return None + @functools.lru_cache() + def output_is_64bit(self, env): + ''' + returns true if the output produced is 64-bit, false if 32-bit + ''' + return self.sizeof('void *', '', env) == 8 + def find_library_real(self, libname, env, extra_dirs, code, libtype): # First try if we can just add the library as -l. # Gcc + co seem to prefer builtin lib dirs to -L dirs. @@ -950,8 +983,18 @@ class CCompiler(Compiler): # Not found or we want to use a specific libtype? Try to find the # library file itself. patterns = self.get_library_naming(env, libtype) + # try to detect if we are 64-bit or 32-bit. If we can't + # detect, we will just skip path validity checks done in + # get_library_dirs() call + try: + if self.output_is_64bit(env): + elf_class = 2 + else: + elf_class = 1 + except: + elf_class = 0 # Search in the specified dirs, and then in the system libraries - for d in itertools.chain(extra_dirs, self.get_library_dirs(env)): + for d in itertools.chain(extra_dirs, self.get_library_dirs(env, elf_class)): for p in patterns: trial = self._get_trials_from_pattern(p, d, libname) if not trial: @@ -986,12 +1029,12 @@ class CCompiler(Compiler): return self.find_library_impl(libname, env, extra_dirs, code, libtype) def thread_flags(self, env): - if for_haiku(self.is_cross, env): + if for_haiku(self.is_cross, env) or for_darwin(self.is_cross, env): return [] return ['-pthread'] def thread_link_flags(self, env): - if for_haiku(self.is_cross, env): + if for_haiku(self.is_cross, env) or for_darwin(self.is_cross, env): return [] return ['-pthread'] diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 87bf5af..26aeba7 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -299,7 +299,7 @@ msvc_optimization_args = {'0': [], 'g': ['/O0'], '1': ['/O1'], '2': ['/O2'], - '3': ['/O3'], + '3': ['/O2'], 's': ['/O1'], # Implies /Os. } diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index e9ceafb..2865b1f 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -30,14 +30,17 @@ from .compilers import ( ) d_feature_args = {'gcc': {'unittest': '-funittest', + 'debug': '-fdebug', 'version': '-fversion', 'import_dir': '-J' }, 'llvm': {'unittest': '-unittest', + 'debug': '-d-debug', 'version': '-d-version', 'import_dir': '-J' }, 'dmd': {'unittest': '-unittest', + 'debug': '-debug', 'version': '-version', 'import_dir': '-J' } @@ -168,16 +171,53 @@ class DCompiler(Compiler): if unittest: res.append(unittest_arg) + if 'debug' in kwargs: + debug_level = -1 + debugs = kwargs.pop('debug') + if not isinstance(debugs, list): + debugs = [debugs] + + debug_arg = d_feature_args[self.id]['debug'] + if not debug_arg: + raise EnvironmentException('D compiler %s does not support conditional debug identifiers.' % self.name_string()) + + # Parse all debug identifiers and the largest debug level identifier + for d in debugs: + if isinstance(d, int): + if d > debug_level: + debug_level = d + elif isinstance(d, str) and d.isdigit(): + if int(d) > debug_level: + debug_level = int(d) + else: + res.append('{0}={1}'.format(debug_arg, d)) + + if debug_level >= 0: + res.append('{0}={1}'.format(debug_arg, debug_level)) + if 'versions' in kwargs: + version_level = -1 versions = kwargs.pop('versions') if not isinstance(versions, list): versions = [versions] version_arg = d_feature_args[self.id]['version'] if not version_arg: - raise EnvironmentException('D compiler %s does not support the "feature versions" feature.' % self.name_string()) + raise EnvironmentException('D compiler %s does not support conditional version identifiers.' % self.name_string()) + + # Parse all version identifiers and the largest version level identifier for v in versions: - res.append('{0}={1}'.format(version_arg, v)) + if isinstance(v, int): + if v > version_level: + version_level = v + elif isinstance(v, str) and v.isdigit(): + if int(v) > version_level: + version_level = int(v) + else: + res.append('{0}={1}'.format(version_arg, v)) + + if version_level >= 0: + res.append('{0}={1}'.format(version_arg, version_level)) if 'import_dirs' in kwargs: import_dirs = kwargs.pop('import_dirs') @@ -378,7 +418,11 @@ class DCompiler(Compiler): return args def get_debug_args(self, is_debug): - return clike_debug_args[is_debug] + ddebug_args = [] + if is_debug: + ddebug_args = [d_feature_args[self.id]['debug']] + + return clike_debug_args[is_debug] + ddebug_args def get_crt_args(self, crt_val, buildtype): if not is_windows(): diff --git a/mesonbuild/dependencies/__init__.py b/mesonbuild/dependencies/__init__.py index 00b6fa2..0375537 100644 --- a/mesonbuild/dependencies/__init__.py +++ b/mesonbuild/dependencies/__init__.py @@ -18,7 +18,7 @@ from .base import ( # noqa: F401 ExternalDependency, NotFoundDependency, ExternalLibrary, ExtraFrameworkDependency, InternalDependency, PkgConfigDependency, find_external_dependency, get_dep_identifier, packages, _packages_accept_language) from .dev import GMockDependency, GTestDependency, LLVMDependency, ValgrindDependency -from .misc import (MPIDependency, OpenMPDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency) +from .misc import (MPIDependency, OpenMPDependency, Python3Dependency, ThreadDependency, PcapDependency, CupsDependency, LibWmfDependency, LibGCryptDependency) from .platform import AppleFrameworks from .ui import GLDependency, GnuStepDependency, Qt4Dependency, Qt5Dependency, SDL2Dependency, WxDependency, VulkanDependency @@ -39,6 +39,7 @@ packages.update({ 'pcap': PcapDependency, 'cups': CupsDependency, 'libwmf': LibWmfDependency, + 'libgcrypt': LibGCryptDependency, # From platform: 'appleframeworks': AppleFrameworks, diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py index d8289c5..1e7c3e8 100644 --- a/mesonbuild/dependencies/dev.py +++ b/mesonbuild/dependencies/dev.py @@ -16,6 +16,7 @@ # development purposes, such as testing, debugging, etc.. import functools +import glob import os import re @@ -27,6 +28,17 @@ from .base import ( ) +def get_shared_library_suffix(environment, native): + """This is only gauranteed to work for languages that compile to machine + code, not for languages like C# that use a bytecode and always end in .dll + """ + if mesonlib.for_windows(native, environment): + return '.dll' + elif mesonlib.for_darwin(native, environment): + return '.dylib' + return '.so' + + class GTestDependency(ExternalDependency): def __init__(self, environment, kwargs): super().__init__('gtest', environment, 'cpp', kwargs) @@ -235,7 +247,7 @@ class LLVMDependency(ConfigToolDependency): self.compile_args = list(cargs.difference(self.__cpp_blacklist)) if version_compare(self.version, '>= 3.9'): - self._set_new_link_args() + self._set_new_link_args(environment) else: self._set_old_link_args() self.link_args = strip_system_libdirs(environment, self.link_args) @@ -258,18 +270,63 @@ class LLVMDependency(ConfigToolDependency): new_args.append(arg) return new_args - def _set_new_link_args(self): + def __check_libfiles(self, shared): + """Use llvm-config's --libfiles to check if libraries exist.""" + mode = '--link-shared' if shared else '--link-static' + + # Set self.required to true to force an exception in get_config_value + # if the returncode != 0 + restore = self.required + self.required = True + + try: + # It doesn't matter what the stage is, the caller needs to catch + # the exception anyway. + self.link_args = self.get_config_value(['--libfiles', mode], '') + finally: + self.required = restore + + def _set_new_link_args(self, environment): """How to set linker args for LLVM versions >= 3.9""" - if ((mesonlib.is_dragonflybsd() or mesonlib.is_freebsd()) and not - self.static and version_compare(self.version, '>= 4.0')): - # llvm-config on DragonFly BSD and FreeBSD for versions 4.0, 5.0, - # and 6.0 have an error when generating arguments for shared mode - # linking, even though libLLVM.so is installed, because for some - # reason the tool expects to find a .so for each static library. - # This works around that. - self.link_args = self.get_config_value(['--ldflags'], 'link_args') - self.link_args.append('-lLLVM') - return + mode = self.get_config_value(['--shared-mode'], 'link_args')[0] + if not self.static and mode == 'static': + # If llvm is configured with LLVM_BUILD_LLVM_DYLIB but not with + # LLVM_LINK_LLVM_DYLIB and not LLVM_BUILD_SHARED_LIBS (which + # upstreams doesn't recomend using), then llvm-config will lie to + # you about how to do shared-linking. It wants to link to a a bunch + # of individual shared libs (which don't exist because llvm wasn't + # built with LLVM_BUILD_SHARED_LIBS. + # + # Therefore, we'll try to get the libfiles, if the return code is 0 + # or we get an empty list, then we'll try to build a working + # configuration by hand. + try: + self.__check_libfiles(True) + except DependencyException: + lib_ext = get_shared_library_suffix(environment, self.native) + libdir = self.get_config_value(['--libdir'], 'link_args')[0] + # Sort for reproducability + matches = sorted(glob.iglob(os.path.join(libdir, 'libLLVM*{}'.format(lib_ext)))) + if not matches: + if self.required: + raise + return + + self.link_args = self.get_config_value(['--ldflags'], 'link_args') + libname = os.path.basename(matches[0]).rstrip(lib_ext).lstrip('lib') + self.link_args.append('-l{}'.format(libname)) + return + elif self.static and mode == 'shared': + # If, however LLVM_BUILD_SHARED_LIBS is true # (*cough* gentoo *cough*) + # then this is correct. Building with LLVM_BUILD_SHARED_LIBS has a side + # effect, it stops the generation of static archives. Therefore we need + # to check for that and error out on static if this is the case + try: + self.__check_libfiles(False) + except DependencyException: + if self.required: + raise + link_args = ['--link-static', '--system-libs'] if self.static else ['--link-shared'] self.link_args = self.get_config_value( ['--libs', '--ldflags'] + link_args + list(self.required_modules), diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 5164512..a2f7daf 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -506,3 +506,34 @@ class LibWmfDependency(ExternalDependency): @staticmethod def get_methods(): return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL] + + +class LibGCryptDependency(ExternalDependency): + def __init__(self, environment, kwargs): + super().__init__('libgcrypt', environment, None, kwargs) + + @classmethod + def _factory(cls, environment, kwargs): + methods = cls._process_method_kw(kwargs) + candidates = [] + + if DependencyMethods.PKGCONFIG in methods: + candidates.append(functools.partial(PkgConfigDependency, 'libgcrypt', environment, kwargs)) + + if DependencyMethods.CONFIG_TOOL in methods: + candidates.append(functools.partial(ConfigToolDependency.factory, + 'libgcrypt', environment, None, kwargs, ['libgcrypt-config'], + 'libgcrypt-config', + LibGCryptDependency.tool_finish_init)) + + return candidates + + @staticmethod + def tool_finish_init(ctdep): + ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args') + ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args') + ctdep.version = ctdep.get_config_value(['--version'], 'version')[0] + + @staticmethod + def get_methods(): + return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL] diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 5128de4..1c2f034 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -331,14 +331,15 @@ class GnomeModule(ExtensionModule): for lib in dep.libraries: if hasattr(lib, 'held_object'): lib = lib.held_object - internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath)) - libdepflags = self._get_dependencies_flags(lib.get_external_deps(), state, depends, include_rpath, - use_gir_args, True) - cflags.update(libdepflags[0]) - internal_ldflags.update(libdepflags[1]) - external_ldflags.update(libdepflags[2]) - external_ldflags_nodedup += libdepflags[3] - gi_includes.update(libdepflags[4]) + if isinstance(lib, build.SharedLibrary): + internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath)) + libdepflags = self._get_dependencies_flags(lib.get_external_deps(), state, depends, include_rpath, + use_gir_args, True) + cflags.update(libdepflags[0]) + internal_ldflags.update(libdepflags[1]) + external_ldflags.update(libdepflags[2]) + external_ldflags_nodedup += libdepflags[3] + gi_includes.update(libdepflags[4]) extdepflags = self._get_dependencies_flags(dep.ext_deps, state, depends, include_rpath, use_gir_args, True) cflags.update(extdepflags[0]) @@ -518,7 +519,12 @@ class GnomeModule(ExtensionModule): ret = [] for lang in langs: - for link_arg in state.environment.coredata.get_external_link_args(lang): + if state.environment.is_cross_build(): + link_args = state.environment.cross_info.config["properties"].get(lang + '_link_args', "") + else: + link_args = state.environment.coredata.get_external_link_args(lang) + + for link_arg in link_args: if link_arg.startswith('-L'): ret.append(link_arg) @@ -691,7 +697,10 @@ class GnomeModule(ExtensionModule): def _get_external_args_for_langs(self, state, langs): ret = [] for lang in langs: - ret += state.environment.coredata.get_external_args(lang) + if state.environment.is_cross_build(): + ret += state.environment.cross_info.config["properties"].get(lang + '_args', "") + else: + ret += state.environment.coredata.get_external_args(lang) return ret @staticmethod @@ -1012,6 +1021,8 @@ This will become a hard error in the future.''') ldflags.update(external_ldflags) if state.environment.is_cross_build(): + cflags.update(state.environment.cross_info.config["properties"].get('c_args', "")) + ldflags.update(state.environment.cross_info.config["properties"].get('c_link_args', "")) compiler = state.environment.coredata.cross_compilers.get('c') else: cflags.update(state.environment.coredata.get_external_args('c')) diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py index a8e916a..237220f 100644 --- a/mesonbuild/modules/qt.py +++ b/mesonbuild/modules/qt.py @@ -116,11 +116,12 @@ class QtBaseModule: except Exception: return [] + @FeatureNewKwargs('qt.preprocess', '0.49.0', ['uic_extra_arguments']) @FeatureNewKwargs('qt.preprocess', '0.44.0', ['moc_extra_arguments']) - @permittedKwargs({'moc_headers', 'moc_sources', 'moc_extra_arguments', 'include_directories', 'dependencies', 'ui_files', 'qresources', 'method'}) + @permittedKwargs({'moc_headers', 'moc_sources', 'uic_extra_arguments', 'moc_extra_arguments', 'include_directories', 'dependencies', 'ui_files', 'qresources', 'method'}) def preprocess(self, state, args, kwargs): - rcc_files, ui_files, moc_headers, moc_sources, moc_extra_arguments, sources, include_directories, dependencies \ - = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'moc_extra_arguments', 'sources', 'include_directories', 'dependencies', pop = True) + rcc_files, ui_files, moc_headers, moc_sources, uic_extra_arguments, moc_extra_arguments, sources, include_directories, dependencies \ + = extract_as_list(kwargs, 'qresources', 'ui_files', 'moc_headers', 'moc_sources', 'uic_extra_arguments', 'moc_extra_arguments', 'sources', 'include_directories', 'dependencies', pop = True) sources += args[1:] method = kwargs.get('method', 'auto') self._detect_tools(state.environment, method) @@ -160,8 +161,9 @@ class QtBaseModule: if len(ui_files) > 0: if not self.uic.found(): raise MesonException(err_msg.format('UIC', 'uic-qt' + self.qt_version)) + arguments = uic_extra_arguments + ['-o', '@OUTPUT@', '@INPUT@'] ui_kwargs = {'output': 'ui_@BASENAME@.h', - 'arguments': ['-o', '@OUTPUT@', '@INPUT@']} + 'arguments': arguments} ui_gen = build.Generator([self.uic], ui_kwargs) ui_output = ui_gen.process_files('Qt{} ui'.format(self.qt_version), ui_files, state) sources.append(ui_output) diff --git a/mesonbuild/scripts/dist.py b/mesonbuild/scripts/dist.py index 6fa10ff..68cfcd0 100644 --- a/mesonbuild/scripts/dist.py +++ b/mesonbuild/scripts/dist.py @@ -26,6 +26,7 @@ from glob import glob from mesonbuild.environment import detect_ninja from mesonbuild.dependencies import ExternalProgram from mesonbuild.mesonlib import windows_proof_rmtree +from mesonbuild import mlog def create_hash(fname): hashname = fname + '.sha256sum' @@ -80,18 +81,26 @@ def run_dist_scripts(dist_root, dist_scripts): env = os.environ.copy() env['MESON_DIST_ROOT'] = dist_root for d in dist_scripts: - print('Processing dist script %s.' % d) + print('Processing dist script %s' % d) ddir, dname = os.path.split(d) ep = ExternalProgram(dname, search_dir=os.path.join(dist_root, ddir), silent=True) if not ep.found(): - sys.exit('Script %s could not be found in dist directory.' % d) + sys.exit('Script %s could not be found in dist directory' % d) pc = subprocess.run(ep.command, env=env) if pc.returncode != 0: - sys.exit('Dist script errored out.') + sys.exit('Dist script errored out') + + +def git_have_dirty_index(src_root): + '''Check whether there are uncommitted changes in git''' + ret = subprocess.call(['git', '-C', src_root, 'diff-index', '--quiet', 'HEAD']) + return ret == 1 def create_dist_git(dist_name, src_root, bld_root, dist_sub, dist_scripts): + if git_have_dirty_index(src_root): + mlog.warning('Repository has uncommitted changes that will not be included in the dist tarball') distdir = os.path.join(dist_sub, dist_name) if os.path.exists(distdir): shutil.rmtree(distdir) @@ -111,14 +120,21 @@ def create_dist_git(dist_name, src_root, bld_root, dist_sub, dist_scripts): return (xzname, ) +def hg_have_dirty_index(src_root): + '''Check whether there are uncommitted changes in hg''' + out = subprocess.check_output(['hg', '-R', src_root, 'summary']) + return b'commit: (clean)' not in out + def create_dist_hg(dist_name, src_root, bld_root, dist_sub, dist_scripts): - os.makedirs(dist_sub, exist_ok=True) + if hg_have_dirty_index(src_root): + mlog.warning('Repository has uncommitted changes that will not be included in the dist tarball') + os.makedirs(dist_sub, exist_ok=True) tarname = os.path.join(dist_sub, dist_name + '.tar') xzname = tarname + '.xz' subprocess.check_call(['hg', 'archive', '-R', src_root, '-S', '-t', 'tar', tarname]) if len(dist_scripts) > 0: - print('WARNING: dist scripts not supported in Mercurial projects.') + mlog.warning('dist scripts are not supported in Mercurial projects') with lzma.open(xzname, 'wb') as xf, open(tarname, 'rb') as tf: shutil.copyfileobj(tf, xf) os.unlink(tarname) @@ -129,7 +145,7 @@ def create_dist_hg(dist_name, src_root, bld_root, dist_sub, dist_scripts): def check_dist(packagename, meson_command): - print('Testing distribution package %s.' % packagename) + print('Testing distribution package %s' % packagename) unpackdir = tempfile.mkdtemp() builddir = tempfile.mkdtemp() installdir = tempfile.mkdtemp() @@ -142,21 +158,21 @@ def check_dist(packagename, meson_command): print('Running Meson on distribution package failed') return 1 if subprocess.call([ninja_bin], cwd=builddir) != 0: - print('Compiling the distribution package failed.') + print('Compiling the distribution package failed') return 1 if subprocess.call([ninja_bin, 'test'], cwd=builddir) != 0: - print('Running unit tests on the distribution package failed.') + print('Running unit tests on the distribution package failed') return 1 myenv = os.environ.copy() myenv['DESTDIR'] = installdir if subprocess.call([ninja_bin, 'install'], cwd=builddir, env=myenv) != 0: - print('Installing the distribution package failed.') + print('Installing the distribution package failed') return 1 finally: shutil.rmtree(unpackdir) shutil.rmtree(builddir) shutil.rmtree(installdir) - print('Distribution package %s tested.' % packagename) + print('Distribution package %s tested' % packagename) return 0 def run(args): @@ -177,7 +193,7 @@ def run(args): elif os.path.isdir(os.path.join(src_root, '.hg')): names = create_dist_hg(dist_name, src_root, bld_root, dist_sub, build.dist_scripts) else: - print('Dist currently only works with Git or Mercurial repos.') + print('Dist currently only works with Git or Mercurial repos') return 1 if names is None: return 1 diff --git a/mesonbuild/scripts/gtkdochelper.py b/mesonbuild/scripts/gtkdochelper.py index 04b4deb..01ced5b 100644 --- a/mesonbuild/scripts/gtkdochelper.py +++ b/mesonbuild/scripts/gtkdochelper.py @@ -66,7 +66,7 @@ def gtkdoc_run_check(cmd, cwd, library_paths=None): # This preserves the order of messages. p, out = Popen_safe(cmd, cwd=cwd, env=env, stderr=subprocess.STDOUT)[0:2] if p.returncode != 0: - err_msg = ["{!r} failed with status {:d}".format(cmd[0], p.returncode)] + err_msg = ["{!r} failed with status {:d}".format(cmd, p.returncode)] if out: err_msg.append(out) raise MesonException('\n'.join(err_msg)) diff --git a/run_unittests.py b/run_unittests.py index 8fe1c11..8bea2d0 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -37,7 +37,7 @@ import mesonbuild.coredata import mesonbuild.modules.gnome from mesonbuild.interpreter import Interpreter, ObjectHolder from mesonbuild.mesonlib import ( - is_windows, is_osx, is_cygwin, is_dragonflybsd, is_openbsd, + is_windows, is_osx, is_cygwin, is_dragonflybsd, is_openbsd, is_haiku, windows_proof_rmtree, python_command, version_compare, BuildDirLock, Version ) @@ -3270,17 +3270,17 @@ class LinuxlikeTests(BasePlatformTests): self.assertEqual(sorted(out), sorted(['libfoo >= 1.0'])) out = self._run(cmd + ['--cflags-only-other']).strip().split() - self.assertEqual(sorted(out), sorted(['-pthread', '-DCUSTOM'])) + self.check_pkg_flags_are_same(out, ['-pthread', '-DCUSTOM']) out = self._run(cmd + ['--libs-only-l', '--libs-only-other']).strip().split() - self.assertEqual(sorted(out), sorted(['-pthread', '-lcustom', - '-llibmain', '-llibexposed'])) + self.check_pkg_flags_are_same(out, ['-pthread', '-lcustom', + '-llibmain', '-llibexposed']) out = self._run(cmd + ['--libs-only-l', '--libs-only-other', '--static']).strip().split() - self.assertEqual(sorted(out), sorted(['-pthread', '-lcustom', - '-llibmain', '-llibexposed', - '-llibinternal', '-lcustom2', - '-lfoo'])) + self.check_pkg_flags_are_same(out, ['-pthread', '-lcustom', + '-llibmain', '-llibexposed', + '-llibinternal', '-lcustom2', + '-lfoo']) cmd = ['pkg-config', 'requires-test'] out = self._run(cmd + ['--print-requires']).strip().split('\n') @@ -3290,6 +3290,11 @@ class LinuxlikeTests(BasePlatformTests): out = self._run(cmd + ['--print-requires-private']).strip().split('\n') self.assertEqual(sorted(out), sorted(['libexposed', 'libfoo >= 1.0', 'libhello'])) + def check_pkg_flags_are_same(self, output, expected): + if is_osx() or is_haiku(): + expected = [x for x in expected if x != '-pthread'] + self.assertEqual(sorted(output), sorted(expected)) + def test_pkg_unfound(self): testdir = os.path.join(self.unit_test_dir, '23 unfound pkgconfig') self.init(testdir) diff --git a/test cases/common/14 configure file/meson.build b/test cases/common/14 configure file/meson.build index d7beeb1..a3601aa 100644 --- a/test cases/common/14 configure file/meson.build +++ b/test cases/common/14 configure file/meson.build @@ -12,20 +12,20 @@ assert(conf.get('var', 'default') == 'mystring', 'Get function is not working.') assert(conf.get('notthere', 'default') == 'default', 'Default value getting is not working.') cfile = configure_file(input : 'config.h.in', -output : 'config.h', -configuration : conf) + output : 'config.h', + configuration : conf) e = executable('inctest', 'prog.c', # Note that you should NOT do this. Don't add generated headers here # This tests that we do the right thing even if people add in conf files # to their sources. -cfile) + cfile) test('inctest', e) # Test if we can also pass files() as input configure_file(input : files('config.h.in'), - output : 'config2.h', - configuration : conf) + output : 'config2.h', + configuration : conf) # Now generate a header file with an external script. genprog = import('python3').find_python() @@ -93,8 +93,7 @@ dump = configuration_data() dump.set('ZERO', 0) config_templates = files(['config4a.h.in', 'config4b.h.in']) foreach config_template : config_templates - configure_file(input : config_template, output : '@BASENAME@', - configuration : dump) + configure_file(input : config_template, output : '@BASENAME@', configuration : dump) endforeach test('Substituted', executable('prog4', 'prog4.c')) @@ -123,8 +122,7 @@ conf5.set('var2', 'error') configure_file( input : 'config5.h.in', output : '@BASENAME@', - configuration : conf5 -) + configuration : conf5) test('test5', executable('prog5', 'prog5.c')) # Test escaping @@ -134,8 +132,7 @@ conf6.set('var2', 'bar') configure_file( input : 'config6.h.in', output : '@BASENAME@', - configuration : conf6 -) + configuration : conf6) test('test6', executable('prog6', 'prog6.c')) # test empty install dir string @@ -152,8 +149,7 @@ configure_file( input : 'config7.h.in', output : '@BASENAME@', format : 'cmake', - configuration : conf7 -) + configuration : conf7) test('test7', executable('prog7', 'prog7.c')) # Test copying of an empty configuration data object @@ -182,24 +178,21 @@ configure_file( input : 'config8.h.in', output : '@BASENAME@', encoding : 'koi8-r', - configuration : conf8 -) + configuration : conf8) # Test that passing an empty configuration_data() object to a file with # #mesondefine substitutions does not print the warning. configure_file( input: 'nosubst-nocopy1.txt.in', output: 'nosubst-nocopy1.txt', - configuration : configuration_data() -) + configuration : configuration_data()) # test that passing an empty configuration_data() object to a file with # @foo@ substitutions does not print the warning. configure_file( input: 'nosubst-nocopy2.txt.in', output: 'nosubst-nocopy2.txt', - configuration : configuration_data() -) + configuration : configuration_data()) # test that passing a configured file object to test() works, and that passing # an empty configuration_data() object to a file that leads to no substitutions @@ -207,27 +200,23 @@ configure_file( test_file = configure_file( input: 'test.py.in', output: 'test.py', - configuration: configuration_data() -) + configuration: configuration_data()) # Test that overwriting an existing file creates a warning. configure_file( input: 'test.py.in', output: 'double_output.txt', - configuration: conf -) + configuration: conf) configure_file( input: 'test.py.in', output: 'double_output.txt', - configuration: conf -) + configuration: conf) # Test that the same file name in a different subdir will not create a warning configure_file( input: 'test.py.in', output: 'no_write_conflict.txt', - configuration: conf -) + configuration: conf) test('configure-file', test_file) diff --git a/test cases/d/9 features/app.d b/test cases/d/9 features/app.d index 6b43bf0..05c56ca 100644 --- a/test cases/d/9 features/app.d +++ b/test cases/d/9 features/app.d @@ -41,6 +41,30 @@ void main (string[] args) exit (1); } } + + version (With_VersionInteger) + version(3) exit(0); + + version (With_Debug) + debug exit(0); + + version (With_DebugInteger) + debug(3) exit(0); + + version (With_DebugIdentifier) + debug(DebugIdentifier) exit(0); + + version (With_DebugAll) { + int dbg = 0; + debug dbg++; + debug(2) dbg++; + debug(3) dbg++; + debug(4) dbg++; + debug(DebugIdentifier) dbg++; + + if (dbg == 5) + exit(0); + } // we fail here exit (1); diff --git a/test cases/d/9 features/meson.build b/test cases/d/9 features/meson.build index 694e488..06f0341 100644 --- a/test cases/d/9 features/meson.build +++ b/test cases/d/9 features/meson.build @@ -1,4 +1,4 @@ -project('D Features', 'd') +project('D Features', 'd', default_options : ['debug=false']) # ONLY FOR BACKWARDS COMPATIBILITY. # DO NOT DO THIS IN NEW CODE! @@ -44,3 +44,63 @@ e_test = executable('dapp_test', d_unittest: true ) test('dapp_test', e_test) + +# test version level +e_version_int = executable('dapp_version_int', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_VersionInteger', 3], +) +test('dapp_version_int_t', e_version_int, args: ['debug']) + +# test version level failure +e_version_int_fail = executable('dapp_version_int_fail', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_VersionInteger', 2], +) +test('dapp_version_int_t_fail', e_version_int_fail, args: ['debug'], should_fail: true) + +# test debug conditions: disabled +e_no_debug = executable('dapp_no_debug', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_Debug'], +) +test('dapp_no_debug_t_fail', e_no_debug, args: ['debug'], should_fail: true) + +# test debug conditions: enabled +e_debug = executable('dapp_debug', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_Debug'], + d_debug: 1, +) +test('dapp_debug_t', e_debug, args: ['debug']) + +# test debug conditions: integer +e_debug_int = executable('dapp_debug_int', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_DebugInteger'], + d_debug: 3, +) +test('dapp_debug_int_t', e_debug_int, args: ['debug']) + +# test debug conditions: identifier +e_debug_ident = executable('dapp_debug_ident', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_DebugIdentifier'], + d_debug: 'DebugIdentifier', +) +test('dapp_debug_ident_t', e_debug_ident, args: ['debug']) + +# test with all debug conditions at once, and with redundant values +e_debug_all = executable('dapp_debug_all', + test_src, + d_import_dirs: [data_dir], + d_module_versions: ['With_DebugAll'], + d_debug: ['4', 'DebugIdentifier', 2, 'DebugIdentifierUnused'], +) +test('dapp_debug_all_t', e_debug_all, args: ['debug']) diff --git a/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c b/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c new file mode 100644 index 0000000..f131359 --- /dev/null +++ b/test cases/frameworks/24 libgcrypt/libgcrypt_prog.c @@ -0,0 +1,8 @@ +#include <gcrypt.h> + +int +main() +{ + gcry_check_version(NULL); + return 0; +} diff --git a/test cases/frameworks/24 libgcrypt/meson.build b/test cases/frameworks/24 libgcrypt/meson.build new file mode 100644 index 0000000..5aadb13 --- /dev/null +++ b/test cases/frameworks/24 libgcrypt/meson.build @@ -0,0 +1,23 @@ +project('libgcrypt test', 'c') + +wm = find_program('libgcrypt-config', required : false) +if not wm.found() + error('MESON_SKIP_TEST: libgcrypt-config not installed') +endif + +libgcrypt_dep = dependency('libgcrypt', version : '>= 1.0') +libgcrypt_ver = libgcrypt_dep.version() +assert(libgcrypt_ver.split('.').length() > 1, 'libgcrypt version is "@0@"'.format(libgcrypt_ver)) +message('libgcrypt version is "@0@"'.format(libgcrypt_ver)) +e = executable('libgcrypt_prog', 'libgcrypt_prog.c', dependencies : libgcrypt_dep) + +test('libgcrypttest', e) + +# Test using the method keyword: + +dependency('libgcrypt', method : 'config-tool') +dependency('libgcrypt', method : 'pkg-config', required: false) + +# Check we can apply a version constraint +dependency('libgcrypt', version: '>=@0@'.format(libgcrypt_dep.version()), method: 'pkg-config', required: false) +dependency('libgcrypt', version: '>=@0@'.format(libgcrypt_dep.version()), method: 'config-tool') |