aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-04-05 12:41:32 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2021-04-05 12:41:32 +0300
commit6043016a380237c9ee859f9dee77dfca52c794ed (patch)
tree69437dd2eacbd8b8e6d557eea4eedea5c097e73e
parent2d8332e7f1b290fd6c0bfc000eda9a4b9dd82321 (diff)
downloadmeson-6043016a380237c9ee859f9dee77dfca52c794ed.zip
meson-6043016a380237c9ee859f9dee77dfca52c794ed.tar.gz
meson-6043016a380237c9ee859f9dee77dfca52c794ed.tar.bz2
Refactor Xcode target generation to its own method.
-rw-r--r--mesonbuild/backend/xcodebackend.py238
1 files changed, 122 insertions, 116 deletions
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index d8876cf..6b73f00 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -42,6 +42,11 @@ XCODETYPEMAP = {'c': 'sourcecode.c.c',
's': 'sourcecode.asm',
'asm': 'sourcecode.asm',
}
+LANGNAMEMAP = {'c': 'C',
+ 'cpp': 'CPLUSPLUS',
+ 'objc': 'OBJC',
+ 'objcpp': 'OBJCPLUSPLUS',
+ }
class PbxItem:
def __init__(self, value, comment = ''):
@@ -727,7 +732,6 @@ class XCodeBackend(backends.Backend):
settings_dict.add_item('COMBINE_HIDPI_IMAGES', 'YES')
settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', 'NO')
settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO')
- settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', 0)
settings_dict.add_item('GCC_PREPROCESSOR_DEFINITIONS', '""')
settings_dict.add_item('GCC_SYMBOLS_PRIVATE_EXTERN', 'NO')
settings_dict.add_item('INSTALL_PATH', '""')
@@ -756,7 +760,6 @@ class XCodeBackend(backends.Backend):
settings_dict.add_item('COMBINE_HIDPI_IMAGES', 'YES')
settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', 'NO')
settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO')
- settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', 0)
settings_dict.add_item('GCC_PREPROCESSOR_DEFINITIONS', '""')
settings_dict.add_item('GCC_SYMBOLS_PRIVATE_EXTERN', 'NO')
settings_dict.add_item('INSTALL_PATH', '""')
@@ -775,121 +778,124 @@ class XCodeBackend(backends.Backend):
bt_dict.add_item('name', f'"{buildtype}"')
# Now finally targets.
- langnamemap = {'c': 'C', 'cpp': 'CPLUSPLUS', 'objc': 'OBJC', 'objcpp': 'OBJCPLUSPLUS'}
for target_name, target in self.build.get_build_targets().items():
- for buildtype in self.buildtypes:
- dep_libs = []
- links_dylib = False
- headerdirs = []
- for d in target.include_dirs:
- for sd in d.incdirs:
- cd = os.path.join(d.curdir, sd)
- headerdirs.append(os.path.join(self.environment.get_source_dir(), cd))
- headerdirs.append(os.path.join(self.environment.get_build_dir(), cd))
- for l in target.link_targets:
- abs_path = os.path.join(self.environment.get_build_dir(),
- l.subdir, buildtype, l.get_filename())
- dep_libs.append("'%s'" % abs_path)
- if isinstance(l, build.SharedLibrary):
- links_dylib = True
- if links_dylib:
- dep_libs = ['-Wl,-search_paths_first', '-Wl,-headerpad_max_install_names'] + dep_libs
- dylib_version = None
- if isinstance(target, build.SharedLibrary):
- ldargs = ['-dynamiclib', '-Wl,-headerpad_max_install_names'] + dep_libs
- install_path = os.path.join(self.environment.get_build_dir(), target.subdir, buildtype)
- dylib_version = target.soversion
- else:
- ldargs = dep_libs
- install_path = ''
- if dylib_version is not None:
- product_name = target.get_basename() + '.' + dylib_version
- else:
- product_name = target.get_basename()
- ldargs += target.link_args
- linker, stdlib_args = self.determine_linker_and_stdlib_args(target)
- ldargs += self.build.get_project_link_args(linker, target.subproject, target.for_machine)
- ldargs += self.build.get_global_link_args(linker, target.for_machine)
- cargs = []
- for dep in target.get_external_deps():
- cargs += dep.get_compile_args()
- ldargs += dep.get_link_args()
- ldstr = ' '.join(ldargs)
- valid = self.buildconfmap[target_name][buildtype]
- langargs = {}
- for lang in self.environment.coredata.compilers[target.for_machine]:
- if lang not in langnamemap:
- continue
- # Add compile args added using add_project_arguments()
- pargs = self.build.projects_args[target.for_machine].get(target.subproject, {}).get(lang, [])
- # Add compile args added using add_global_arguments()
- # These override per-project arguments
- gargs = self.build.global_args[target.for_machine].get(lang, [])
- targs = target.get_extra_args(lang)
- args = pargs + gargs + targs
- if args:
- langname = langnamemap[lang]
- compiler = target.compilers.get(lang)
- lang_cargs = cargs
- if compiler and target.implicit_include_directories:
- lang_cargs += self.get_build_dir_include_args(target, compiler)
- langargs[langname] = args
- langargs[langname] += lang_cargs
- symroot = os.path.join(self.environment.get_build_dir(), target.subdir)
- bt_dict = PbxDict()
- objects_dict.add_item(valid, bt_dict, buildtype)
- bt_dict.add_item('isa', 'XCBuildConfiguration')
- settings_dict = PbxDict()
- bt_dict.add_item('buildSettings', settings_dict)
- settings_dict.add_item('COMBINE_HIDPI_IMAGES', 'YES')
- if dylib_version is not None:
- settings_dict.add_item('DYLIB_CURRENT_VERSION', f'"{dylib_version}')
- settings_dict.add_item('EXECUTABLE_PREFIX', f'"{target.prefix}"')
- if target.suffix == '':
- suffix = ''
- else:
- suffix = '.' + target.suffix
- settings_dict.add_item('EXECUTABLE_SUFFIX', f'"{suffix}"')
- settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES')
- settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO')
- settings_dict.add_item('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 "{}". Target "{}" might not compile correctly.'.format(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)"
- settings_dict.add_item('GCC_PRECOMPILE_PREFIX_HEADER', 'YES')
- settings_dict.add_item('GCC_PREFIX_HEADER', f'"$(PROJECT_DIR)/{relative_pch_path}"')
- settings_dict.add_item('GCC_PREPROCESSOR_DEFINITIONS', '""')
- settings_dict.add_item('GCC_SYMBOLS_PRIVATE_EXTERN', 'NO')
- if headerdirs:
- quotedh = ','.join(['"\\"%s\\""' % i for i in headerdirs])
- settings_dict.add_item('HEADER_SEARCH_PATHS', f'({quotedh}')
- settings_dict.add_item('INSTALL_PATH', f'"{install_path}"')
- settings_dict.add_item('LIBRARY_SEARCH_PATHS', '""')
- if isinstance(target, build.SharedLibrary):
- settings_dict.add_item('LIBRARY_STYLE', 'DYNAMIC')
- for langname, args in langargs.items():
- settings_dict.add_item(f'OTHER_{langname}FLAGS', args)
- settings_dict.add_item('OTHER_LDFLAGS', f'"{ldstr}"')
- settings_dict.add_item('OTHER_REZFLAGS', '""')
- settings_dict.add_item('PRODUCT_NAME', product_name)
- settings_dict.add_item('SECTORDER_FLAGS', '""')
- settings_dict.add_item('SYMROOT', f'"{symroot}"')
- settings_dict.add_item('SYSTEM_HEADER_SEARCH_PATHS', '"{}"'.format(self.environment.get_build_dir()))
- settings_dict.add_item('USE_HEADERMAP', 'NO')
- warn_array = PbxArray()
- settings_dict.add_item('WARNING_CFLAGS', warn_array)
- warn_array.add_item('"-Wmost"')
- warn_array.add_item('"-Wno-four-char-constants"')
- warn_array.add_item('"-Wno-unknown-pragmas"')
- bt_dict.add_item('name', buildtype)
+ self.generate_single_build_target(objects_dict, target_name, target)
+
+
+ def generate_single_build_target(self, objects_dict, target_name, target):
+ for buildtype in self.buildtypes:
+ dep_libs = []
+ links_dylib = False
+ headerdirs = []
+ for d in target.include_dirs:
+ for sd in d.incdirs:
+ cd = os.path.join(d.curdir, sd)
+ headerdirs.append(os.path.join(self.environment.get_source_dir(), cd))
+ headerdirs.append(os.path.join(self.environment.get_build_dir(), cd))
+ for l in target.link_targets:
+ abs_path = os.path.join(self.environment.get_build_dir(),
+ l.subdir, buildtype, l.get_filename())
+ dep_libs.append("'%s'" % abs_path)
+ if isinstance(l, build.SharedLibrary):
+ links_dylib = True
+ if links_dylib:
+ dep_libs = ['-Wl,-search_paths_first', '-Wl,-headerpad_max_install_names'] + dep_libs
+ dylib_version = None
+ if isinstance(target, build.SharedLibrary):
+ ldargs = ['-dynamiclib', '-Wl,-headerpad_max_install_names'] + dep_libs
+ install_path = os.path.join(self.environment.get_build_dir(), target.subdir, buildtype)
+ dylib_version = target.soversion
+ else:
+ ldargs = dep_libs
+ install_path = ''
+ if dylib_version is not None:
+ product_name = target.get_basename() + '.' + dylib_version
+ else:
+ product_name = target.get_basename()
+ ldargs += target.link_args
+ linker, stdlib_args = self.determine_linker_and_stdlib_args(target)
+ ldargs += self.build.get_project_link_args(linker, target.subproject, target.for_machine)
+ ldargs += self.build.get_global_link_args(linker, target.for_machine)
+ cargs = []
+ for dep in target.get_external_deps():
+ cargs += dep.get_compile_args()
+ ldargs += dep.get_link_args()
+ ldstr = ' '.join(ldargs)
+ valid = self.buildconfmap[target_name][buildtype]
+ langargs = {}
+ for lang in self.environment.coredata.compilers[target.for_machine]:
+ if lang not in LANGNAMEMAP:
+ continue
+ # Add compile args added using add_project_arguments()
+ pargs = self.build.projects_args[target.for_machine].get(target.subproject, {}).get(lang, [])
+ # Add compile args added using add_global_arguments()
+ # These override per-project arguments
+ gargs = self.build.global_args[target.for_machine].get(lang, [])
+ targs = target.get_extra_args(lang)
+ args = pargs + gargs + targs
+ if args:
+ langname = langnamemap[lang]
+ compiler = target.compilers.get(lang)
+ lang_cargs = cargs
+ if compiler and target.implicit_include_directories:
+ lang_cargs += self.get_build_dir_include_args(target, compiler)
+ langargs[langname] = args
+ langargs[langname] += lang_cargs
+ symroot = os.path.join(self.environment.get_build_dir(), target.subdir)
+ bt_dict = PbxDict()
+ objects_dict.add_item(valid, bt_dict, buildtype)
+ bt_dict.add_item('isa', 'XCBuildConfiguration')
+ settings_dict = PbxDict()
+ bt_dict.add_item('buildSettings', settings_dict)
+ settings_dict.add_item('COMBINE_HIDPI_IMAGES', 'YES')
+ if dylib_version is not None:
+ settings_dict.add_item('DYLIB_CURRENT_VERSION', f'"{dylib_version}')
+ settings_dict.add_item('EXECUTABLE_PREFIX', f'"{target.prefix}"')
+ if target.suffix == '':
+ suffix = ''
+ else:
+ suffix = '.' + target.suffix
+ settings_dict.add_item('EXECUTABLE_SUFFIX', f'"{suffix}"')
+ settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', 'YES')
+ settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO')
+ settings_dict.add_item('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 "{}". Target "{}" might not compile correctly.'.format(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)"
+ settings_dict.add_item('GCC_PRECOMPILE_PREFIX_HEADER', 'YES')
+ settings_dict.add_item('GCC_PREFIX_HEADER', f'"$(PROJECT_DIR)/{relative_pch_path}"')
+ settings_dict.add_item('GCC_PREPROCESSOR_DEFINITIONS', '""')
+ settings_dict.add_item('GCC_SYMBOLS_PRIVATE_EXTERN', 'NO')
+ if headerdirs:
+ quotedh = ','.join(['"\\"%s\\""' % i for i in headerdirs])
+ settings_dict.add_item('HEADER_SEARCH_PATHS', f'({quotedh}')
+ settings_dict.add_item('INSTALL_PATH', f'"{install_path}"')
+ settings_dict.add_item('LIBRARY_SEARCH_PATHS', '""')
+ if isinstance(target, build.SharedLibrary):
+ settings_dict.add_item('LIBRARY_STYLE', 'DYNAMIC')
+ for langname, args in langargs.items():
+ settings_dict.add_item(f'OTHER_{langname}FLAGS', args)
+ settings_dict.add_item('OTHER_LDFLAGS', f'"{ldstr}"')
+ settings_dict.add_item('OTHER_REZFLAGS', '""')
+ settings_dict.add_item('PRODUCT_NAME', product_name)
+ settings_dict.add_item('SECTORDER_FLAGS', '""')
+ settings_dict.add_item('SYMROOT', f'"{symroot}"')
+ settings_dict.add_item('SYSTEM_HEADER_SEARCH_PATHS', '"{}"'.format(self.environment.get_build_dir()))
+ settings_dict.add_item('USE_HEADERMAP', 'NO')
+ warn_array = PbxArray()
+ settings_dict.add_item('WARNING_CFLAGS', warn_array)
+ warn_array.add_item('"-Wmost"')
+ warn_array.add_item('"-Wno-four-char-constants"')
+ warn_array.add_item('"-Wno-unknown-pragmas"')
+ bt_dict.add_item('name', buildtype)
def generate_xc_configurationList(self, objects_dict):
# FIXME: sort items