diff --git a/tools/migration/legacy_fields_migration_lib.py b/tools/migration/legacy_fields_migration_lib.py index ac0ae8d..70d24c5 100644 --- a/tools/migration/legacy_fields_migration_lib.py +++ b/tools/migration/legacy_fields_migration_lib.py @@ -29,6 +29,10 @@ ALL_LINK_ACTIONS = [ "c++-link-nodeps-dynamic-library" ] +DYNAMIC_LIBRARY_LINK_ACTIONS = [ + "c++-link-dynamic-library", "c++-link-nodeps-dynamic-library" +] + # Map converting from LinkingMode to corresponding feature name LINKING_MODE_TO_FEATURE_NAME = { "FULLY_STATIC": "fully_static_link", @@ -42,24 +46,88 @@ def migrate_legacy_fields(crosstool): """Migrates parsed crosstool (inplace) to not use legacy fields.""" crosstool.ClearField("default_toolchain") for toolchain in crosstool.toolchain: - # clear noop fields first - toolchain.ClearField("debian_extra_requires") - toolchain.ClearField("gcc_plugin_compiler_flag") - toolchain.ClearField("ar_flag") - toolchain.ClearField("ar_thin_archives_flag") - toolchain.ClearField("gcc_plugin_header_directory") - toolchain.ClearField("mao_plugin_header_directory") - toolchain.ClearField("supports_normalizing_ar") - toolchain.ClearField("supports_thin_archives") - toolchain.ClearField("supports_incremental_linker") - toolchain.ClearField("supports_dsym") - toolchain.ClearField("default_python_top") - toolchain.ClearField("default_python_version") - toolchain.ClearField("python_preload_swigdeps") - _ = [_migrate_expand_if_all_available(f) for f in toolchain.feature] _ = [_migrate_expand_if_all_available(ac) for ac in toolchain.action_config] + if (toolchain.dynamic_library_linker_flag or + _contains_dynamic_flags(toolchain)) and not _contains_feature( + toolchain, "supports_dynamic_linker"): + feature = toolchain.feature.add() + feature.name = "supports_dynamic_linker" + feature.enabled = True + + if toolchain.supports_start_end_lib and not _contains_feature( + toolchain, "supports_start_end_lib"): + feature = toolchain.feature.add() + feature.name = "supports_start_end_lib" + feature.enabled = True + + if toolchain.supports_interface_shared_objects and not _contains_feature( + toolchain, "supports_interface_shared_libraries"): + feature = toolchain.feature.add() + feature.name = "supports_interface_shared_libraries" + feature.enabled = True + + if toolchain.supports_embedded_runtimes and not _contains_feature( + toolchain, "static_link_cpp_runtimes"): + feature = toolchain.feature.add() + feature.name = "static_link_cpp_runtimes" + feature.enabled = True + + if toolchain.needsPic and not _contains_feature(toolchain, "supports_pic"): + feature = toolchain.feature.add() + feature.name = "supports_pic" + feature.enabled = True + + if toolchain.supports_fission and not _contains_feature( + toolchain, "per_object_debug_info"): + # feature { + # name: "per_object_debug_info" + # flag_set { + # action: "assemble" + # action: "preprocess-assemble" + # action: "c-compile" + # action: "c++-compile" + # action: "c++-module-codegen" + # action: "lto-backend" + # flag_group { + # expand_if_all_available: 'per_object_debug_info_file'", + # flag: "-gsplit-dwarf" + # } + # } + # } + feature = toolchain.feature.add() + feature.name = "per_object_debug_info" + flag_set = feature.flag_set.add() + flag_set.action[:] = [ + "c-compile", "c++-compile", "c++-module-codegen", "assemble", + "preprocess-assemble", "lto-backend" + ] + flag_group = flag_set.flag_group.add() + flag_group.expand_if_all_available[:] = ["per_object_debug_info_file"] + flag_group.flag[:] = ["-gsplit-dwarf"] + + if toolchain.objcopy_embed_flag and not _contains_feature( + toolchain, "objcopy_embed_flags"): + feature = toolchain.feature.add() + feature.name = "objcopy_embed_flags" + feature.enabled = True + flag_set = feature.flag_set.add() + flag_set.action[:] = ["objcopy_embed_data"] + flag_group = flag_set.flag_group.add() + flag_group.flag[:] = toolchain.objcopy_embed_flag + + if toolchain.ld_embed_flag and not _contains_feature( + toolchain, "ld_embed_flags"): + feature = toolchain.feature.add() + feature.name = "ld_embed_flags" + feature.enabled = True + flag_set = feature.flag_set.add() + flag_set.action[:] = ["ld_embed_data"] + flag_group = flag_set.flag_group.add() + flag_group.flag[:] = toolchain.ld_embed_flag + + # Create default_link_flags feature for linker_flag flag_sets = _extract_legacy_link_flag_sets_for(toolchain) if flag_sets: @@ -78,8 +146,6 @@ def migrate_legacy_fields(crosstool): feature.name = "default_compile_flags" _add_flag_sets(feature, flag_sets) - toolchain.ClearField("compilation_mode_flags") - # Unfiltered cxx flags have to have their own special feature. # "unfiltered_compile_flags" is a well-known (by Bazel) feature name that is # excluded from nocopts filtering. @@ -97,8 +163,38 @@ def migrate_legacy_fields(crosstool): feature.enabled = True _add_flag_sets( - feature, [[None, ALL_COMPILE_ACTIONS, toolchain.unfiltered_cxx_flag]]) - toolchain.ClearField("unfiltered_cxx_flag") + feature, + [[None, ALL_COMPILE_ACTIONS, toolchain.unfiltered_cxx_flag, []]]) + + # clear fields + toolchain.ClearField("debian_extra_requires") + toolchain.ClearField("gcc_plugin_compiler_flag") + toolchain.ClearField("ar_flag") + toolchain.ClearField("ar_thin_archives_flag") + toolchain.ClearField("gcc_plugin_header_directory") + toolchain.ClearField("mao_plugin_header_directory") + toolchain.ClearField("supports_normalizing_ar") + toolchain.ClearField("supports_thin_archives") + toolchain.ClearField("supports_incremental_linker") + toolchain.ClearField("supports_dsym") + toolchain.ClearField("supports_gold_linker") + toolchain.ClearField("default_python_top") + toolchain.ClearField("default_python_version") + toolchain.ClearField("python_preload_swigdeps") + toolchain.ClearField("needsPic") + toolchain.ClearField("compilation_mode_flags") + toolchain.ClearField("linking_mode_flags") + toolchain.ClearField("unfiltered_cxx_flag") + toolchain.ClearField("ld_embed_flag") + toolchain.ClearField("objcopy_embed_flag") + toolchain.ClearField("supports_start_end_lib") + toolchain.ClearField("supports_interface_shared_objects") + toolchain.ClearField("supports_fission") + toolchain.ClearField("compiler_flag") + toolchain.ClearField("cxx_flag") + toolchain.ClearField("linker_flag") + toolchain.ClearField("static_runtimes_filegroup") + toolchain.ClearField("dynamic_runtimes_filegroup") def _add_flag_sets(feature, flag_sets): @@ -107,11 +203,13 @@ def _add_flag_sets(feature, flag_sets): with_feature = flag_set[0] actions = flag_set[1] flags = flag_set[2] + expand_if_all_available = flag_set[3] flag_set = feature.flag_set.add() if with_feature is not None: flag_set.with_feature.add().feature[:] = [with_feature] flag_set.action[:] = actions flag_group = flag_set.flag_group.add() + flag_group.expand_if_all_available[:] = expand_if_all_available flag_group.flag[:] = flags return feature @@ -120,11 +218,9 @@ def _extract_legacy_compile_flag_sets_for(toolchain): """Get flag sets for default_compile_flags feature.""" result = [] if toolchain.compiler_flag: - result.append([None, ALL_COMPILE_ACTIONS, toolchain.compiler_flag]) - toolchain.ClearField("compiler_flag") + result.append([None, ALL_COMPILE_ACTIONS, toolchain.compiler_flag, []]) if toolchain.cxx_flag: - result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag]) - toolchain.ClearField("cxx_flag") + result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag, []]) # Migrate compiler_flag/cxx_flag from compilation_mode_flags for cmf in toolchain.compilation_mode_flags: @@ -139,10 +235,10 @@ def _extract_legacy_compile_flag_sets_for(toolchain): feature.name = mode if cmf.compiler_flag: - result.append([mode, ALL_COMPILE_ACTIONS, cmf.compiler_flag]) + result.append([mode, ALL_COMPILE_ACTIONS, cmf.compiler_flag, []]) if cmf.cxx_flag: - result.append([mode, ALL_CXX_COMPILE_ACTIONS, cmf.cxx_flag]) + result.append([mode, ALL_CXX_COMPILE_ACTIONS, cmf.cxx_flag, []]) return result @@ -153,8 +249,7 @@ def _extract_legacy_link_flag_sets_for(toolchain): # Migrate linker_flag if toolchain.linker_flag: - result.append([None, ALL_LINK_ACTIONS, toolchain.linker_flag]) - toolchain.ClearField("linker_flag") + result.append([None, ALL_LINK_ACTIONS, toolchain.linker_flag, []]) # Migrate linker_flags from compilation_mode_flags for cmf in toolchain.compilation_mode_flags: @@ -168,7 +263,7 @@ def _extract_legacy_link_flag_sets_for(toolchain): feature.name = mode if cmf.linker_flag: - result.append([mode, ALL_LINK_ACTIONS, cmf.linker_flag]) + result.append([mode, ALL_LINK_ACTIONS, cmf.linker_flag, []]) # Migrate linker_flags from linking_mode_flags for lmf in toolchain.linking_mode_flags: @@ -178,15 +273,23 @@ def _extract_legacy_link_flag_sets_for(toolchain): if _contains_feature(toolchain, mode): continue - # dynamic_linking_mode is also a marker feature it has a meaning - # even when empty - if lmf.linker_flag or mode == "dynamic_linking_mode": + if lmf.linker_flag: feature = toolchain.feature.add() feature.name = mode if lmf.linker_flag: - result.append([mode, ALL_LINK_ACTIONS, lmf.linker_flag]) - toolchain.ClearField("linking_mode_flags") + result.append([mode, ALL_LINK_ACTIONS, lmf.linker_flag, []]) + + if toolchain.dynamic_library_linker_flag: + result.append([ + None, DYNAMIC_LIBRARY_LINK_ACTIONS, + toolchain.dynamic_library_linker_flag, [] + ]) + + if toolchain.test_only_linker_flag: + result.append([ + None, ALL_LINK_ACTIONS, toolchain.test_only_linker_flag, ["is_cc_test"] + ]) return result @@ -215,3 +318,11 @@ def _migrate_expand_if_all_available(message): flag_set.expand_if_all_available[:]) flag_group.expand_if_all_available[:] = new_vars flag_set.ClearField("expand_if_all_available") + + +def _contains_dynamic_flags(toolchain): + for lmf in toolchain.linking_mode_flags: + mode = crosstool_config_pb2.LinkingMode.Name(lmf.mode) + if mode == "DYNAMIC": + return True + return False diff --git a/tools/migration/legacy_fields_migration_lib_test.py b/tools/migration/legacy_fields_migration_lib_test.py index c0165ce..41a467a 100644 --- a/tools/migration/legacy_fields_migration_lib_test.py +++ b/tools/migration/legacy_fields_migration_lib_test.py @@ -4,6 +4,7 @@ from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_ from tools.migration.legacy_fields_migration_lib import ALL_COMPILE_ACTIONS from tools.migration.legacy_fields_migration_lib import ALL_CXX_COMPILE_ACTIONS from tools.migration.legacy_fields_migration_lib import ALL_LINK_ACTIONS +from tools.migration.legacy_fields_migration_lib import DYNAMIC_LIBRARY_LINK_ACTIONS from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields @@ -30,7 +31,7 @@ def to_string(crosstool): class LegacyFieldsMigrationLibTest(unittest.TestCase): - def test_deletes_unused_fields(self): + def test_deletes_fields(self): crosstool = make_crosstool(""" debian_extra_requires: 'debian-1' gcc_plugin_compiler_flag: 'gcc_plugin_compiler_flag-1' @@ -45,6 +46,13 @@ class LegacyFieldsMigrationLibTest(unittest.TestCase): supports_thin_archives: false supports_incremental_linker: false supports_dsym: false + supports_gold_linker: false + needsPic: false + supports_start_end_lib: false + supports_interface_shared_objects: false + supports_fission: false + static_runtimes_filegroup: 'yolo' + dynamic_runtimes_filegroup: 'yolo' """) output = migrate_to_string(crosstool) self.assertNotIn("debian_extra_requires", output) @@ -60,6 +68,13 @@ class LegacyFieldsMigrationLibTest(unittest.TestCase): self.assertNotIn("default_python_top", output) self.assertNotIn("default_python_version", output) self.assertNotIn("python_preload_swigdeps", output) + self.assertNotIn("supports_gold_linker", output) + self.assertNotIn("needsPic", output) + self.assertNotIn("supports_start_end_lib", output) + self.assertNotIn("supports_interface_shared_objects", output) + self.assertNotIn("supports_fission", output) + self.assertNotIn("static_runtimes_filegroup", output) + self.assertNotIn("dynamic_runtimes_filegroup", output) def test_deletes_default_toolchains(self): crosstool = make_crosstool("") @@ -121,6 +136,19 @@ class LegacyFieldsMigrationLibTest(unittest.TestCase): self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag, ["linker-flag-1"]) + def test_migrate_dynamic_library_linker_flags(self): + crosstool = make_crosstool(""" + dynamic_library_linker_flag: 'linker-flag-1' + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.linker_flag), 0) + self.assertEqual(output.feature[0].name, "default_link_flags") + self.assertEqual(output.feature[0].flag_set[0].action, + DYNAMIC_LIBRARY_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag, + ["linker-flag-1"]) + def test_compilation_mode_flags(self): crosstool = make_crosstool(""" compiler_flag: "compile-flag-1" @@ -230,16 +258,78 @@ class LegacyFieldsMigrationLibTest(unittest.TestCase): self.assertNotIn("coverage-flag-3", output) self.assertNotIn("COVERAGE", output) - def test_dynamic_linking_mode_is_added_even_when_empty(self): + def test_supports_dynamic_linker_when_dynamic_library_linker_flag_is_used( + self): + crosstool = make_crosstool(""" + dynamic_library_linker_flag: "foo" + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "default_link_flags") + self.assertEqual(output.feature[1].name, "supports_dynamic_linker") + self.assertEqual(output.feature[1].enabled, True) + + def test_supports_dynamic_linker_is_added_when_DYNAMIC_present(self): crosstool = make_crosstool(""" linking_mode_flags { mode: DYNAMIC } """) - output = migrate_to_string(crosstool) - self.assertNotIn("linking_mode_flags", output) - self.assertNotIn("DYNAMIC", output) - self.assertIn("name: \"dynamic_linking_mode\"", output) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_dynamic_linker") + self.assertEqual(output.feature[0].enabled, True) + + def test_supports_dynamic_linker_is_not_added_when_present(self): + crosstool = make_crosstool(""" + feature { name: "supports_dynamic_linker" enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_dynamic_linker") + self.assertEqual(output.feature[0].enabled, False) + + def test_all_linker_flag_ordering(self): + crosstool = make_crosstool(""" + linker_flag: 'linker-flag-1' + compilation_mode_flags { + mode: OPT + linker_flag: 'cmf-flag-2' + } + linking_mode_flags { + mode: MOSTLY_STATIC + linker_flag: 'lmf-flag-3' + } + dynamic_library_linker_flag: 'dl-flag-4' + test_only_linker_flag: 'to-flag-5' + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "default_link_flags") + self.assertEqual(output.feature[0].enabled, True) + self.assertEqual(output.feature[0].flag_set[0].action[:], ALL_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:], + ["linker-flag-1"]) + self.assertEqual(output.feature[0].flag_set[1].action[:], ALL_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0], + "opt") + self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag[:], + ["cmf-flag-2"]) + self.assertEqual(output.feature[0].flag_set[2].action[:], ALL_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0], + "static_linking_mode") + self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag[:], + ["lmf-flag-3"]) + self.assertEqual(output.feature[0].flag_set[3].action[:], + DYNAMIC_LIBRARY_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[3].flag_group[0].flag[:], + ["dl-flag-4"]) + self.assertEqual(output.feature[0].flag_set[4].action[:], ALL_LINK_ACTIONS) + self.assertEqual(output.feature[0].flag_set[4].flag_group[0].flag[:], + ["to-flag-5"]) + self.assertEqual( + output.feature[0].flag_set[4].flag_group[0].expand_if_all_available[:], + ["is_cc_test"]) def test_linking_mode_features_are_not_added_when_present(self): crosstool = make_crosstool(""" @@ -360,6 +450,176 @@ class LegacyFieldsMigrationLibTest(unittest.TestCase): self.assertEqual(output.feature[1].name, "default_compile_flags") self.assertEqual(len(output.feature[1].flag_set), 0) + def test_supports_start_end_lib_migrated(self): + crosstool = make_crosstool("supports_start_end_lib: true") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_start_end_lib") + self.assertEqual(output.feature[0].enabled, True) + + def test_supports_start_end_lib_not_migrated_on_false(self): + crosstool = make_crosstool("supports_start_end_lib: false") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.feature), 0) + + def test_supports_start_end_lib_not_migrated_when_already_present(self): + crosstool = make_crosstool(""" + supports_start_end_lib: true + feature { name: "supports_start_end_lib" enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_start_end_lib") + self.assertEqual(output.feature[0].enabled, False) + + def test_supports_interface_shared_libraries_migrated(self): + crosstool = make_crosstool("supports_interface_shared_objects: true") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, + "supports_interface_shared_libraries") + self.assertEqual(output.feature[0].enabled, True) + + def test_supports_interface_shared_libraries_not_migrated_on_false(self): + crosstool = make_crosstool("supports_interface_shared_objects: false") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.feature), 0) + + def test_supports_interface_shared_libraries_not_migrated_when_present(self): + crosstool = make_crosstool(""" + supports_interface_shared_objects: true + feature { + name: "supports_interface_shared_libraries" + enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, + "supports_interface_shared_libraries") + self.assertEqual(output.feature[0].enabled, False) + + def test_supports_embedded_runtimes_migrated(self): + crosstool = make_crosstool("supports_embedded_runtimes: true") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes") + self.assertEqual(output.feature[0].enabled, True) + + def test_supports_embedded_runtimes_not_migrated_on_false(self): + crosstool = make_crosstool("supports_embedded_runtimes: false") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.feature), 0) + + def test_supports_embedded_runtimes_not_migrated_when_already_present(self): + crosstool = make_crosstool(""" + supports_embedded_runtimes: true + feature { name: "static_link_cpp_runtimes" enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes") + self.assertEqual(output.feature[0].enabled, False) + + def test_needs_pic_migrated(self): + crosstool = make_crosstool("needsPic: true") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_pic") + self.assertEqual(output.feature[0].enabled, True) + + def test_needs_pic_not_migrated_on_false(self): + crosstool = make_crosstool("needsPic: false") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.feature), 0) + + def test_needs_pic_not_migrated_when_already_present(self): + crosstool = make_crosstool(""" + needsPic: true + feature { name: "supports_pic" enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "supports_pic") + self.assertEqual(output.feature[0].enabled, False) + + def test_supports_fission_migrated(self): + crosstool = make_crosstool("supports_fission: true") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "per_object_debug_info") + self.assertEqual(output.feature[0].enabled, False) + + def test_supports_fission_not_migrated_on_false(self): + crosstool = make_crosstool("supports_fission: false") + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(len(output.feature), 0) + + def test_supports_fission_not_migrated_when_already_present(self): + crosstool = make_crosstool(""" + supports_fission: true + feature { name: "per_object_debug_info" enabled: false } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "per_object_debug_info") + self.assertEqual(output.feature[0].enabled, False) + + def test_migrating_objcopy_embed_flag(self): + crosstool = make_crosstool(""" + objcopy_embed_flag: "a" + objcopy_embed_flag: "b" + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "objcopy_embed_flags") + self.assertEqual(output.feature[0].enabled, True) + self.assertEqual(output.feature[0].flag_set[0].action[:], + ["objcopy_embed_data"]) + self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:], + ["a", "b"]) + self.assertEqual(len(output.objcopy_embed_flag), 0) + + def test_not_migrating_objcopy_embed_flag_when_feature_present(self): + crosstool = make_crosstool(""" + objcopy_embed_flag: "a" + objcopy_embed_flag: "b" + feature { name: "objcopy_embed_flags" } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "objcopy_embed_flags") + self.assertEqual(output.feature[0].enabled, False) + + def test_migrating_ld_embed_flag(self): + crosstool = make_crosstool(""" + ld_embed_flag: "a" + ld_embed_flag: "b" + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "ld_embed_flags") + self.assertEqual(output.feature[0].enabled, True) + self.assertEqual(output.feature[0].flag_set[0].action[:], ["ld_embed_data"]) + self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:], + ["a", "b"]) + self.assertEqual(len(output.ld_embed_flag), 0) + + def test_not_migrating_objcopy_embed_flag_when_feature_present(self): + crosstool = make_crosstool(""" + objcopy_embed_flag: "a" + objcopy_embed_flag: "b" + feature { name: "objcopy_embed_flags" } + """) + migrate_legacy_fields(crosstool) + output = crosstool.toolchain[0] + self.assertEqual(output.feature[0].name, "objcopy_embed_flags") + self.assertEqual(output.feature[0].enabled, False) + def test_migrate_expand_if_all_available_from_flag_sets(self): crosstool = make_crosstool(""" action_config { diff --git a/tools/migration/legacy_fields_migrator.py b/tools/migration/legacy_fields_migrator.py index 10ebacd..806d09d 100644 --- a/tools/migration/legacy_fields_migrator.py +++ b/tools/migration/legacy_fields_migrator.py @@ -19,6 +19,7 @@ from absl import flags from google.protobuf import text_format from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2 from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields +import os flags.DEFINE_string("input", None, "Input CROSSTOOL file to be migrated") flags.DEFINE_string("output", None, @@ -36,18 +37,29 @@ def main(unused_argv): if not output_filename: raise app.UsageError("ERROR output unspecified") - f = open(input_filename, "r") + f = open(to_absolute_path(input_filename), "r") input_text = f.read() text_format.Merge(input_text, crosstool) f.close() output_text = migrate_legacy_fields(crosstool) - f = open(output_filename, "w") + f = open(to_absolute_path(output_filename), "w") output_text = text_format.MessageToString(crosstool) f.write(output_text) f.close() +def to_absolute_path(path): + path = os.path.expanduser(path) + if os.path.isabs(path): + return path + else: + if os.environ["BUILD_WORKING_DIRECTORY"]: + return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path) + else: + return path + + if __name__ == "__main__": app.run(main)