diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 13 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 13 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 32 | ||||
-rw-r--r-- | mesonbuild/dependencies.py | 19 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 47 | ||||
-rw-r--r-- | test cases/frameworks/4 qt5/meson.build | 22 | ||||
-rw-r--r-- | test cases/linuxlike/2 external library/meson.build | 5 |
7 files changed, 75 insertions, 76 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 286afa9..fcb16ee 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -142,7 +142,7 @@ class Backend(): return os.path.relpath(os.path.join('dummyprefixdir', todir),\ os.path.join('dummyprefixdir', fromdir)) - def flatten_object_list(self, target, proj_dir_to_build_root=''): + def flatten_object_list(self, target, proj_dir_to_build_root='', include_dir_names=True): obj_list = [] for obj in target.get_objects(): if isinstance(obj, str): @@ -150,7 +150,7 @@ class Backend(): self.build_to_src, target.get_subdir(), obj) obj_list.append(o) elif isinstance(obj, build.ExtractedObjects): - obj_list += self.determine_ext_objs(obj, proj_dir_to_build_root) + obj_list += self.determine_ext_objs(obj, proj_dir_to_build_root, include_dir_names) else: raise MesonException('Unknown data type in object list.') return obj_list @@ -207,7 +207,7 @@ class Backend(): return c raise RuntimeError('Unreachable code') - def determine_ext_objs(self, extobj, proj_dir_to_build_root=''): + def determine_ext_objs(self, extobj, proj_dir_to_build_root='', include_dir_names=True): result = [] targetdir = self.get_target_private_dir(extobj.target) suffix = '.' + self.environment.get_object_suffix() @@ -221,7 +221,12 @@ class Backend(): if pathsegs[0] == 'subprojects': pathsegs = pathsegs[2:] fixedpath = os.sep.join(pathsegs) - objbase = osrc.fname.replace('/', '_').replace('\\', '_') + if include_dir_names: + objbase = osrc_base.replace('/', '_').replace('\\', '_') + else: + # vs2010 backend puts all obj files without directory prefixes into build dir, so just + # use the file name without a directory (will be stripped by os.path.basename() below). + objbase = osrc_base objname = os.path.join(proj_dir_to_build_root, targetdir, os.path.basename(objbase) + suffix) result.append(objname) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index a72681b..ac4f0b2 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -36,7 +36,7 @@ class Vs2010Backend(backends.Backend): super().__init__(build) self.project_file_version = '10.0.30319.1' # foo.c compiles to foo.obj, not foo.c.obj - self.source_suffix_in_obj = False + self.source_suffix_in_objs = False def generate_custom_generator_commands(self, target, parent_node): all_output_files = [] @@ -116,7 +116,7 @@ class Vs2010Backend(backends.Backend): result = {} for o in obj_list: if isinstance(o, build.ExtractedObjects): - result[o.target.get_basename()] = True + result[o.target.get_id()] = True return result.keys() def determine_deps(self, p): @@ -492,9 +492,10 @@ class Vs2010Backend(backends.Backend): rel_path = self.relpath(lobj.subdir, target.subdir) linkname = os.path.join(rel_path, lobj.get_import_filename()) additional_links.append(linkname) - for o in self.flatten_object_list(target, down): + additional_objects = [] + for o in self.flatten_object_list(target, down, include_dir_names=False): assert(isinstance(o, str)) - additional_links.append(o) + additional_objects.append(o) if len(additional_links) > 0: additional_links.append('%(AdditionalDependencies)') ET.SubElement(link, 'AdditionalDependencies').text = ';'.join(additional_links) @@ -549,13 +550,15 @@ class Vs2010Backend(backends.Backend): # just the file name instead of the relative path to the file. pch_file.text = os.path.split(header)[1] - if len(objects) > 0: + if len(objects) + len(additional_objects) > 0: # Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of # the CustomBuildStep Outputs. inc_objs = ET.SubElement(root, 'ItemGroup') for s in objects: relpath = s.rel_to_builddir(proj_to_src_root) ET.SubElement(inc_objs, 'Object', Include=relpath) + for s in additional_objects: + ET.SubElement(inc_objs, 'Object', Include=s) ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets') # Reference the regen target. ig = ET.SubElement(root, 'ItemGroup') diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index f3ddf8d..5461d07 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -190,7 +190,7 @@ class Compiler(): def unix_compile_flags_to_native(self, args): return args - def find_library(self, libname): + def find_library(self, libname, extra_dirs): raise EnvironmentException('Language {} does not support library finding.'.format(self.language)) class CCompiler(Compiler): @@ -298,6 +298,9 @@ class CCompiler(Compiler): def get_pch_name(self, header_name): return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix() + def get_linker_search_args(self, dirname): + return ['-L'+dirname] + def sanity_check(self, work_dir): mlog.debug('Sanity testing C compiler:', ' '.join(self.exelist)) mlog.debug('Is cross compiler: %s.' % str(self.is_cross)) @@ -566,14 +569,17 @@ void bar() { ''' return self.compiles(templ % (prefix, typename), extra_args) - def find_library(self, libname): + def find_library(self, libname, extra_dirs): code = '''int main(int argc, char **argv) { return 0; } ''' - linkarg = '-l' + libname - if self.links(code, extra_args=[linkarg]): - return linkarg + args = [] + for i in extra_dirs: + args += self.get_linker_search_args(i) + args.append('-l' + libname) + if self.links(code, extra_args=args): + return args return None def thread_flags(self): @@ -1144,6 +1150,9 @@ class VisualStudioCCompiler(CCompiler): def get_linker_output_args(self, outputname): return ['/OUT:' + outputname] + def get_linker_search_args(self, dirname): + return ['/LIBPATH:' + dirname] + def get_pic_args(self): return [] # PIC is handled by the loader on Windows @@ -1175,6 +1184,19 @@ class VisualStudioCCompiler(CCompiler): def build_rpath_args(self, build_dir, rpath_paths, install_rpath): return [] + def find_library(self, libname, extra_dirs): + code = '''int main(int argc, char **argv) { + return 0; +} + ''' + args = [] + for i in extra_dirs: + args += self.get_linker_search_args(i) + args.append(libname + '.lib') + if self.links(code, extra_args=args): + return args + return None + # FIXME, no idea what these should be. def thread_flags(self): return [] diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py index ee2dd62..b9f5c89 100644 --- a/mesonbuild/dependencies.py +++ b/mesonbuild/dependencies.py @@ -385,30 +385,29 @@ class ExternalProgram(): return self.name class ExternalLibrary(Dependency): - def __init__(self, name, fullpath=None, silent=False): + def __init__(self, name, link_args=None, silent=False): super().__init__() self.name = name # Rename fullpath to link_args once standalone find_library() gets removed. - if fullpath is not None: - if isinstance(fullpath, list): - self.fullpath = fullpath + if link_args is not None: + if isinstance(link_args, list): + self.link_args = link_args else: - self.fullpath = [fullpath] + self.link_args = [link_args] else: - self.fullpath = fullpath + self.link_args = link_args if not silent: if self.found(): - mlog.log('Library', mlog.bold(name), 'found:', mlog.green('YES'), - '(%s)' % self.fullpath) + mlog.log('Library', mlog.bold(name), 'found:', mlog.green('YES')) else: mlog.log('Library', mlog.bold(name), 'found:', mlog.red('NO')) def found(self): - return self.fullpath is not None + return self.link_args is not None def get_link_args(self): if self.found(): - return self.fullpath + return self.link_args return [] class BoostDependency(Dependency): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 2ade18a..35cbc3e 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -27,8 +27,6 @@ from functools import wraps import importlib -find_lib_deprecation_printed = False - class InterpreterException(coredata.MesonException): pass @@ -762,8 +760,14 @@ class CompilerHolder(InterpreterObject): required = kwargs.get('required', True) if not isinstance(required, bool): raise InterpreterException('required must be boolean.') - linkarg = self.compiler.find_library(libname) - lib = dependencies.ExternalLibrary(libname, linkarg) + search_dirs = kwargs.get('dirs', []) + for i in search_dirs: + if not os.path.isabs(i): + raise InvalidCode('Search directory %s is not an absolute path.' % i) + linkargs = self.compiler.find_library(libname, search_dirs) + if required and linkargs is None: + raise InterpreterException('Library %s not found'.format(libname)) + lib = dependencies.ExternalLibrary(libname, linkargs) return ExternalLibraryHolder(lib) class ModuleState: @@ -1542,40 +1546,7 @@ class Interpreter(): return progobj def func_find_library(self, node, args, kwargs): - global find_lib_deprecation_printed - if not find_lib_deprecation_printed: - find_lib_deprecation_printed = True - mlog.log(mlog.red('DEPRECATION:'), 'find_library() is deprecated, use the corresponding method in compiler object instead.') - self.validate_arguments(args, 1, [str]) - required = kwargs.get('required', True) - if not isinstance(required, bool): - raise InvalidArguments('"required" argument must be a boolean.') - libname = args[0] - # We do not cache found libraries because they can come - # and go between invocations wildly. As an example we - # may find the 64 bit version but need instead the 32 bit - # one that is not installed. If we cache the found path - # then we will never found the new one if it get installed. - # This causes a bit of a slowdown as libraries are rechecked - # on every regen, but since it is a fast operation it should be - # ok. - if 'dirs' in kwargs: - search_dirs = kwargs['dirs'] - if not isinstance(search_dirs, list): - search_dirs = [search_dirs] - for i in search_dirs: - if not isinstance(i, str): - raise InvalidCode('Directory entry is not a string.') - if not os.path.isabs(i): - raise InvalidCode('Search directory %s is not an absolute path.' % i) - else: - search_dirs = None - result = self.environment.find_library(libname, search_dirs) - extlib = dependencies.ExternalLibrary(libname, result) - libobj = ExternalLibraryHolder(extlib) - if required and not libobj.found(): - raise InvalidArguments('External library "%s" not found.' % libname) - return libobj + mlog.log(mlog.red('DEPRECATION:'), 'find_library() is removed, use the corresponding method in compiler object instead.') def func_dependency(self, node, args, kwargs): self.validate_arguments(args, 1, [str]) diff --git a/test cases/frameworks/4 qt5/meson.build b/test cases/frameworks/4 qt5/meson.build index bce9dbd..cfea5ba 100644 --- a/test cases/frameworks/4 qt5/meson.build +++ b/test cases/frameworks/4 qt5/meson.build @@ -4,15 +4,15 @@ qt5 = import('qt5') qt5dep = dependency('qt5', modules : ['Core', 'Gui', 'Widgets']) prep = qt5.preprocess( -moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use. -ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol. -qresources : 'stuff.qrc', # Resource file for rcc compiler. + moc_headers : ['mainWindow.h'], # These need to be fed through the moc tool before use. + ui_files : 'mainWindow.ui', # XML files that need to be compiled with the uic tol. + qresources : 'stuff.qrc', # Resource file for rcc compiler. ) q5exe = executable('qt5app', -sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing. -prep], -dependencies : qt5dep) + sources : ['main.cpp', 'mainWindow.cpp', # Sources that don't need preprocessing. + prep], + dependencies : qt5dep) # We need a console test application because some test environments # do not have an X server. @@ -20,7 +20,7 @@ dependencies : qt5dep) qt5core = dependency('qt5', modules : 'Core') qt5coreapp = executable('q5core', 'q5core.cpp', -dependencies : qt5core) + dependencies : qt5core) test('qt5test', qt5coreapp) @@ -28,11 +28,11 @@ test('qt5test', qt5coreapp) # headers but the user must manually include moc # files from sources. manpreprocessed = qt5.preprocess( -moc_sources : 'manualinclude.cpp', -moc_headers : 'manualinclude.h') + moc_sources : 'manualinclude.cpp', + moc_headers : 'manualinclude.h') q5maninclude = executable('q5maninclude', -sources : ['manualinclude.cpp', manpreprocessed], -dependencies : qt5core) + sources : ['manualinclude.cpp', manpreprocessed], + dependencies : qt5core) test('q5maninclude', q5maninclude) diff --git a/test cases/linuxlike/2 external library/meson.build b/test cases/linuxlike/2 external library/meson.build index f83affc..5839c1a 100644 --- a/test cases/linuxlike/2 external library/meson.build +++ b/test cases/linuxlike/2 external library/meson.build @@ -1,8 +1,7 @@ project('external library', 'c') cc = meson.get_compiler('c') -zlib = find_library('z') # DEPRECATED -zlib2 = cc.find_library('z') # The modern way. +zlib = cc.find_library('z') # Verify that link testing works. linkcode = '''#include<zlib.h> @@ -25,7 +24,7 @@ assert(not cc.links(nolinkcode, name : 'Failing link'), 'Linking succeeded when e = executable('zprog', 'prog.c', dependencies : zlib) test('libtest', e) -e2 = executable('zprog_alt', 'prog.c', dependencies : zlib2) +e2 = executable('zprog_alt', 'prog.c', dependencies : zlib) test('libtest_alt', e2) # Test that ext deps work via an internal dep. |