diff --git a/go/private/common.bzl b/go/private/common.bzl index 7a28c29d08..5b1785777f 100644 --- a/go/private/common.bzl +++ b/go/private/common.bzl @@ -241,6 +241,12 @@ def as_set(v): return depset(v) fail("as_tuple failed on {}".format(v)) +_STRUCT_TYPE = type(struct()) + +def is_struct(v): + """Returns true if v is a struct.""" + return type(v) == _STRUCT_TYPE + def count_group_matches(v, prefix, suffix): """Counts reluctant substring matches between prefix and suffix. diff --git a/go/private/context.bzl b/go/private/context.bzl index 462b75f176..bbed198895 100644 --- a/go/private/context.bzl +++ b/go/private/context.bzl @@ -50,6 +50,7 @@ load( "as_iterable", "goos_to_extension", "goos_to_shared_extension", + "is_struct", ) load( "//go/platform:apple.bzl", @@ -240,6 +241,7 @@ def _library_to_source(go, attr, library, coverage_instrumented): "clinkopts": _expand_opts(go, "clinkopts", getattr(attr, "clinkopts", [])), "cgo_deps": [], "cgo_exports": [], + "cc_info": None, } if coverage_instrumented: source["cover"] = attr_srcs @@ -266,6 +268,7 @@ def _library_to_source(go, attr, library, coverage_instrumented): fail("source {} has C/C++ extension, but cgo was not enabled (set 'cgo = True')".format(f.path)) if library.resolve: library.resolve(go, attr, source, _merge_embed) + source["cc_info"] = _collect_cc_infos(source["deps"], source["cdeps"]) return GoSource(**source) def _collect_runfiles(go, data, deps): @@ -280,6 +283,19 @@ def _collect_runfiles(go, data, deps): runfiles = runfiles.merge(get_source(t).runfiles) return runfiles +def _collect_cc_infos(deps, cdeps): + cc_infos = [] + for dep in cdeps: + if CcInfo in dep: + cc_infos.append(dep[CcInfo]) + for dep in deps: + # dep may be a struct, which doesn't support indexing by providers. + if is_struct(dep): + continue + if GoSource in dep: + cc_infos.append(dep[GoSource].cc_info) + return cc_common.merge_cc_infos(cc_infos = cc_infos) + def _check_binary_dep(go, dep, edge): """Checks that this rule doesn't depend on a go_binary or go_test. diff --git a/go/private/rules/binary.bzl b/go/private/rules/binary.bzl index 8d95020ef9..752324e1be 100644 --- a/go/private/rules/binary.bzl +++ b/go/private/rules/binary.bzl @@ -163,7 +163,7 @@ def _go_binary_impl(ctx): cc_import_kwargs["alwayslink"] = True ccinfo = new_cc_import(go, **cc_import_kwargs) ccinfo = cc_common.merge_cc_infos( - cc_infos = [ccinfo] + [d[CcInfo] for d in source.cdeps], + cc_infos = [ccinfo, source.cc_info], ) providers.append(ccinfo) diff --git a/go/providers.rst b/go/providers.rst index d3b45765e0..3f903c69e6 100644 --- a/go/providers.rst +++ b/go/providers.rst @@ -204,6 +204,10 @@ method. In general, only rules_go should need to build or handle these. +--------------------------------+-----------------------------------------------------------------+ | The exposed cc headers for these sources. | +--------------------------------+-----------------------------------------------------------------+ +| :param:`cc_info` | :type:`CcInfo` | ++--------------------------------+-----------------------------------------------------------------+ +| The result of merging the ``CcInfo``s of all `deps` and `cdeps` | ++--------------------------------+-----------------------------------------------------------------+ GoArchiveData ~~~~~~~~~~~~~ diff --git a/tests/core/cgo/BUILD.bazel b/tests/core/cgo/BUILD.bazel index cefa1b9812..cc12203fac 100644 --- a/tests/core/cgo/BUILD.bazel +++ b/tests/core/cgo/BUILD.bazel @@ -434,3 +434,41 @@ go_binary( }), deps = [":use_external_symbol"], ) + +cc_library( + name = "native_dep", + srcs = ["native_dep.c"], + hdrs = ["native_dep.h"], + # Force static linking to ensure that the build doesn't succeed by + # accidentally picking up the shared library in the search path. + linkstatic = True, +) + +go_library( + name = "transitive_dep", + srcs = ["transitive_dep.go"], + cdeps = [":native_dep"], + cgo = True, + importpath = "github.com/bazelbuild/rules_go/tests/core/cgo/transitive_dep", +) + +go_library( + name = "direct_dep", + srcs = ["direct_dep.go"], + importpath = "github.com/bazelbuild/rules_go/tests/core/cgo/direct_dep", + deps = [":transitive_dep"], +) + +go_binary( + name = "use_transitive_symbol", + srcs = ["use_transitive_symbol.go"], + cgo = True, + linkmode = "c-archive", + deps = [":direct_dep"], +) + +cc_binary( + name = "use_c_symbol_through_go", + srcs = ["use_c_symbol_through_go.c"], + deps = [":use_transitive_symbol"], +) diff --git a/tests/core/cgo/direct_dep.go b/tests/core/cgo/direct_dep.go new file mode 100644 index 0000000000..6f7178638a --- /dev/null +++ b/tests/core/cgo/direct_dep.go @@ -0,0 +1,9 @@ +package direct_dep + +import ( + "github.com/bazelbuild/rules_go/tests/core/cgo/transitive_dep" +) + +func PrintGreeting() { + transitive_dep.PrintGreeting() +} diff --git a/tests/core/cgo/native_dep.c b/tests/core/cgo/native_dep.c new file mode 100644 index 0000000000..f6504a8551 --- /dev/null +++ b/tests/core/cgo/native_dep.c @@ -0,0 +1,5 @@ +#include + +void native_greeting(void) { + printf("Hello, world!\n"); +} diff --git a/tests/core/cgo/native_dep.h b/tests/core/cgo/native_dep.h new file mode 100644 index 0000000000..5d750beb50 --- /dev/null +++ b/tests/core/cgo/native_dep.h @@ -0,0 +1 @@ +extern void native_greeting(void); diff --git a/tests/core/cgo/transitive_dep.go b/tests/core/cgo/transitive_dep.go new file mode 100644 index 0000000000..40632f5036 --- /dev/null +++ b/tests/core/cgo/transitive_dep.go @@ -0,0 +1,10 @@ +package transitive_dep + +/* +#include "tests/core/cgo/native_dep.h" + */ +import "C" + +func PrintGreeting() { + C.native_greeting(); +} diff --git a/tests/core/cgo/use_c_symbol_through_go.c b/tests/core/cgo/use_c_symbol_through_go.c new file mode 100644 index 0000000000..bd5b7fecc9 --- /dev/null +++ b/tests/core/cgo/use_c_symbol_through_go.c @@ -0,0 +1,5 @@ +#include "tests/core/cgo/use_transitive_symbol.h" + +int main() { + PrintGreeting(); +} diff --git a/tests/core/cgo/use_transitive_symbol.go b/tests/core/cgo/use_transitive_symbol.go new file mode 100644 index 0000000000..c229311e45 --- /dev/null +++ b/tests/core/cgo/use_transitive_symbol.go @@ -0,0 +1,14 @@ +package main + +import "C" + +import ( + "github.com/bazelbuild/rules_go/tests/core/cgo/direct_dep" +) + +//export PrintGreeting +func PrintGreeting() { + direct_dep.PrintGreeting() +} + +func main() {}