def _load_uor_doc_and_versions(self): """Load the doc and version metadata for uors. Loading version numbers is done after loading other metadata because the version of one uor may refer to that of another. """ uor_map = repocontextutil.get_uor_map(self.repo_context) for uor in uor_map.values(): uor.doc = repoloadutil.get_uor_doc(uor) uor.version = repoloadutil.get_uor_version(uor, uor_map)
def make_build_config(repo_context, build_flags_parser, uplid, ufid, default_rules, debug_keys=[]): """Create a build configuration for repository. Args: repo_context (RepoContext): Repository structure and metadata. build_flags_parser (BuildFlagsParser): Parser for build flags. uplid (Uplid): Build platform id. ufid (Ufid): Build flags id. default_rules (list of OptionRule): Option rules that is the base of all UORs. debug_keys (list of str): Print some debug information for some option keys. """ build_config = buildconfig.BuildConfig(repo_context.root_path, uplid, ufid) for unit in repo_context.units.values(): if unit.type_ == repounits.UnitType.THIRD_PARTY_DIR: build_config.third_party_dirs[unit.name] = unit uor_dep_graph = repocontextutil.get_uor_digraph(repo_context) uor_map = repocontextutil.get_uor_map(repo_context) build_config.external_dep = graphutil.find_external_nodes(uor_dep_graph) # BDE_CXXINCLUDES is hard coded in bde_build initial_options = { 'BDE_CXXINCLUDES': '$(BDE_CXXINCLUDE)' } # Waf already knows about the flags necessary for building shared objects, # so don't get the necessary flags from opts files. We don't have to the # operation below once we remove the the option rules for 'shr' in the # default option files. effective_ufid = copy.deepcopy(build_config.ufid) effective_ufid.flags.discard('shr') def_oe = optionsevaluator.OptionsEvaluator(build_config.uplid, effective_ufid, initial_options) def_oe.store_option_rules(default_rules, debug_keys) def_oe_copy = copy.deepcopy(def_oe) def_oe_copy.evaluate() build_config.default_flags = get_build_flags_from_opts( build_flags_parser, def_oe_copy.results, def_oe_copy.results) # These custom environment variables comes from default_internal.opts and # needs to be set when building dpkg. env_variables = ('SET_TMPDIR', 'XLC_LIBPATH') setenv_re = re.compile(r'^([^=]+)=(.*)$') for e in env_variables: if e in def_oe_copy.results: m = setenv_re.match(def_oe_copy.results[e]) if m: build_config.custom_envs[m.group(1)] = m.group(2) def set_unit_loc(oe, unit): oe.results['%s_LOCN' % unit.name.upper().replace('+', '_')] = unit.path def load_uor(uor): # Preserve the existing behavior of loading defs, opts and cap files as # bde_build: # # - Exported options of an UOR: read the defs files of its dependencies # follow by itself. The files of the dependencies should be read in # topological order, if the order of certain dependencies are # ambiguous, order them first by dependency levels, and then by their # name. # # - Internal options of an UOR: read the defs files in the same way, # followed by its own opts file. dep_levels = graphutil.levelize(uor_dep_graph, uor_dep_graph[uor.name]) oe = copy.deepcopy(def_oe) # We load options in levelized order instead of any topological order # to preserve the behavior with bde_build (older version of the build # tool). Note that we cannot cache intermediate results because later # option rules may change the results from the preivous rule. for level in dep_levels: for dep_name in sorted(level): if dep_name not in build_config.external_dep and \ dep_name not in build_config.third_party_dirs: dep_uor = uor_map[dep_name] oe.store_option_rules(dep_uor.cap) oe.store_option_rules(dep_uor.defs) if (build_config.uplid.os_type == 'windows' and build_config.uplid.comp_type == 'cl'): # By default, Visual Studio uses a single pdb file for all object # files compiled from a particular directory named # vc<vs_version>.pdb. We want to use a separate pdb file for each # package group and standard alone package. # # BDE_CXXFLAGS and BDE_CFLAGS are defined by default.opts, so the # code below is a bit hackish. pdb_option = ' /Fd%s\\%s.pdb' % ( os.path.relpath(uor.path, build_config.root_path), uor.name) oe.results['BDE_CXXFLAGS'] += pdb_option oe.results['BDE_CFLAGS'] += pdb_option if uor.type_ == repounits.UnitType.GROUP: uor_bc = buildconfig.PackageGroupBuildConfig() elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT: uor_bc = buildconfig.StdalonePackageBuildConfig() else: assert(False) uor_bc.name = uor.name uor_bc.path = uor.path uor_bc.doc = uor.doc uor_bc.version = uor.version uor_bc.dep = uor.dep - build_config.external_dep uor_bc.external_dep = uor.dep & build_config.external_dep # Store options from dependencies, options for exports, and internal # options separately dep_oe = copy.deepcopy(oe) dep_oe.evaluate() oe.store_option_rules(uor.cap) oe.store_option_rules(uor.defs) set_unit_loc(oe, uor) export_oe = copy.deepcopy(oe) int_oe = copy.deepcopy(oe) export_oe.evaluate() if export_oe.results.get('CAPABILITY') == 'NEVER': logutil.warn('Skipped non-supported UOR %s' % uor.name) return int_oe.store_option_rules(uor.opts) # Copy unevaluted internal options to be used by packages within # package groups. int_oe_copy = copy.deepcopy(int_oe) if debug_keys: logutil.info('--Evaluating %s' % uor.name) int_oe.evaluate(debug_keys) # Remove export flags of an uor's dependencies from its own export # flags. This implementation is not very optimal, but it's gets the # job done. dep_flags = get_build_flags_from_opts(build_flags_parser, dep_oe.results, dep_oe.results) uor_bc.flags = get_build_flags_from_opts( build_flags_parser, int_oe.results, export_oe.results, dep_flags.export_flags, dep_flags.export_libs) if uor.type_ == repounits.UnitType.GROUP: load_package_group(uor, uor_bc, int_oe_copy) elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT: load_sa_package(uor, uor_bc) else: assert(False) def load_sa_package(package, package_bc): package_bc.components = package.components package_bc.type_ = package.type_ package_bc.has_dums = package.has_dums package_bc.app_main = package.app_main build_config.stdalone_packages[package_bc.name] = package_bc def load_package_group(group, group_bc, oe): skipped_packages = set() for package_name in group.mem: is_skipped = not load_normal_package(package_name, oe) if is_skipped: skipped_packages.add(package_name) group_bc.mem = group.mem - skipped_packages build_config.package_groups[group_bc.name] = group_bc def load_normal_package(package_name, oe): package = repo_context.units[package_name] int_oe = copy.deepcopy(oe) int_oe.store_option_rules(package.opts) int_oe.store_option_rules(package.cap) set_unit_loc(int_oe, package) if debug_keys: logutil.info('--Evaluating %s' % package_name) int_oe.evaluate(debug_keys) if int_oe.results.get('CAPABILITY') == 'NEVER': logutil.warn('Skipped non-supported package %s' % package_name) return False if package.type_ == repounits.PackageType.PACKAGE_PLUS: package_bc = buildconfig.PlusPackageBuildConfig() else: package_bc = buildconfig.InnerPackageBuildConfig() package_bc.name = package.name package_bc.path = package.path package_bc.dep = package.dep package_bc.type_ = package.type_ package_bc.flags = get_build_flags_from_opts(build_flags_parser, int_oe.results) package_bc.has_dums = package.has_dums if package.type_ == repounits.PackageType.PACKAGE_PLUS: package_bc.headers = package.pt_extras.headers package_bc.cpp_sources = package.pt_extras.cpp_sources package_bc.cpp_tests = package.pt_extras.cpp_tests package_bc.c_tests = package.pt_extras.c_tests else: package_bc.components = package.components build_config.inner_packages[package_name] = package_bc return True for unit in repo_context.units.values(): if (unit.type_ in repounits.UnitTypeCategory.UOR_CAT and unit.type_ != repounits.UnitType.THIRD_PARTY_DIR): load_uor(unit) # Sometimes we want to override the default SONAME used for a shared # object. This can be done by setting a environment variable. # E.g., we can set 'BDE_BSL_SONAME' to 'robo20150101bsl' to set the # SONAME of the shared object built for the package group 'bsl'. for name in uor_map: soname = os.environ.get('BDE_%s_SONAME' % name.upper()) if soname: build_config.soname_overrides[name] = soname return build_config
def make_build_config(repo_context, build_flags_parser, uplid, ufid, default_rules, debug_keys=[]): """Create a build configuration for repository. Args: repo_context (RepoContext): Repository structure and metadata. build_flags_parser (BuildFlagsParser): Parser for build flags. uplid (Uplid): Build platform id. ufid (Ufid): Build flags id. default_rules (list of OptionRule): Option rules that is the base of all UORs. debug_keys (list of str): Print some debug information for some option keys. """ build_config = buildconfig.BuildConfig(repo_context.root_path, uplid, ufid) for unit in repo_context.units.values(): if unit.type_ == repounits.UnitType.THIRD_PARTY_DIR: build_config.third_party_dirs[unit.name] = unit uor_dep_graph = repocontextutil.get_uor_digraph(repo_context) uor_map = repocontextutil.get_uor_map(repo_context) build_config.external_dep = graphutil.find_external_nodes(uor_dep_graph) # BDE_CXXINCLUDES is hard coded in bde_build initial_options = {'BDE_CXXINCLUDES': '$(BDE_CXXINCLUDE)'} # Waf already knows about the flags necessary for building shared objects, # so don't get the necessary flags from opts files. We don't have to the # operation below once we remove the the option rules for 'shr' in the # default option files. effective_ufid = copy.deepcopy(build_config.ufid) effective_ufid.flags.discard('shr') def_oe = optionsevaluator.OptionsEvaluator(build_config.uplid, effective_ufid, initial_options) def_oe.store_option_rules(default_rules, debug_keys) def_oe_copy = copy.deepcopy(def_oe) def_oe_copy.evaluate() build_config.default_flags = get_build_flags_from_opts( build_flags_parser, def_oe_copy.results, def_oe_copy.results) # These custom environment variables comes from default_internal.opts and # needs to be set when building dpkg. env_variables = ('SET_TMPDIR', 'XLC_LIBPATH') setenv_re = re.compile(r'^([^=]+)=(.*)$') for e in env_variables: if e in def_oe_copy.results: m = setenv_re.match(def_oe_copy.results[e]) if m: build_config.custom_envs[m.group(1)] = m.group(2) def set_unit_loc(oe, unit): oe.results['%s_LOCN' % unit.name.upper().replace('+', '_')] = unit.path def load_uor(uor): # Preserve the existing behavior of loading defs, opts and cap files as # bde_build: # # - Exported options of an UOR: read the defs files of its dependencies # follow by itself. The files of the dependencies should be read in # topological order, if the order of certain dependencies are # ambiguous, order them first by dependency levels, and then by their # name. # # - Internal options of an UOR: read the defs files in the same way, # followed by its own opts file. dep_levels = graphutil.levelize(uor_dep_graph, uor_dep_graph[uor.name]) oe = copy.deepcopy(def_oe) # We load options in levelized order instead of any topological order # to preserve the behavior with bde_build (older version of the build # tool). Note that we cannot cache intermediate results because later # option rules may change the results from the preivous rule. for level in dep_levels: for dep_name in sorted(level): if dep_name not in build_config.external_dep and \ dep_name not in build_config.third_party_dirs: dep_uor = uor_map[dep_name] oe.store_option_rules(dep_uor.cap) oe.store_option_rules(dep_uor.defs) if (build_config.uplid.os_type == 'windows' and build_config.uplid.comp_type == 'cl'): # By default, Visual Studio uses a single pdb file for all object # files compiled from a particular directory named # vc<vs_version>.pdb. We want to use a separate pdb file for each # package group and standard alone package. # # BDE_CXXFLAGS and BDE_CFLAGS are defined by default.opts, so the # code below is a bit hackish. pdb_option = ' /Fd%s\\%s.pdb' % (os.path.relpath( uor.path, build_config.root_path), uor.name) oe.results['BDE_CXXFLAGS'] += pdb_option oe.results['BDE_CFLAGS'] += pdb_option if uor.type_ == repounits.UnitType.GROUP: uor_bc = buildconfig.PackageGroupBuildConfig() elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT: uor_bc = buildconfig.StdalonePackageBuildConfig() else: assert (False) uor_bc.name = uor.name uor_bc.path = uor.path uor_bc.doc = uor.doc uor_bc.version = uor.version uor_bc.dep = uor.dep - build_config.external_dep uor_bc.external_dep = uor.dep & build_config.external_dep # Store options from dependencies, options for exports, and internal # options separately dep_oe = copy.deepcopy(oe) dep_oe.evaluate() oe.store_option_rules(uor.cap) oe.store_option_rules(uor.defs) set_unit_loc(oe, uor) export_oe = copy.deepcopy(oe) int_oe = copy.deepcopy(oe) export_oe.evaluate() if export_oe.results.get('CAPABILITY') == 'NEVER': logutil.warn('Skipped non-supported UOR %s' % uor.name) return int_oe.store_option_rules(uor.opts) # Copy unevaluted internal options to be used by packages within # package groups. int_oe_copy = copy.deepcopy(int_oe) if debug_keys: logutil.info('--Evaluating %s' % uor.name) int_oe.evaluate(debug_keys) # Remove export flags of an uor's dependencies from its own export # flags. This implementation is not very optimal, but it's gets the # job done. dep_flags = get_build_flags_from_opts(build_flags_parser, dep_oe.results, dep_oe.results) uor_bc.flags = get_build_flags_from_opts(build_flags_parser, int_oe.results, export_oe.results, dep_flags.export_flags, dep_flags.export_libs) if uor.type_ == repounits.UnitType.GROUP: load_package_group(uor, uor_bc, int_oe_copy) elif uor.type_ in repounits.UnitTypeCategory.PACKAGE_STAND_ALONE_CAT: load_sa_package(uor, uor_bc) else: assert (False) def load_sa_package(package, package_bc): package_bc.components = package.components package_bc.type_ = package.type_ package_bc.has_dums = package.has_dums package_bc.app_main = package.app_main build_config.stdalone_packages[package_bc.name] = package_bc def load_package_group(group, group_bc, oe): skipped_packages = set() for package_name in group.mem: is_skipped = not load_normal_package(package_name, oe) if is_skipped: skipped_packages.add(package_name) group_bc.mem = group.mem - skipped_packages build_config.package_groups[group_bc.name] = group_bc def load_normal_package(package_name, oe): package = repo_context.units[package_name] int_oe = copy.deepcopy(oe) int_oe.store_option_rules(package.opts) int_oe.store_option_rules(package.cap) set_unit_loc(int_oe, package) if debug_keys: logutil.info('--Evaluating %s' % package_name) int_oe.evaluate(debug_keys) if int_oe.results.get('CAPABILITY') == 'NEVER': logutil.warn('Skipped non-supported package %s' % package_name) return False if package.type_ == repounits.PackageType.PACKAGE_PLUS: package_bc = buildconfig.PlusPackageBuildConfig() else: package_bc = buildconfig.InnerPackageBuildConfig() package_bc.name = package.name package_bc.path = package.path package_bc.dep = package.dep package_bc.type_ = package.type_ package_bc.flags = get_build_flags_from_opts(build_flags_parser, int_oe.results) package_bc.has_dums = package.has_dums if package.type_ == repounits.PackageType.PACKAGE_PLUS: package_bc.headers = package.pt_extras.headers package_bc.cpp_sources = package.pt_extras.cpp_sources package_bc.cpp_tests = package.pt_extras.cpp_tests package_bc.c_tests = package.pt_extras.c_tests else: package_bc.components = package.components build_config.inner_packages[package_name] = package_bc return True for unit in repo_context.units.values(): if (unit.type_ in repounits.UnitTypeCategory.UOR_CAT and unit.type_ != repounits.UnitType.THIRD_PARTY_DIR): load_uor(unit) # Sometimes we want to override the default SONAME used for a shared # object. This can be done by setting a environment variable. # E.g., we can set 'BDE_BSL_SONAME' to 'robo20150101bsl' to set the # SONAME of the shared object built for the package group 'bsl'. for name in uor_map: soname = os.environ.get('BDE_%s_SONAME' % name.upper()) if soname: build_config.soname_overrides[name] = soname return build_config