Merge pull request #4243 from nacho4d/feature/xcode-fix2

fixings for xcode backend
pull/4259/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 9ceb21997b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 81
      mesonbuild/backend/xcodebackend.py
  2. 1
      run_project_tests.py
  3. 4
      run_tests.py
  4. 7
      test cases/common/13 pch/meson.build

@ -16,7 +16,8 @@ from . import backends
from .. import build from .. import build
from .. import dependencies from .. import dependencies
from .. import mesonlib from .. import mesonlib
import uuid, os from .. import mlog
import uuid, os, operator
from ..mesonlib import MesonException from ..mesonlib import MesonException
@ -60,6 +61,12 @@ class XCodeBackend(backends.Backend):
os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True)
return dirname return dirname
def target_to_build_root(self, target):
if self.get_target_dir(target) == '':
return ''
directories = os.path.normpath(self.get_target_dir(target)).split(os.sep)
return os.sep.join(['..'] * len(directories))
def write_line(self, text): def write_line(self, text):
self.ofile.write(self.indent * self.indent_level + text) self.ofile.write(self.indent * self.indent_level + text)
if not text.endswith('\n'): if not text.endswith('\n'):
@ -202,36 +209,36 @@ class XCodeBackend(backends.Backend):
self.source_phase[t] = self.gen_id() self.source_phase[t] = self.gen_id()
def generate_pbx_aggregate_target(self): def generate_pbx_aggregate_target(self):
target_dependencies = list(map(lambda t: self.pbx_dep_map[t], self.build.targets))
aggregated_targets = []
aggregated_targets.append((self.all_id, 'ALL_BUILD', self.all_buildconf_id, [], target_dependencies))
aggregated_targets.append((self.test_id, 'RUN_TESTS', self.test_buildconf_id, [self.test_command_id], []))
# Sort objects by ID before writing
sorted_aggregated_targets = sorted(aggregated_targets, key=operator.itemgetter(0))
self.ofile.write('\n/* Begin PBXAggregateTarget section */\n') self.ofile.write('\n/* Begin PBXAggregateTarget section */\n')
self.write_line('%s /* ALL_BUILD */ = {' % self.all_id) for t in sorted_aggregated_targets:
name = t[1]
buildconf_id = t[2]
build_phases = t[3]
dependencies = t[4]
self.write_line('%s /* %s */ = {' % (t[0], name))
self.indent_level += 1 self.indent_level += 1
self.write_line('isa = PBXAggregateTarget;') self.write_line('isa = PBXAggregateTarget;')
self.write_line('buildConfigurationList = %s /* Build configuration list for PBXAggregateTarget "ALL_BUILD" */;' % self.all_buildconf_id) self.write_line('buildConfigurationList = %s /* Build configuration list for PBXAggregateTarget "%s" */;' % (buildconf_id, name))
self.write_line('buildPhases = (') self.write_line('buildPhases = (')
self.write_line(');')
self.write_line('dependencies = (')
self.indent_level += 1 self.indent_level += 1
for t in self.build.targets: for bp in build_phases:
self.write_line('%s /* PBXTargetDependency */,' % self.pbx_dep_map[t]) self.write_line('%s /* ShellScript */,' % bp)
self.indent_level -= 1 self.indent_level -= 1
self.write_line(');') self.write_line(');')
self.write_line('name = ALL_BUILD;') self.write_line('dependencies = (')
self.write_line('productName = ALL_BUILD;')
self.indent_level -= 1
self.write_line('};')
self.write_line('%s /* RUN_TESTS */ = {' % self.test_id)
self.indent_level += 1
self.write_line('isa = PBXAggregateTarget;')
self.write_line('buildConfigurationList = %s /* Build configuration list for PBXAggregateTarget "RUN_TESTS" */;' % self.test_buildconf_id)
self.write_line('buildPhases = (')
self.indent_level += 1 self.indent_level += 1
self.write_line('%s /* ShellScript */,' % self.test_command_id) for td in dependencies:
self.write_line('%s /* PBXTargetDependency */,' % td)
self.indent_level -= 1 self.indent_level -= 1
self.write_line(');') self.write_line(');')
self.write_line('dependencies = (') self.write_line('name = %s;' % name)
self.write_line(');') self.write_line('productName = %s;' % name)
self.write_line('name = RUN_TESTS;')
self.write_line('productName = RUN_TESTS;')
self.indent_level -= 1 self.indent_level -= 1
self.write_line('};') self.write_line('};')
self.ofile.write('/* End PBXAggregateTarget section */\n') self.ofile.write('/* End PBXAggregateTarget section */\n')
@ -594,14 +601,20 @@ class XCodeBackend(backends.Backend):
self.ofile.write('/* End PBXSourcesBuildPhase section */\n') self.ofile.write('/* End PBXSourcesBuildPhase section */\n')
def generate_pbx_target_dependency(self): def generate_pbx_target_dependency(self):
self.ofile.write('\n/* Begin PBXTargetDependency section */\n') targets = []
for t in self.build.targets: for t in self.build.targets:
idval = self.pbx_dep_map[t] # VERIFY: is this correct? idval = self.pbx_dep_map[t] # VERIFY: is this correct?
self.write_line('%s /* PBXTargetDependency */ = {' % idval) targets.append((idval, self.native_targets[t], t, self.containerproxy_map[t]))
# Sort object by ID
sorted_targets = sorted(targets, key=operator.itemgetter(0))
self.ofile.write('\n/* Begin PBXTargetDependency section */\n')
for t in sorted_targets:
self.write_line('%s /* PBXTargetDependency */ = {' % t[0])
self.indent_level += 1 self.indent_level += 1
self.write_line('isa = PBXTargetDependency;') self.write_line('isa = PBXTargetDependency;')
self.write_line('target = %s /* %s */;' % (self.native_targets[t], t)) self.write_line('target = %s /* %s */;' % (t[1], t[2]))
self.write_line('targetProxy = %s /* PBXContainerItemProxy */;' % self.containerproxy_map[t]) self.write_line('targetProxy = %s /* PBXContainerItemProxy */;' % t[3])
self.indent_level -= 1 self.indent_level -= 1
self.write_line('};') self.write_line('};')
self.ofile.write('/* End PBXTargetDependency section */\n') self.ofile.write('/* End PBXTargetDependency section */\n')
@ -743,6 +756,19 @@ class XCodeBackend(backends.Backend):
self.write_line('GCC_GENERATE_DEBUGGING_SYMBOLS = YES;') self.write_line('GCC_GENERATE_DEBUGGING_SYMBOLS = YES;')
self.write_line('GCC_INLINES_ARE_PRIVATE_EXTERN = NO;') self.write_line('GCC_INLINES_ARE_PRIVATE_EXTERN = NO;')
self.write_line('GCC_OPTIMIZATION_LEVEL = 0;') self.write_line('GCC_OPTIMIZATION_LEVEL = 0;')
if target.has_pch:
# Xcode uses GCC_PREFIX_HEADER which only allows one file per target/executable. Precompiling various header files and
# applying a particular pch to each source file will require custom scripts (as a build phase) and build flags per each
# file. Since Xcode itself already discourages precompiled headers in favor of modules we don't try much harder here.
pchs = target.get_pch('c') + target.get_pch('cpp') + target.get_pch('objc') + target.get_pch('objcpp')
# Make sure to use headers (other backends require implementation files like *.c *.cpp, etc; these should not be used here)
pchs = [pch for pch in pchs if pch.endswith('.h') or pch.endswith('.hh') or pch.endswith('hpp')]
if pchs:
if len(pchs) > 1:
mlog.warning('Unsupported Xcode configuration: More than 1 precompiled header found "%s". Target "%s" might not compile correctly.' % (str(pchs), target.name))
relative_pch_path = os.path.join(target.get_subdir(), pchs[0]) # Path relative to target so it can be used with "$(PROJECT_DIR)"
self.write_line('GCC_PRECOMPILE_PREFIX_HEADER = YES;')
self.write_line('GCC_PREFIX_HEADER = "$(PROJECT_DIR)/%s";' % relative_pch_path)
self.write_line('GCC_PREPROCESSOR_DEFINITIONS = "";') self.write_line('GCC_PREPROCESSOR_DEFINITIONS = "";')
self.write_line('GCC_SYMBOLS_PRIVATE_EXTERN = NO;') self.write_line('GCC_SYMBOLS_PRIVATE_EXTERN = NO;')
if len(headerdirs) > 0: if len(headerdirs) > 0:
@ -764,12 +790,13 @@ class XCodeBackend(backends.Backend):
self.write_build_setting_line('WARNING_CFLAGS', ['-Wmost', '-Wno-four-char-constants', '-Wno-unknown-pragmas']) self.write_build_setting_line('WARNING_CFLAGS', ['-Wmost', '-Wno-four-char-constants', '-Wno-unknown-pragmas'])
self.indent_level -= 1 self.indent_level -= 1
self.write_line('};') self.write_line('};')
self.write_line('name = "%s";' % buildtype) self.write_line('name = %s;' % buildtype)
self.indent_level -= 1 self.indent_level -= 1
self.write_line('};') self.write_line('};')
self.ofile.write('/* End XCBuildConfiguration section */\n') self.ofile.write('/* End XCBuildConfiguration section */\n')
def generate_xc_configurationList(self): def generate_xc_configurationList(self):
# FIXME: sort items
self.ofile.write('\n/* Begin XCConfigurationList section */\n') self.ofile.write('\n/* Begin XCConfigurationList section */\n')
self.write_line('%s /* Build configuration list for PBXProject "%s" */ = {' % (self.project_conflist, self.build.project_name)) self.write_line('%s /* Build configuration list for PBXProject "%s" */ = {' % (self.project_conflist, self.build.project_name))
self.indent_level += 1 self.indent_level += 1
@ -828,7 +855,7 @@ class XCodeBackend(backends.Backend):
self.indent_level -= 1 self.indent_level -= 1
self.write_line(');') self.write_line(');')
self.write_line('defaultConfigurationIsVisible = 0;') self.write_line('defaultConfigurationIsVisible = 0;')
self.write_line('defaultConfigurationName = "%s";' % typestr) self.write_line('defaultConfigurationName = %s;' % typestr)
self.indent_level -= 1 self.indent_level -= 1
self.write_line('};') self.write_line('};')
self.ofile.write('/* End XCConfigurationList section */\n') self.ofile.write('/* End XCConfigurationList section */\n')

@ -393,6 +393,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
def gather_tests(testdir: Path): def gather_tests(testdir: Path):
tests = [t.name for t in testdir.glob('*')] tests = [t.name for t in testdir.glob('*')]
tests = [t for t in tests if not t.startswith('.')] # Filter non-tests files (dot files, etc)
testlist = [(int(t.split()[0]), t) for t in tests] testlist = [(int(t.split()[0]), t) for t in tests]
testlist.sort() testlist.sort()
tests = [testdir / t[1] for t in testlist] tests = [testdir / t[1] for t in testlist]

@ -143,7 +143,9 @@ def get_backend_commands(backend, debug=False):
test_cmd = cmd + ['RUN_TESTS.vcxproj'] test_cmd = cmd + ['RUN_TESTS.vcxproj']
elif backend is Backend.xcode: elif backend is Backend.xcode:
cmd = ['xcodebuild'] cmd = ['xcodebuild']
clean_cmd = cmd + ['-alltargets', 'clean'] # In Xcode9 new build system's clean command fails when using a custom build directory.
# Maybe use it when CI uses Xcode10 we can remove '-UseNewBuildSystem=FALSE'
clean_cmd = cmd + ['-alltargets', 'clean', '-UseNewBuildSystem=FALSE']
test_cmd = cmd + ['-target', 'RUN_TESTS'] test_cmd = cmd + ['-target', 'RUN_TESTS']
elif backend is Backend.ninja: elif backend is Backend.ninja:
# We need at least 1.6 because of -w dupbuild=err # We need at least 1.6 because of -w dupbuild=err

@ -2,4 +2,9 @@ project('pch test', 'c', 'cpp')
subdir('c') subdir('c')
subdir('cpp') subdir('cpp')
subdir('mixed')
if meson.backend() == 'xcode'
warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.')
else
subdir('mixed')
endif

Loading…
Cancel
Save