Skip to content

Commit

Permalink
Link in native libraries of transitive dependencies in archive mode
Browse files Browse the repository at this point in the history
When linking a go_binary in one of the native archive modes, all
native libraries of transitive dependencies should be included in the
resulting CcInfo, not just the libraries obtained from the cdeps.

This commit adds a `cc_info` field to the `GoSource` provider that
includes the result of merging the `CcInfo`s of all `deps` and `cdeps`
for all Go libraries, not just for those using cgo themselves.
  • Loading branch information
fmeum committed Jun 7, 2022
1 parent e819d11 commit 07c4ee0
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 1 deletion.
6 changes: 6 additions & 0 deletions go/private/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 16 additions & 0 deletions go/private/context.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ load(
"as_iterable",
"goos_to_extension",
"goos_to_shared_extension",
"is_struct",
)
load(
"//go/platform:apple.bzl",
Expand Down Expand Up @@ -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
Expand All @@ -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):
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion go/private/rules/binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 4 additions & 0 deletions go/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~~~~~~~~~
Expand Down
38 changes: 38 additions & 0 deletions tests/core/cgo/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
)
9 changes: 9 additions & 0 deletions tests/core/cgo/direct_dep.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package direct_dep

import (
"github.com/bazelbuild/rules_go/tests/core/cgo/transitive_dep"
)

func PrintGreeting() {
transitive_dep.PrintGreeting()
}
5 changes: 5 additions & 0 deletions tests/core/cgo/native_dep.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stdio.h>

void native_greeting(void) {
printf("Hello, world!\n");
}
1 change: 1 addition & 0 deletions tests/core/cgo/native_dep.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern void native_greeting(void);
10 changes: 10 additions & 0 deletions tests/core/cgo/transitive_dep.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package transitive_dep

/*
#include "tests/core/cgo/native_dep.h"
*/
import "C"

func PrintGreeting() {
C.native_greeting();
}
5 changes: 5 additions & 0 deletions tests/core/cgo/use_c_symbol_through_go.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "tests/core/cgo/use_transitive_symbol.h"

int main() {
PrintGreeting();
}
14 changes: 14 additions & 0 deletions tests/core/cgo/use_transitive_symbol.go
Original file line number Diff line number Diff line change
@@ -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() {}

0 comments on commit 07c4ee0

Please sign in to comment.