diff --git a/go/private/actions/archive.bzl b/go/private/actions/archive.bzl index f1415d3f6b..88d2bbd287 100644 --- a/go/private/actions/archive.bzl +++ b/go/private/actions/archive.bzl @@ -71,130 +71,63 @@ def emit_archive(go, source = None): fail("Archive mode does not match {} is {} expected {}".format(a.data.label, mode_string(a.source.mode), mode_string(go.mode))) importmap = "main" if source.library.is_main else source.library.importmap - - if not source.cgo_archives: - # TODO(jayconrod): We still need to support the legacy cgo path when - # Objective C sources are present, since the Objective C toolchain - # isn't exposed to Starlark. The legacy path runs cgo as a separate - # action, then builds generated code with cc_library / objc_library. - # A go_library compiles generated Go code and packs the other - # objects from cgo_archives. "cgo_archives" is not supported on - # the new path because we do all that in one action. + importpath, _ = effective_importpath_pkgpath(source.library) + if source.cgo and not go.mode.pure: # TODO(jayconrod): do we need to do full Bourne tokenization here? cppopts = [f for fs in source.cppopts for f in fs.split(" ")] copts = [f for fs in source.copts for f in fs.split(" ")] cxxopts = [f for fs in source.cxxopts for f in fs.split(" ")] clinkopts = [f for fs in source.clinkopts for f in fs.split(" ")] - - importpath, _ = effective_importpath_pkgpath(source.library) - if source.cgo and not go.mode.pure: - cgo = cgo_configure( - go, - srcs = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, - cdeps = source.cdeps, - cppopts = cppopts, - copts = copts, - cxxopts = cxxopts, - clinkopts = clinkopts, - ) - if go.mode.link in (LINKMODE_C_SHARED, LINKMODE_C_ARCHIVE): - out_cgo_export_h = go.declare_file(go, path = "_cgo_install.h") - cgo_deps = cgo.deps - runfiles = runfiles.merge(cgo.runfiles) - emit_compilepkg( - go, - sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, - cover = source.cover, - importpath = importpath, - importmap = importmap, - archives = direct, - out_lib = out_lib, - out_export = out_export, - out_cgo_export_h = out_cgo_export_h, - gc_goopts = source.gc_goopts, - cgo = True, - cgo_inputs = cgo.inputs, - cppopts = cgo.cppopts, - copts = cgo.copts, - cxxopts = cgo.cxxopts, - objcopts = cgo.objcopts, - objcxxopts = cgo.objcxxopts, - clinkopts = cgo.clinkopts, - cgo_archives = source.cgo_archives, - testfilter = testfilter, - ) - else: - cgo_deps = depset() - emit_compilepkg( - go, - sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, - cover = source.cover, - importpath = importpath, - importmap = importmap, - archives = direct, - out_lib = out_lib, - out_export = out_export, - gc_goopts = source.gc_goopts, - cgo = False, - cgo_archives = source.cgo_archives, - testfilter = testfilter, - ) + cgo = cgo_configure( + go, + srcs = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, + cdeps = source.cdeps, + cppopts = cppopts, + copts = copts, + cxxopts = cxxopts, + clinkopts = clinkopts, + ) + if go.mode.link in (LINKMODE_C_SHARED, LINKMODE_C_ARCHIVE): + out_cgo_export_h = go.declare_file(go, path = "_cgo_install.h") + cgo_deps = cgo.deps + runfiles = runfiles.merge(cgo.runfiles) + emit_compilepkg( + go, + sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, + cover = source.cover, + importpath = importpath, + importmap = importmap, + archives = direct, + out_lib = out_lib, + out_export = out_export, + out_cgo_export_h = out_cgo_export_h, + gc_goopts = source.gc_goopts, + cgo = True, + cgo_inputs = cgo.inputs, + cppopts = cgo.cppopts, + copts = cgo.copts, + cxxopts = cgo.cxxopts, + objcopts = cgo.objcopts, + objcxxopts = cgo.objcxxopts, + clinkopts = cgo.clinkopts, + testfilter = testfilter, + ) else: - cgo_deps = source.cgo_deps - - if bool(go.cover and go.coverdata and source.cover): - source = go.cover(go, source) - direct.append(go.coverdata) - - asmhdr = None - if split.asm: - asmhdr = go.declare_file(go, "go_asm.h") - - if len(split.asm) == 0 and not source.cgo_archives: - go.compile( - go, - sources = split.go, - importpath = importmap, - archives = direct, - out_lib = out_lib, - out_export = out_export, - gc_goopts = source.gc_goopts, - testfilter = testfilter, - ) - else: - # Assembly files must be passed to the compiler as sources. We need - # to run the assembler to produce a symabis file that gets passed to - # the compiler. The compiler builder does all this so it doesn't - # need to be a separate action (but individual .o files are still - # produced with separate actions). - partial_lib = go.declare_file(go, path = lib_name + "~partial", ext = ".a") - go.compile( - go, - sources = split.go + split.asm + split.headers, - importpath = importmap, - archives = direct, - out_lib = partial_lib, - out_export = out_export, - gc_goopts = source.gc_goopts, - testfilter = testfilter, - asmhdr = asmhdr, - ) - - # include other .s as inputs, since they may be #included. - # This may result in multiple copies of symbols defined in included - # files, but go build allows it, so we do, too. - asm_headers = split.headers + split.asm + [asmhdr] - extra_objects = [] - for src in split.asm: - extra_objects.append(go.asm(go, source = src, hdrs = asm_headers)) - go.pack( - go, - in_lib = partial_lib, - out_lib = out_lib, - objects = extra_objects, - archives = source.cgo_archives, - ) + cgo_deps = depset() + emit_compilepkg( + go, + sources = split.go + split.c + split.asm + split.cxx + split.objc + split.headers, + cover = source.cover, + importpath = importpath, + importmap = importmap, + archives = direct, + out_lib = out_lib, + out_export = out_export, + gc_goopts = source.gc_goopts, + cgo = False, + testfilter = testfilter, + ) data = GoArchiveData( name = source.library.name, diff --git a/go/private/actions/compilepkg.bzl b/go/private/actions/compilepkg.bzl index d012497b1f..f21deb0cd8 100644 --- a/go/private/actions/compilepkg.bzl +++ b/go/private/actions/compilepkg.bzl @@ -46,7 +46,6 @@ def emit_compilepkg( objcopts = [], objcxxopts = [], clinkopts = [], - cgo_archives = [], out_lib = None, out_export = None, out_cgo_export_h = None, @@ -59,7 +58,6 @@ def emit_compilepkg( inputs = (sources + [go.package_list] + [archive.data.file for archive in archives] + - cgo_archives + go.sdk.tools + go.sdk.headers + go.stdlib.libs) outputs = [out_lib] env = go.env diff --git a/go/private/compat/v23.bzl b/go/private/compat/v23.bzl index 37098880d2..e73b5af2ab 100644 --- a/go/private/compat/v23.bzl +++ b/go/private/compat/v23.bzl @@ -55,31 +55,6 @@ def cc_libs(target): libs.append(library_to_link.dynamic_library) return libs -def cc_compile_flags(target): - # Copied from get_compile_flags in migration instructions from - # bazelbuild/bazel#7036. - options = [] - compilation_context = target[CcInfo].compilation_context - for define in compilation_context.defines.to_list(): - options.append("-D{}".format(define)) - - for system_include in compilation_context.system_includes.to_list(): - if len(system_include) == 0: - system_include = "." - options.append("-isystem {}".format(system_include)) - - for include in compilation_context.includes.to_list(): - if len(include) == 0: - include = "." - options.append("-I {}".format(include)) - - for quote_include in compilation_context.quote_includes.to_list(): - if len(quote_include) == 0: - quote_include = "." - options.append("-iquote {}".format(quote_include)) - - return options - def cc_toolchain_all_files(ctx): return ctx.files._cc_toolchain @@ -96,27 +71,9 @@ def get_proto(target): def proto_check_deps_sources(target): return target[ProtoInfo].check_deps_sources -def proto_direct_descriptor_set(target): - return target[ProtoInfo].direct_descriptor_set - -def proto_direct_sources(target): - return target[ProtoInfo].direct_sources - def proto_source_root(target): return target[ProtoInfo].proto_source_root -def proto_transitive_descriptor_sets(target): - return target[ProtoInfo].transitive_descriptor_sets - -def proto_transitive_imports(target): - return target[ProtoInfo].transitive_imports - -def proto_transitive_proto_path(target): - return target[ProtoInfo].transitive_proto_path - -def proto_transitive_sources(target): - return target[ProtoInfo].transitive_sources - # Compatibility for --incompatible_disallow_struct_provider def providers_with_coverage(ctx, source_attributes, dependency_attributes, extensions, providers): return providers + [coverage_common.instrumented_files_info( diff --git a/go/private/compat/v25.bzl b/go/private/compat/v25.bzl index ff15772282..1c632c5acb 100644 --- a/go/private/compat/v25.bzl +++ b/go/private/compat/v25.bzl @@ -59,31 +59,6 @@ def cc_libs(target): libs.append(library_to_link.dynamic_library) return libs -def cc_compile_flags(target): - # Copied from get_compile_flags in migration instructions from - # bazelbuild/bazel#7036. - options = [] - compilation_context = target[CcInfo].compilation_context - for define in compilation_context.defines.to_list(): - options.append("-D{}".format(define)) - - for system_include in compilation_context.system_includes.to_list(): - if len(system_include) == 0: - system_include = "." - options.append("-isystem {}".format(system_include)) - - for include in compilation_context.includes.to_list(): - if len(include) == 0: - include = "." - options.append("-I {}".format(include)) - - for quote_include in compilation_context.quote_includes.to_list(): - if len(quote_include) == 0: - quote_include = "." - options.append("-iquote {}".format(quote_include)) - - return options - def cc_toolchain_all_files(ctx): return find_cpp_toolchain(ctx).all_files.to_list() @@ -100,27 +75,9 @@ def get_proto(target): def proto_check_deps_sources(target): return target[ProtoInfo].check_deps_sources -def proto_direct_descriptor_set(target): - return target[ProtoInfo].direct_descriptor_set - -def proto_direct_sources(target): - return target[ProtoInfo].direct_sources - def proto_source_root(target): return target[ProtoInfo].proto_source_root -def proto_transitive_descriptor_sets(target): - return target[ProtoInfo].transitive_descriptor_sets - -def proto_transitive_imports(target): - return target[ProtoInfo].transitive_imports - -def proto_transitive_proto_path(target): - return target[ProtoInfo].transitive_proto_path - -def proto_transitive_sources(target): - return target[ProtoInfo].transitive_sources - # Compatibility for --incompatible_disallow_struct_provider def providers_with_coverage(ctx, source_attributes, dependency_attributes, extensions, providers): return providers + [coverage_common.instrumented_files_info( diff --git a/go/private/context.bzl b/go/private/context.bzl index 53d9a7f8a9..79cc748949 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -188,10 +188,6 @@ def _merge_embed(source, embed): source["clinkopts"] = source["clinkopts"] or s.clinkopts source["cgo_deps"] = source["cgo_deps"] + s.cgo_deps source["cgo_exports"] = source["cgo_exports"] + s.cgo_exports - if s.cgo_archives: - if source["cgo_archives"]: - fail("multiple libraries with cgo_archives embedded") - source["cgo_archives"] = s.cgo_archives def _dedup_deps(deps): """Returns a list of targets without duplicate import paths. @@ -237,7 +233,6 @@ def _library_to_source(go, attr, library, coverage_instrumented): "copts": getattr(attr, "copts", []), "cxxopts": getattr(attr, "cxxopts", []), "clinkopts": getattr(attr, "clinkopts", []), - "cgo_archives": [], "cgo_deps": [], "cgo_exports": [], } diff --git a/go/private/rules/cgo.bzl b/go/private/rules/cgo.bzl index 8247e19336..8981b77986 100644 --- a/go/private/rules/cgo.bzl +++ b/go/private/rules/cgo.bzl @@ -12,55 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -load( - "@bazel_skylib//lib:old_sets.bzl", - "sets", -) -load( - "@io_bazel_rules_go//go/private:context.bzl", - "go_context", -) load( "@io_bazel_rules_go//go/private:common.bzl", - "as_iterable", - "as_list", - "as_set", "has_simple_shared_lib_extension", "has_versioned_shared_lib_extension", - "join_srcs", - "pkg_dir", - "split_srcs", -) -load( - "@io_bazel_rules_go//go/private:providers.bzl", - "GoLibrary", -) -load( - "@io_bazel_rules_go//go/private:rules/rule.bzl", - "go_rule", ) load( "@io_bazel_rules_go//go/private:mode.bzl", "LINKMODE_C_ARCHIVE", "LINKMODE_C_SHARED", "LINKMODE_NORMAL", - "LINKMODE_PIE", "extldflags_from_cc_toolchain", - "mode_string", - "new_mode", -) -load( - "@io_bazel_rules_go//go/platform:list.bzl", - "GOARCH", - "GOOS", - "GOOS_GOARCH", - "MSAN_GOOS_GOARCH", - "RACE_GOOS_GOARCH", ) load( "@io_bazel_rules_go_compat//:compat.bzl", - "CC_PROVIDER_NAME", - "cc_compile_flags", "cc_defines", "cc_includes", "cc_libs", @@ -200,652 +165,18 @@ def cgo_configure(go, srcs, cdeps, cppopts, copts, cxxopts, clinkopts): clinkopts = clinkopts, ) -_CgoCodegen = provider() -_CgoInfo = provider() - -# Maximum number of characters in stem of base name for mangled cgo files. -# Some file systems have fairly short limits (eCryptFS has a limit of 143), -# and this should be kept below those to accomodate number suffixes and -# extensions. -MAX_STEM_LENGTH = 130 - -def _mangle(src, stems): - """_mangle returns a file stem and extension for a source file that will - be passed to cgo. The stem will be unique among other sources in the same - library. It will not contain any separators, so cgo's name mangling algorithm - will be a no-op.""" - stem, _, ext = src.basename.rpartition(".") - if len(stem) > MAX_STEM_LENGTH: - stem = stem[:MAX_STEM_LENGTH] - if stem in stems: - for i in range(100): - next_stem = "{}_{}".format(stem, i) - if next_stem not in stems: - break - if next_stem in stems: - fail("could not find unique mangled name for {}".format(src.path)) - stem = next_stem - stems[stem] = True - return stem, ext - _DEFAULT_PLATFORM_COPTS = select({ "@io_bazel_rules_go//go/platform:darwin": [], "@io_bazel_rules_go//go/platform:windows_amd64": ["-mthreads"], "//conditions:default": ["-pthread"], }) -_DEFAULT_PLATFORM_LINKOPTS = select({ - "@io_bazel_rules_go//go/platform:android": ["-llog", "-ldl"], - "@io_bazel_rules_go//go/platform:darwin": [], - "@io_bazel_rules_go//go/platform:windows_amd64": ["-mthreads"], - "//conditions:default": ["-pthread"], -}) - -def _c_filter_options(options, blacklist): - return [ - opt - for opt in options - if not any([opt.startswith(prefix) for prefix in blacklist]) - ] - -def _select_archives(libs): - """Selects static archives to pack from a list of cc_library targets. - Returns at most one file per library. - - Each cc_library may produce several files which are logically the same - static library. We prefer files with the extensions .pic.lo, .lo, or .a - in that order. If a cc_library is empty, it may not produce any files, - so _select_archives may return fewer archives than libs. - """ - - # list of file extensions in descending order or preference. - exts = [".pic.lo", ".lo", ".a"] - outs = [] - for lib in libs: - out = None - for ext in exts: - for f in as_iterable(lib.files): - if f.basename.endswith(ext): - out = f - break - if out: - break - if out: - outs.append(out) - return outs - def _include_unique(opts, flag, include, seen): if include in seen: return seen[include] = True opts.extend([flag, include]) -def _encode_cgo_mode(goos, goarch, race, msan): - return "_".join((goos, goarch, str(race), str(msan))) - -def _cgo_codegen_impl(ctx): - go = go_context(ctx) - if not go.cgo_tools: - fail("Go toolchain does not support cgo") - linkopts = extldflags_from_cc_toolchain(go) + ctx.attr.linkopts - cppopts = list(ctx.attr.cppopts) - copts = go.cgo_tools.c_compile_options + ctx.attr.copts - deps = depset([], order = "topological") - cgo_export_h = go.declare_file(go, path = "_cgo_export.h") - cgo_export_c = go.declare_file(go, path = "_cgo_export.c") - cgo_main = go.declare_file(go, path = "_cgo_main.c") - cgo_types = go.declare_file(go, path = "_cgo_gotypes.go") - out_dir = cgo_main.dirname - - builder_args = go.builder_args(go, "cgo") # interpreted by builder - tool_args = go.tool_args(go) # interpreted by cgo - cc_args = go.tool_args(go) # interpreted by C compiler - - c_outs = [cgo_export_h, cgo_export_c] - cxx_outs = [cgo_export_h] - objc_outs = [cgo_export_h] - transformed_go_outs = [] - transformed_go_map = {} - gen_go_outs = [cgo_types] - - seen_includes = {} - seen_quote_includes = {} - seen_system_includes = {} - - source = split_srcs(ctx.files.srcs) - for hdr in source.headers: - _include_unique(cppopts, "-iquote", hdr.dirname, seen_quote_includes) - stems = {} - for src in source.go: - mangled_stem, src_ext = _mangle(src, stems) - gen_go_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext) - gen_c_file = go.declare_file(go, path = mangled_stem + ".cgo2.c") - transformed_go_outs.append(gen_go_file) - transformed_go_map[gen_go_file] = src - c_outs.append(gen_c_file) - builder_args.add("-src", gen_go_file.path + "=" + src.path) - for src in source.asm: - mangled_stem, src_ext = _mangle(src, stems) - gen_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext) - transformed_go_outs.append(gen_file) - builder_args.add("-src", gen_file.path + "=" + src.path) - for src in source.c: - mangled_stem, src_ext = _mangle(src, stems) - gen_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext) - c_outs.append(gen_file) - builder_args.add("-src", gen_file.path + "=" + src.path) - for src in source.cxx: - mangled_stem, src_ext = _mangle(src, stems) - gen_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext) - cxx_outs.append(gen_file) - builder_args.add("-src", gen_file.path + "=" + src.path) - for src in source.objc: - mangled_stem, src_ext = _mangle(src, stems) - gen_file = go.declare_file(go, path = mangled_stem + ".cgo1." + src_ext) - objc_outs.append(gen_file) - builder_args.add("-src", gen_file.path + "=" + src.path) - - # Filter out -lstdc++ in CGO_LDFLAGS if we don't have any C++ code. This - # also gets filtered out in link.bzl. - have_cc = len(source.cxx) + len(source.objc) + len(ctx.attr.deps) > 0 - if not have_cc: - linkopts = [o for o in linkopts if o not in ("-lstdc++", "-lc++")] - - tool_args.add("-objdir", out_dir) - - inputs = sets.union(ctx.files.srcs, go.crosstool, go.sdk.tools) - deps = depset() - runfiles = ctx.runfiles(collect_data = True) - for d in ctx.attr.deps: - runfiles = runfiles.merge(d.data_runfiles) - if has_cc(d): - inputs = sets.union(inputs, cc_transitive_headers(d)) - deps = sets.union(deps, cc_libs(d)) - cppopts.extend(["-D" + define for define in cc_defines(d)]) - for inc in cc_includes(d): - _include_unique(cppopts, "-I", inc, seen_includes) - for inc in cc_quote_includes(d): - _include_unique(cppopts, "-iquote", inc, seen_quote_includes) - for inc in cc_system_includes(d): - _include_unique(cppopts, "-isystem", inc, seen_system_includes) - for lib in cc_libs(d): - # If both static and dynamic variants are available, Bazel will only give - # us the static variant. We'll get one file for each transitive dependency, - # so the same file may appear more than once. - if (lib.basename.startswith("lib") and - has_simple_shared_lib_extension(lib.basename)): - # If the loader would be able to find the library using rpaths, - # use -L and -l instead of hard coding the path to the library in - # the binary. This gives users more flexibility. The linker will add - # rpaths later. We can't add them here because they are relative to - # the binary location, and we don't know where that is. - libname = lib.basename[len("lib"):lib.basename.rindex(".")] - linkopts.extend(["-L", lib.dirname, "-l", libname]) - elif (lib.basename.startswith("lib") and - has_versioned_shared_lib_extension(lib.basename)): - # With a versioned shared library, we must use the full filename, - # otherwise the library will not be found by the linker. - libname = ":%s" % lib.basename - linkopts.extend(["-L", lib.dirname, "-l", libname]) - else: - linkopts.append(lib.path) - linkopts.extend(cc_link_flags(d)) - elif hasattr(d, "objc"): - cppopts.extend(["-D" + define for define in d.objc.define.to_list()]) - for inc in d.objc.include.to_list(): - _include_unique(cppopts, "-I", inc, seen_includes) - for inc in d.objc.iquote.to_list(): - _include_unique(cppopts, "-iquote", inc, seen_quote_includes) - for inc in d.objc.include_system.to_list(): - _include_unique(cppopts, "-isystem", inc, seen_system_includes) - - # TODO(jayconrod): do we need to link against dynamic libraries or - # frameworks? We link against *_fully_linked.a, so maybe not? - - else: - fail("unknown library has neither cc nor objc providers: %s" % d.label) - - # cgo writes CGO_LDFLAGS to _cgo_import.go in the form of pragmas which get - # compiled into .a files. The linker finds these and passes them to the - # external linker. - # TODO(jayconrod): do we need to set this here, or only in _cgo_import? - # go build does it here. - env = go.env - env["CC"] = go.cgo_tools.c_compiler_path - env["CGO_LDFLAGS"] = " ".join(linkopts) - - cc_args.add_all(cppopts) - cc_args.add_all(copts) - - ctx.actions.run( - inputs = inputs, - outputs = c_outs + cxx_outs + objc_outs + gen_go_outs + transformed_go_outs + [cgo_main], - mnemonic = "CGoCodeGen", - progress_message = "CGoCodeGen %s" % ctx.label, - executable = go.toolchain._builder, - arguments = [builder_args, "--", tool_args, "--", cc_args], - env = env, - ) - - return [ - _CgoCodegen( - transformed_go = transformed_go_outs, - transformed_go_map = transformed_go_map, - gen_go = gen_go_outs, - deps = as_list(deps), - exports = [cgo_export_h], - ), - DefaultInfo( - files = depset(), - runfiles = runfiles, - ), - OutputGroupInfo( - c_files = sets.union(c_outs, source.headers), - cxx_files = sets.union(cxx_outs, source.headers), - objc_files = sets.union(objc_outs, source.headers), - go_files = sets.union(transformed_go_outs, gen_go_outs), - main_c = as_set([cgo_main]), - ), - ] - -_cgo_codegen = go_rule( - _cgo_codegen_impl, - attrs = { - "srcs": attr.label_list(allow_files = True), - "deps": attr.label_list(allow_files = False), - "copts": attr.string_list(), - "cxxopts": attr.string_list(), - "cppopts": attr.string_list(), - "linkopts": attr.string_list(), - # Attributes below are read into go.mode. They determine build tags - # which are used to filter sources. We need to set these explicitly, - # since the aspect won't reach this rule. - "goos": attr.string( - mandatory = True, - values = GOOS.keys(), - ), - "goarch": attr.string( - mandatory = True, - values = GOARCH.keys(), - ), - "race": attr.string( - values = ["on", "off"], - default = "off", - ), - "msan": attr.string( - values = ["on", "off"], - default = "off", - ), - "pure": attr.string(default = "off"), # never explicitly set - }, -) - -def _cgo_import_impl(ctx): - go = go_context(ctx) - out = go.declare_file(go, path = "_cgo_import.go") - args = go.builder_args(go, "cgo") - args.add("-import") - args.add("-src", ctx.files.sample_go_srcs[0]) - args.add("--") # stop builder from processing args - args.add("-dynout", out) - args.add("-dynimport", ctx.file.cgo_o) - ctx.actions.run( - inputs = [ - ctx.file.cgo_o, - ctx.files.sample_go_srcs[0], - ] + go.sdk.tools, - outputs = [out], - executable = go.toolchain._builder, - arguments = [args], - mnemonic = "CGoImportGen", - ) - return [DefaultInfo(files = depset([out]))] - -_cgo_import = go_rule( - _cgo_import_impl, - attrs = { - "cgo_o": attr.label( - allow_single_file = True, - ), - "sample_go_srcs": attr.label_list(allow_files = True), - }, -) -"""Generates symbol-import directives for cgo - -Args: - cgo_o: The loadable object to extract dynamic symbols from. - sample_go_src: A go source which is compiled together with the generated file. - The generated file will have the same Go package name as this file. - out: Destination of the generated codes. -""" - -def _cgo_resolve_source(go, attr, source, merge): - library = source["library"] - cgo_mode = _encode_cgo_mode(go.mode.goos, go.mode.goarch, go.mode.race, go.mode.msan) - cgo_info = None - for target, target_cgo_mode in library.cgo_mode_info.items(): - if cgo_mode == target_cgo_mode: - cgo_info = target[_CgoInfo] - break - if not cgo_info: - fail("{}: no matching cgo rules for mode {}".format(library.label, mode_string(go.mode))) - - source["orig_srcs"] = cgo_info.orig_srcs - source["orig_src_map"] = cgo_info.transformed_go_map - source["runfiles"] = cgo_info.runfiles - source["cover"] = [] - if source["mode"].pure: - split = split_srcs(cgo_info.orig_srcs) - source["srcs"] = split.go + split.asm - if go.coverage_instrumented: - source["cover"] = source["srcs"] - else: - source["srcs"] = cgo_info.transformed_go_srcs + cgo_info.gen_go_srcs - if go.coverage_instrumented: - source["cover"] = cgo_info.transformed_go_srcs - source["cgo_deps"] = cgo_info.cgo_deps - source["cgo_exports"] = cgo_info.cgo_exports - source["cgo_archives"] = cgo_info.cgo_archives - -def _cgo_collect_info_impl(ctx): - go = go_context(ctx) - codegen = ctx.attr.codegen[_CgoCodegen] - import_files = as_list(ctx.files.cgo_import) - runfiles = ctx.runfiles(collect_data = True) - runfiles = runfiles.merge(ctx.attr.codegen.data_runfiles) - return [ - _CgoInfo( - orig_srcs = ctx.files.srcs, - transformed_go_srcs = codegen.transformed_go, - transformed_go_map = codegen.transformed_go_map, - gen_go_srcs = codegen.gen_go + import_files, - cgo_deps = codegen.deps, - cgo_exports = codegen.exports, - cgo_archives = _select_archives(ctx.attr.libs), - runfiles = runfiles, - ), - DefaultInfo(files = depset(), runfiles = runfiles), - ] - -_cgo_collect_info = go_rule( - _cgo_collect_info_impl, - attrs = { - "srcs": attr.label_list( - mandatory = True, - allow_files = True, - ), - "codegen": attr.label( - mandatory = True, - providers = [_CgoCodegen], - ), - "libs": attr.label_list( - mandatory = True, - allow_files = True, - providers = [CC_PROVIDER_NAME], - ), - "cgo_import": attr.label(mandatory = True), - }, -) -"""No-op rule that collects mode-specific information from _cgo_codegen and -cc_library info into a _CgoInfo provider for easy consumption.""" - -def _cgo_select_embed_impl(ctx): - go = go_context(ctx) - library = go.new_library( - go, - resolver = _cgo_resolve_source, - cgo_mode_info = ctx.attr.info, - ) - source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented()) - return [ - library, - source, - DefaultInfo(files = depset(), runfiles = source.runfiles), - ] - -_cgo_select_embed = go_rule( - _cgo_select_embed_impl, - attrs = { - "info": attr.label_keyed_string_dict( - mandatory = True, - providers = [_CgoInfo], - ), - }, -) -"""No-op rule that collects information about cgo rules in all supported -modes, then builds GoLibrary and GoSource providers for the current mode.""" - -def setup_cgo_library(name, srcs, cdeps, copts, cxxopts, cppopts, clinkopts, objc, objcopts, linkmode, **common_attrs): - """Declares a graph of rules needed to build the cgo part of a go_library. - The graph is collected into a single rule which may be embedded in a - regular go_library. - - We build C/C++/ObjC code using cc_library / objc_library rules. We'd prefer - to create our own compile / link actions within a single rule, but we'd - almost certainly break something. - """ - - # Add some implicit flags for the current rule. - repo_name = native.repository_name() - base_dir = pkg_dir( - "external/" + repo_name[1:] if len(repo_name) > 1 else "", - native.package_name(), - ) - copts = copts - cxxopts = cxxopts - cppopts = cppopts + ["-I", base_dir] - - if objc: - clinkopts = clinkopts + [ - "-fobjc-link-runtime", - ] - for framework in objcopts.get("sdk_frameworks", []): - clinkopts.append("-framework %s" % framework) - if linkmode == LINKMODE_PIE and "-pie" not in clinkopts: - clinkopts = clinkopts + ["-pie"] - - # Declare cgo rules for each platform and race / msan configuration. We - # normally propagate mode attributes through an aspect, but we can't create - # alternate cc_library rules with an aspect. - cgo_mode_info = {} - for goos, goarch in GOOS_GOARCH: - cgo_info_name = setup_cgo_library_for_mode(name, srcs, cdeps, copts, cxxopts, cppopts, clinkopts, objc, objcopts, goos, goarch, race = False, msan = False, **common_attrs) - cgo_mode_info[cgo_info_name] = _encode_cgo_mode(goos, goarch, race = False, msan = False) - for goos, goarch in RACE_GOOS_GOARCH: - cgo_info_name = setup_cgo_library_for_mode(name, srcs, cdeps, copts, cxxopts, cppopts, clinkopts, objc, objcopts, goos, goarch, race = True, msan = False, **common_attrs) - cgo_mode_info[cgo_info_name] = _encode_cgo_mode(goos, goarch, race = True, msan = False) - for goos, goarch in MSAN_GOOS_GOARCH: - cgo_info_name = setup_cgo_library_for_mode(name, srcs, cdeps, copts, cxxopts, cppopts, clinkopts, objc, objcopts, goos, goarch, race = False, msan = True, **common_attrs) - cgo_mode_info[cgo_info_name] = _encode_cgo_mode(goos, goarch, race = False, msan = True) - - # Collect everything in a single embedable, aspect-friendly library. - cgo_embed_name = name + "__cgo_embed" - _cgo_select_embed( - name = cgo_embed_name, - info = cgo_mode_info, - visibility = ["//visibility:private"], - **common_attrs - ) - return cgo_embed_name - -def setup_cgo_library_for_mode(name, srcs, cdeps, copts, cxxopts, cppopts, clinkopts, objc, objcopts, goos, goarch, race, msan, **common_attrs): - mode = new_mode( - goos = goos, - goarch = goarch, - race = race, - msan = msan, - ) - prefix = "{}%{}%".format(name, mode_string(mode)) - cgo_codegen_name = prefix + "cgo_codegen" - _cgo_codegen( - name = cgo_codegen_name, - srcs = srcs, - deps = cdeps, - copts = copts, - cxxopts = cxxopts, - cppopts = cppopts, - linkopts = clinkopts, - goos = goos, - goarch = goarch, - race = "on" if race else "off", - msan = "on" if msan else "off", - visibility = ["//visibility:private"], - **common_attrs - ) - - select_go_files = prefix + "select_go_files" - native.filegroup( - name = select_go_files, - srcs = [cgo_codegen_name], - output_group = "go_files", - visibility = ["//visibility:private"], - **common_attrs - ) - - select_c_files = prefix + "select_c_files" - native.filegroup( - name = select_c_files, - srcs = [cgo_codegen_name], - output_group = "c_files", - visibility = ["//visibility:private"], - **common_attrs - ) - - select_cxx_files = prefix + "select_cxx_files" - native.filegroup( - name = select_cxx_files, - srcs = [cgo_codegen_name], - output_group = "cxx_files", - visibility = ["//visibility:private"], - **common_attrs - ) - - select_objc_files = prefix + "select_objc_files" - native.filegroup( - name = select_objc_files, - srcs = [cgo_codegen_name], - output_group = "objc_files", - visibility = ["//visibility:private"], - **common_attrs - ) - - select_main_c = prefix + "select_main_c" - native.filegroup( - name = select_main_c, - srcs = [cgo_codegen_name], - output_group = "main_c", - visibility = ["//visibility:private"], - **common_attrs - ) - - # Compile C sources and generated files into a library. This will be linked - # into binaries that depend on this cgo_library. It will also be used - # in _cgo_.o. - cgo_c_lib_name = prefix + "cgo_c_lib" - native.cc_library( - name = cgo_c_lib_name, - srcs = [select_c_files], - deps = cdeps, - copts = copts + cppopts + _DEFAULT_PLATFORM_COPTS + [ - # The generated thunks often contain unused variables. - "-Wno-unused-variable", - ], - linkopts = clinkopts + _DEFAULT_PLATFORM_LINKOPTS, - linkstatic = 1, - # _cgo_.o needs all symbols because _cgo_import needs to see them. - alwayslink = 1, - visibility = ["//visibility:private"], - **common_attrs - ) - - cgo_cxx_lib_name = prefix + "cgo_cxx_lib" - native.cc_library( - name = cgo_cxx_lib_name, - srcs = [select_cxx_files], - deps = cdeps, - copts = cxxopts + cppopts + _DEFAULT_PLATFORM_COPTS + [ - # The generated thunks often contain unused variables. - "-Wno-unused-variable", - ], - linkopts = clinkopts + _DEFAULT_PLATFORM_LINKOPTS, - linkstatic = 1, - # _cgo_.o needs all symbols because _cgo_import needs to see them. - alwayslink = 1, - visibility = ["//visibility:private"], - **common_attrs - ) - - cgo_o_deps = [ - cgo_c_lib_name, - cgo_cxx_lib_name, - ] - cgo_collect_info_libs = cgo_o_deps[:] - - if objc: - cgo_objc_lib_name = prefix + "cgo_objc_lib" - objcopts.update(common_attrs) - native.objc_library( - name = cgo_objc_lib_name, - srcs = [select_objc_files], - deps = cdeps, - copts = copts + cppopts + _DEFAULT_PLATFORM_COPTS + [ - # The generated thunks often contain unused variables. - "-Wno-unused-variable", - ], - # _cgo_.o needs all symbols because _cgo_import needs to see them. - alwayslink = 1, - visibility = ["//visibility:private"], - **objcopts - ) - cgo_o_deps.append(cgo_objc_lib_name) - - # cgo needs all the symbols it can find when generating _cgo_import.go. For - # cc_library we use linkstatic = 1. This option does not exist on - # objc_library. To work around that, we used the implicit and documented - # target that objc_library provides, which includes the fully transitive - # dependencies. - # See https://docs.bazel.build/versions/master/be/objective-c.html#objc_library - # for more information. - cgo_collect_info_libs.append(cgo_objc_lib_name + "_fully_linked.a") - - # Create a loadable object with no undefined references. cgo reads this - # when it generates _cgo_import.go. - cgo_o_name = prefix + "_cgo_.o" - native.cc_binary( - name = cgo_o_name, - srcs = [select_main_c], - deps = cdeps + cgo_o_deps, - copts = copts + cppopts + [ - # The generated thunks often contain unused variables. - "-Wno-unused-variable", - ], - linkopts = clinkopts, - visibility = ["//visibility:private"], - **common_attrs - ) - - # Create a Go file which imports symbols from the C library. - cgo_import_name = prefix + "cgo_import" - _cgo_import( - name = cgo_import_name, - cgo_o = cgo_o_name, - sample_go_srcs = [select_go_files], - visibility = ["//visibility:private"], - **common_attrs - ) - - cgo_info_name = prefix + "cgo_info" - _cgo_collect_info( - name = cgo_info_name, - srcs = srcs, - cgo_import = cgo_import_name, - codegen = cgo_codegen_name, - libs = cgo_collect_info_libs, - visibility = ["//visibility:private"], - **common_attrs - ) - return cgo_info_name - # Sets up the cc_ targets when a go_binary is built in either c-archive or # c-shared mode. def go_binary_c_archive_shared(name, kwargs): diff --git a/go/private/rules/wrappers.bzl b/go/private/rules/wrappers.bzl index 4498937321..7554894a82 100644 --- a/go/private/rules/wrappers.bzl +++ b/go/private/rules/wrappers.bzl @@ -12,84 +12,17 @@ # See the License for the specific language governing permissions and # limitations under the License. -load( - "@io_bazel_rules_go//go/private:mode.bzl", - "LINKMODE_NORMAL", -) load("@io_bazel_rules_go//go/private:rules/binary.bzl", "go_binary") load("@io_bazel_rules_go//go/private:rules/library.bzl", "go_library") load("@io_bazel_rules_go//go/private:rules/test.bzl", "go_test") load( "@io_bazel_rules_go//go/private:rules/cgo.bzl", "go_binary_c_archive_shared", - "setup_cgo_library", ) -_CGO_ATTRS = { - "srcs": None, - "cdeps": [], - "copts": [], - "cxxopts": [], - "cppopts": [], - "clinkopts": [], - "objc": False, -} - -_OBJC_CGO_ATTRS = { - "hdrs": None, - "defines": None, - "enable_modules": None, - "includes": None, - "module_map": None, - "non_arc_srcs": None, - "pch": None, - "sdk_dylibs": None, - "sdk_frameworks": None, - "sdk_includes": None, - "textual_hdrs": None, - "weak_sdk_frameworks": None, -} - -_COMMON_ATTRS = { - "tags": ["manual"], - "restricted_to": None, - "compatible_with": None, - "linkmode": LINKMODE_NORMAL, -} - -def _deprecate(attr, name, ruletype, kwargs, message): - value = kwargs.pop(attr, None) - if value and native.repository_name() == "@": - print("DEPRECATED: //{}:{} : the {} attribute on {} is deprecated. {}".format(native.package_name(), name, attr, ruletype, message)) - return value - -def _objc(name, kwargs): - objcopts = {} - for key in kwargs.keys(): - if key.startswith("objc_"): - arg = key[len("objc_"):] - if arg not in _OBJC_CGO_ATTRS: - fail("Forbidden CGo objc_library parameter: " + arg) - value = kwargs.pop(key) - objcopts[arg] = value - return objcopts - def _cgo(name, kwargs): - if not kwargs.get("cgo", False) or not kwargs.get("objc", False): - return - - kwargs.pop("cgo") - linkmode = kwargs.get("linkmode", None) - cgo_attrs = {"name": name} - for key, default in _CGO_ATTRS.items(): - cgo_attrs[key] = kwargs.pop(key, default) - for key, default in _COMMON_ATTRS.items(): - cgo_attrs[key] = kwargs.get(key, default) - if "manual" not in cgo_attrs["tags"]: - cgo_attrs["tags"] = cgo_attrs["tags"] + ["manual"] - cgo_attrs["objcopts"] = _objc(name, kwargs) - cgo_embed = setup_cgo_library(**cgo_attrs) - kwargs["embed"] = kwargs.get("embed", []) + [cgo_embed] + if "objc" in kwargs: + fail("//{}:{}: the objc attribute has been removed. .m sources may be included in srcs or may be extracted into a separated objc_library listed in cdeps.".format(native.package_name(), name)) def go_library_macro(name, **kwargs): """See go/core.rst#go_library for full documentation.""" diff --git a/go/providers.rst b/go/providers.rst index b447c3278c..c24e783cd9 100644 --- a/go/providers.rst +++ b/go/providers.rst @@ -197,10 +197,6 @@ method. In general, only rules_go should need to build or handle these. +--------------------------------+-----------------------------------------------------------------+ | The exposed cc headers for these sources. | +--------------------------------+-----------------------------------------------------------------+ -| :param:`cgo_archives` | :type:`list of File` | -+--------------------------------+-----------------------------------------------------------------+ -| The cgo archives to merge into a go archive for these sources. | -+--------------------------------+-----------------------------------------------------------------+ GoArchiveData ~~~~~~~~~~~~~ diff --git a/go/tools/builders/BUILD.bazel b/go/tools/builders/BUILD.bazel index 0d4d9c0e7c..c93d4a1559 100644 --- a/go/tools/builders/BUILD.bazel +++ b/go/tools/builders/BUILD.bazel @@ -9,28 +9,17 @@ go_test( ], ) -go_test( - name = "extract_test", - size = "small", - srcs = [ - "extract.go", - "extract_test.go", - ], -) - filegroup( name = "builder_srcs", srcs = [ "ar.go", "asm.go", "builder.go", - "cgo.go", "cgo2.go", "compile.go", "compilepkg.go", "cover.go", "env.go", - "extract.go", "filter.go", "filter_buildid.go", "flags.go", diff --git a/go/tools/builders/builder.go b/go/tools/builders/builder.go index f59d6fb6b2..978d40f81b 100644 --- a/go/tools/builders/builder.go +++ b/go/tools/builders/builder.go @@ -41,8 +41,6 @@ func main() { switch verb { case "asm": action = asm - case "cgo": - action = cgo case "compile": action = compile case "compilepkg": diff --git a/go/tools/builders/cgo.go b/go/tools/builders/cgo.go deleted file mode 100644 index 9082b2bd06..0000000000 --- a/go/tools/builders/cgo.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// cgo invokes "go tool cgo" in two separate actions: -// -// * In _cgo_codegen, cgo filters source files and then generates .cgo1.go -// and .cgo2.c files containing split definitions. -// * In _cgo_import, cgo generates _cgo_gotypes.go which contains type -// information for C definitions. - -package main - -import ( - "flag" - "fmt" - "go/build" - "io/ioutil" - "os" - "path/filepath" - "strings" -) - -func cgo(args []string) error { - args, err := readParamsFiles(args) - if err != nil { - return err - } - builderArgs, toolArgs := splitArgs(args) - sources := multiFlag{} - importMode := false - flags := flag.NewFlagSet("CGoCodeGen", flag.ExitOnError) - goenv := envFlags(flags) - flags.Var(&sources, "src", "A source file to be filtered and compiled") - flags.BoolVar(&importMode, "import", false, "When true, run cgo in import mode.") - // process the args - if err := flags.Parse(builderArgs); err != nil { - return err - } - if err := goenv.checkFlags(); err != nil { - return err - } - - // When running in import mode, just invoke cgo with the tool args. No need - // to process source files. - if importMode { - dynpackage, err := extractPackage(sources[0]) - if err != nil { - return err - } - goargs := goenv.goTool("cgo", "-dynpackage", dynpackage) - goargs = append(goargs, toolArgs...) - return goenv.runCommand(goargs) - } - - // create a temporary directory. sources actually passed to cgo will be moved - // here first so that we can use -srcdir to avoid very long mangled filenames. - srcDir, err := ioutil.TempDir("", "srcdir") - if err != nil { - return err - } - defer os.RemoveAll(srcDir) - - // apply build constraints to the source list - // also pick out the cgo sources - cgoSrcs := []string{} - cgoOuts := []string{} - cgoCOuts := []string{} - objDirs := make(map[string]bool) - pkgName := "" - for _, s := range sources { - bits := strings.SplitN(s, "=", 2) - if len(bits) != 2 { - return fmt.Errorf("Invalid source arg, expected output=input got %s", s) - } - out := bits[0] - in := bits[1] - // Check if the file is filtered first - data, err := ioutil.ReadFile(in) - if err != nil { - return err - } - metadata, err := readFileInfo(build.Default, in, true) - if err != nil { - return err - } - // if this is not a go file, it cannot be cgo, so just check the filter - if !strings.HasSuffix(in, ".go") { - // Not a go file, just filter, assume C or C-like - if metadata.matched { - // not filtered, copy over - if err := ioutil.WriteFile(out, data, 0644); err != nil { - return err - } - } else { - // filtered, make empty file - if err := ioutil.WriteFile(out, []byte(""), 0644); err != nil { - return err - } - } - continue - } - - // Go source, must produce both c and go outputs - cOut := strings.TrimSuffix(out, ".cgo1.go") + ".cgo2.c" - - if !metadata.matched { - if metadata.pkg == "" { - return fmt.Errorf("%s: error: could not parse package name", in) - } - // filtered file, fake both the go and the c - if err := ioutil.WriteFile(out, []byte("package "+metadata.pkg), 0644); err != nil { - return err - } - if err := ioutil.WriteFile(cOut, []byte(""), 0644); err != nil { - return err - } - continue - } - - if pkgName != "" && metadata.pkg != pkgName { - return fmt.Errorf("multiple packages found: %s and %s", pkgName, metadata.pkg) - } - pkgName = metadata.pkg - - if metadata.isCgo { - // add to cgo file list - srcInBase := strings.TrimSuffix(filepath.Base(out), ".cgo1.go") + ".go" - srcIn := filepath.Join(srcDir, srcInBase) - if err := ioutil.WriteFile(srcIn, data, 0644); err != nil { - return err - } - cgoSrcs = append(cgoSrcs, srcInBase) - cgoOuts = append(cgoOuts, out) - cgoCOuts = append(cgoCOuts, cOut) - objDirs[filepath.Dir(out)] = true - } else { - // Non cgo file, copy the go and fake the c - if err := ioutil.WriteFile(out, data, 0644); err != nil { - return err - } - if err := ioutil.WriteFile(cOut, []byte(""), 0644); err != nil { - return err - } - } - } - if pkgName == "" { - return fmt.Errorf("no buildable Go source files found") - } - - if len(cgoSrcs) == 0 { - // If there were no cgo sources present, generate a minimal cgo input - // This is so we can still run the cgo tool to build all the other outputs - nullCgoBase := "_cgo_empty.go" - nullCgo := filepath.Join(srcDir, nullCgoBase) - if err := ioutil.WriteFile(nullCgo, []byte("package "+pkgName+"\n/*\n*/\nimport \"C\"\n"), 0644); err != nil { - return err - } - cgoSrcs = append(cgoSrcs, nullCgoBase) - } - - // Tokenize arguments to the C compiler. go_library.copts may contain - // multiple options in the same string. Rules are expected to apply Bourne - // shell tokenization to these, respecting quotes. Ideally, this would - // be done in Skylark, but there's no API, and here, we can just copy what - // go/build does. - var ccArgs []string - toolArgs, ccArgs = splitArgs(toolArgs) - ccArgsSplit := make([]string, 0, len(ccArgs)) - for _, s := range ccArgs { - if r, err := splitQuoted(s); err != nil { - return fmt.Errorf("error tokenizing argument to C compiler: %s: %v:", s, err) - } else { - ccArgsSplit = append(ccArgsSplit, r...) - } - } - - // Run cgo. - goargs := goenv.goTool("cgo", "-srcdir", srcDir) - goargs = append(goargs, toolArgs...) - goargs = append(goargs, "--") - goargs = append(goargs, ccArgsSplit...) - goargs = append(goargs, cgoSrcs...) - if err := goenv.runCommand(goargs); err != nil { - return err - } - - // Now we fix up the generated files - for _, src := range cgoOuts { - if err := fixupLineComments(src, abs("."), false); err != nil { - return err - } - } - for _, src := range cgoCOuts { - if err := fixupLineComments(src, srcDir, true); err != nil { - return err - } - } - for objDir, _ := range objDirs { - if err := fixupLineComments(filepath.Join(objDir, "_cgo_export.h"), srcDir, true); err != nil { - return err - } - } - - return nil -} - -// removes the srcDir prefix from //line or #line comments to make source files reproducible -func fixupLineComments(filename, srcDir string, cFile bool) error { - const goFileLinePrefix = "//line " - const cFileLinePrefix = "#line " - goFileTrim := goFileLinePrefix + srcDir - body, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - lines := strings.Split(string(body), "\n") - for i, line := range lines { - if cFile { - if strings.HasPrefix(line, cFileLinePrefix) { - lines[i] = strings.Replace(line, srcDir+string(os.PathSeparator), "", 1) - } - } else { - if strings.HasPrefix(line, goFileTrim) { - lines[i] = goFileLinePrefix + line[len(goFileTrim)+1:] - } - } - } - if err := ioutil.WriteFile(filename, []byte(strings.Join(lines, "\n")), 0666); err != nil { - return err - } - return nil -} diff --git a/go/tools/builders/extract.go b/go/tools/builders/extract.go deleted file mode 100644 index f1924e1c9f..0000000000 --- a/go/tools/builders/extract.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "go/parser" - "go/token" -) - -func extractPackage(fname string) (string, error) { - fset := token.NewFileSet() - f, err := parser.ParseFile(fset, fname, nil, parser.PackageClauseOnly) - if err != nil { - return "", err - } - return f.Name.String(), nil -} diff --git a/go/tools/builders/extract_test.go b/go/tools/builders/extract_test.go deleted file mode 100644 index 78b0c57480..0000000000 --- a/go/tools/builders/extract_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package main - -import ( - "io/ioutil" - "os" - "testing" -) - -func TestExtract(t *testing.T) { - for _, spec := range []struct { - src string - want string - }{ - // These example inputs also illustrate the reason why we - // cannot simply replace extractPackage with sed(1) or awk(1). - { - src: `package main`, - want: "main", - }, - { - src: `package /* package another */ example // package yetanother`, - want: "example", - }, - } { - f, err := ioutil.TempFile(os.Getenv("TEST_TMPDIR"), "example-go-src") - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) - if err := ioutil.WriteFile(f.Name(), []byte(spec.src), 0644); err != nil { - t.Fatal(err) - } - - name, err := extractPackage(f.Name()) - if err != nil { - t.Errorf("extractPackage(%q) failed with %v; want success; content = %q", f.Name(), err, spec.src) - } - if got, want := name, spec.want; got != want { - t.Errorf("extractPackage(%q) = %q; want %q; content = %q", f.Name(), got, want, spec.src) - } - } -}