From 48e38fbaeb915aee5973c4fba1b2ac573ccac94a Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Thu, 15 Apr 2021 19:00:39 +0300 Subject: Xcode: fix custom targets that produce objs and libs. --- mesonbuild/backend/backends.py | 24 ++++++++++++++++++++++++ mesonbuild/backend/ninjabackend.py | 24 +----------------------- mesonbuild/backend/xcodebackend.py | 9 ++++++++- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 3482f3d..ea5f30d 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1149,6 +1149,30 @@ class Backend: # ${BUILDDIR}/${BUILDTYPE} instead, this becomes unnecessary. return self.get_target_dir(target) + @lru_cache(maxsize=None) + def get_normpath_target(self, source) -> str: + return os.path.normpath(source) + + def get_custom_target_dir_include_args(self, target, compiler, *, absolute_path=False): + custom_target_include_dirs = [] + for i in target.get_generated_sources(): + # Generator output goes into the target private dir which is + # already in the include paths list. Only custom targets have their + # own target build dir. + if not isinstance(i, (build.CustomTarget, build.CustomTargetIndex)): + continue + idir = self.get_normpath_target(self.get_custom_target_output_dir(i)) + if not idir: + idir = '.' + if absolute_path: + idir = os.path.join(self.environment.get_build_dir(), idir) + if idir not in custom_target_include_dirs: + custom_target_include_dirs.append(idir) + incs = [] + for i in custom_target_include_dirs: + incs += compiler.get_include_args(i, False) + return incs + def eval_custom_target_command(self, target, absolute_outputs=False): # We want the outputs to be absolute only when using the VS backend # XXX: Maybe allow the vs backend to use relative paths too? diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index aa89932..e8a7d4b 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2109,7 +2109,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) args = [x.replace('@DEPFILE@', depfile) for x in base_args] args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output) for x in args] - args = self.replace_outputs(args, self.get_target_private_dir(target), outfilelist) + args = self.replace_outputs(args, self.get_target_private_dir(target), outfilelist) # We have consumed output files, so drop them from the list of remaining outputs. if len(generator.outputs) > 1: outfilelist = outfilelist[len(generator.outputs):] @@ -2314,28 +2314,6 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) return (rel_obj, rel_src) @lru_cache(maxsize=None) - def get_normpath_target(self, source) -> str: - return os.path.normpath(source) - - def get_custom_target_dir_include_args(self, target, compiler): - custom_target_include_dirs = [] - for i in target.get_generated_sources(): - # Generator output goes into the target private dir which is - # already in the include paths list. Only custom targets have their - # own target build dir. - if not isinstance(i, (build.CustomTarget, build.CustomTargetIndex)): - continue - idir = self.get_normpath_target(self.get_target_dir(i)) - if not idir: - idir = '.' - if idir not in custom_target_include_dirs: - custom_target_include_dirs.append(idir) - incs = [] - for i in custom_target_include_dirs: - incs += compiler.get_include_args(i, False) - return incs - - @lru_cache(maxsize=None) def generate_inc_dir(self, compiler, d, basedir, is_system): # Avoid superfluous '/.' at the end of paths when d is '.' if d not in ('', '.'): diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index e7f6846..e563b8e 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -55,6 +55,7 @@ OPT2XCODEOPT = {'0': '0', 's': 's', } BOOL2XCODEBOOL = {True: 'YES', False: 'NO'} +LINKABLE_EXTENSIONS = {'.o', '.a', '.obj', '.so', '.dylib'} class PbxItem: def __init__(self, value, comment = ''): @@ -210,7 +211,7 @@ class XCodeBackend(backends.Backend): return str(uuid.uuid4()).upper().replace('-', '')[:24] def get_target_dir(self, target): - dirname = os.path.join(target.get_subdir(), self.environment.coredata.get_option(OptionKey('buildtype'))) + dirname = os.path.join(self.environment.coredata.get_option(OptionKey('buildtype')), target.get_subdir()) os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) return dirname @@ -1160,6 +1161,11 @@ class XCodeBackend(backends.Backend): for o_abs in outputs: if o_abs.endswith('.o') or o_abs.endswith('.obj'): ldargs += [r'\"' + o_abs + r'\"'] + else: + (srcs, ofilenames, cmd) = self.eval_custom_target_command(o) + for ofname in ofilenames: + if os.path.splitext(ofname)[-1] in LINKABLE_EXTENSIONS: + ldargs += [r'\"' + os.path.join(self.environment.get_build_dir(), ofname) + r'\"'] ldstr = ' '.join(ldargs) valid = self.buildconfmap[target_name][buildtype] langargs = {} @@ -1189,6 +1195,7 @@ class XCodeBackend(backends.Backend): # This may break reproducible builds, in which case patches are welcome. lang_cargs += self.get_build_dir_include_args(target, compiler, absolute_path=True) lang_cargs += self.get_source_dir_include_args(target, compiler, absolute_path=True) + lang_cargs += self.get_custom_target_dir_include_args(target, compiler, absolute_path=True) langargs[langname] = args langargs[langname] += lang_cargs symroot = os.path.join(self.environment.get_build_dir(), target.subdir) -- cgit v1.1