diff options
Diffstat (limited to 'mesonbuild/compilers/c.py')
-rw-r--r-- | mesonbuild/compilers/c.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index c0cd0bc..0a90c8c 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -59,6 +59,7 @@ class CCompiler(Compiler): library_dirs_cache = {} program_dirs_cache = {} find_library_cache = {} + find_framework_cache = {} internal_libs = gnu_compiler_internal_libs @staticmethod @@ -1052,6 +1053,66 @@ class CCompiler(Compiler): code = 'int main(int argc, char **argv) { return 0; }' return self.find_library_impl(libname, env, extra_dirs, code, libtype) + def find_framework_paths(self, env): + ''' + These are usually /Library/Frameworks and /System/Library/Frameworks, + unless you select a particular macOS SDK with the -isysroot flag. + You can also add to this by setting -F in CFLAGS. + ''' + if self.id != 'clang': + raise MesonException('Cannot find framework path with non-clang compiler') + # Construct the compiler command-line + commands = self.get_exelist() + ['-v', '-E', '-'] + commands += self.get_always_args() + # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env + commands += env.coredata.get_external_args(self.language) + mlog.debug('Finding framework path by running: ', ' '.join(commands), '\n') + os_env = os.environ.copy() + os_env['LC_ALL'] = 'C' + _, _, stde = Popen_safe(commands, env=os_env, stdin=subprocess.PIPE) + paths = [] + for line in stde.split('\n'): + if '(framework directory)' not in line: + continue + # line is of the form: + # ` /path/to/framework (framework directory)` + paths.append(line[:-21].strip()) + return paths + + def find_framework_real(self, name, env, extra_dirs, allow_system): + code = 'int main(int argc, char **argv) { return 0; }' + link_args = [] + for d in extra_dirs: + link_args += ['-F' + d] + # We can pass -Z to disable searching in the system frameworks, but + # then we must also pass -L/usr/lib to pick up libSystem.dylib + extra_args = [] if allow_system else ['-Z', '-L/usr/lib'] + link_args += ['-framework', name] + if self.links(code, env, extra_args=(extra_args + link_args)): + return link_args + + def find_framework_impl(self, name, env, extra_dirs, allow_system): + if isinstance(extra_dirs, str): + extra_dirs = [extra_dirs] + key = (tuple(self.exelist), name, tuple(extra_dirs), allow_system) + if key in self.find_framework_cache: + value = self.find_framework_cache[key] + else: + value = self.find_framework_real(name, env, extra_dirs, allow_system) + self.find_framework_cache[key] = value + if value is None: + return None + return value[:] + + def find_framework(self, name, env, extra_dirs, allow_system=True): + ''' + Finds the framework with the specified name, and returns link args for + the same or returns None when the framework is not found. + ''' + if self.id != 'clang': + raise MesonException('Cannot find frameworks with non-clang compiler') + return self.find_framework_impl(name, env, extra_dirs, allow_system) + def thread_flags(self, env): if for_haiku(self.is_cross, env) or for_darwin(self.is_cross, env): return [] |