Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link in native libraries of transitive dependencies in archive mode #3186

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just so I understand, can you give an example of this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The deps may be providers rather than targets, see the note on attr at https://github.com/bazelbuild/rules_go/blob/master/go/toolchains.rst#library_to_source.

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],
fmeum marked this conversation as resolved.
Show resolved Hide resolved
)
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` |
fmeum marked this conversation as resolved.
Show resolved Hide resolved
+--------------------------------+-----------------------------------------------------------------+

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() {}