-
-
Notifications
You must be signed in to change notification settings - Fork 661
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
Split C and C++ compilation #1366
Conversation
I took a quick look, but I won't be able to do a detailed review until tomorrow. I have a couple concerns before then though:
|
Thanks for being so fast. Here are some answers:
|
For c++14, it looks like the recommended way is to pass About C/C++ sandwich: @mhlopko, how's it going? Will ObjC be supported, too? For context, it would be useful to build mixed C/C++/ObjC sources that appear alongside cgo code. Right now, we build C/C++ as a |
Indeed, I saw that flag but I figure it was easier just splitting and doing it package by package and also because Go supports setting |
I'll wait until #1365 is merged before diving into this. |
Sure thing! |
Sorry for the slow reply. We are working on 2 things in C++ rules:
I don't know much about open source go rules, but I assume you'll want to use the sandwich. That will allow you to consume C++ providers, dig objects out, and use them with cgo. @oquenchil can comment on timeframes. Re ObjC, they will use their own providers, but tbh I don't know much about that. Maybe @c-parsons has more information. |
@mhlopko thanks for the reply Indeed we'd like to be able to return See for instance at https://github.com/bazelbuild/rules_go/pull/1365/files#diff-dfaef6484291891479c192a6169bc232R90 |
Changed |
@mhlopko I'm actually most interested in the toolchain being exposed in Skylark. How far along is that? #4571 doesn't have much information. We'd like to be able to invoke a C / C++ / ObjC compiler and linker on some generated code during execution without creating The sandwich is also useful for other things, but I'm mainly interested in the toolchain right now. |
Correct me if I'm wrong, but why not do a pure skylark |
I think that's the long-term plan, but the C/C++ rules are really complicated, having accumulated a decade's worth of features and idiosyncrasies within Google. A full migration will take years. I hope a simplified version that serves most common cases will be available sooner than that though. |
Steeve: that's the end goal, to migrate existing rules into Skylark. But there are things that C++ rules do that are not supported in Skylark yet, plus we want to use the same rules internally and externally, and for that we need to do small incremental steps, making sure google doesn't break. Jay: Since I still know very little about external go rules let me make sure at least you have enough information to decide what's best :) Part of the sandwich (spoiler alert :) are functions cc_common.compile(...) and cc_common.link(...). AFAIK this is what you need, give C++ rules sources, compile them, make a .a of them, and propagate providers. Toolchain api will only enable you to get the command line flags that C++ rules would use. That's definitely something you need for internal go rules though. The work is ongoing, optimistically EOQ1 for test runs behind a whitelist. I'll keep you updated. |
This timeframe sounds correct. This should be tested internally first where we have more control on who's using the API and we can change it more easily if necessary. |
Please hold on this one, I'm going to properly rebase it on top of |
Signed-off-by: Steeve Morin <[email protected]>
Signed-off-by: Steeve Morin <[email protected]>
Signed-off-by: Steeve Morin <[email protected]>
I've properly rebased it and added tests. |
The test failure is due to the Travis machine apparently not having a C++14 compiler installed. https://travis-ci.org/bazelbuild/rules_go/jobs/363343765#L2495
https://travis-ci.org/bazelbuild/rules_go/jobs/363343765#L2504
I can change the test to use C++11. But I was using C++14 specific feaures to highlight it, but oh well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for rebasing and sorry for the slow response; I just got back from vacation.
I have a few comments on specifics, but this seems like the right approach given our current constraints. I hope that when Bazel lets us build C/C++/ObjC command lines, we can simplify this and stop using separate cc_library
rules.
go/private/rules/cgo.bzl
Outdated
@@ -283,7 +295,7 @@ def _cgo_collect_info_impl(ctx): | |||
gen_go_srcs = codegen.gen_go + import_files, | |||
cgo_deps = codegen.deps, | |||
cgo_exports = codegen.exports, | |||
cgo_archive = _select_archive(ctx.files.lib), | |||
cgo_archives = _select_archives(ctx.files.libs), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update documentation for GoSource
in go/providers.rst to reflect this change.
FYI, I'm okay with small API breaking changes like this in providers between major versions. I doubt many people are using this yet. In the future, we may need to be more strict about this though.
@@ -16,7 +16,7 @@ def emit_pack(go, | |||
in_lib = None, | |||
out_lib = None, | |||
objects = [], | |||
archive = None): | |||
archives = []): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update documentation in go/toolchains.rst#pack
to reflect this change.
go/private/rules/cgo.bzl
Outdated
@@ -78,20 +78,23 @@ def _c_filter_options(options, blacklist): | |||
return [opt for opt in options | |||
if not any([opt.startswith(prefix) for prefix in blacklist])] | |||
|
|||
def _select_archive(files): | |||
def _select_archives(files): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is safe. See the documentation below. cc_library
may produce multiple output files, and we want exactly one of them.
Instead of calling this once on ctx.files.libs
, call for each target, i.e., [_select_archive(lib.files) for lib in ctx.attr.libs]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i still need to check that one out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok got it, i've pushed a fix
go/private/rules/cgo.bzl
Outdated
@@ -325,13 +337,17 @@ def setup_cgo_library(name, srcs, cdeps, copts, clinkopts): | |||
"external/" + REPOSITORY_NAME[1:] if len(REPOSITORY_NAME) > 1 else "", | |||
PACKAGE_NAME) | |||
copts = copts + ["-I", base_dir] | |||
cxxopts = cxxopts + ["-I", base_dir] | |||
cppopts = cppopts + ["-I", base_dir] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we're separating copts
and cppopts
, this flag should only be added to cppopts
.
Please also double-check all mentions of copts
in this file. There are several places in _cgo_codegen_impl
where it should be changed to cppopts
. Basically anything that isn't specific to C or C++ should be changed.
@@ -25,6 +25,8 @@ _CGO_ATTRS = { | |||
"srcs": None, | |||
"cdeps": [], | |||
"copts": [], | |||
"cxxopts": [], | |||
"cppopts": [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update attribute tables in go/core.rst to include the new attributes.
This may break people that have C++ code that currently depends on options in copts
. Hopefully this won't affect many people. I'll file an issue on Gazelle to separate these.
tests/core/cxx/BUILD.bazel
Outdated
@@ -0,0 +1,19 @@ | |||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Several test comments:
- In terms of test organization, I'd prefer this to be tests/core/cgo, since this is really testing cgo functionality. Could be divided further into language subdirectories (tests/core/cgo/cxx).
- We really want to verify that the right set of options get passed to each language.
copts
should be C-only,cxxopts
should be C++-only,cppopts
should be both. Easiest way to do that is probably with-D
flags, then checking at build time with#if
and#error
. This would also fix the error on Travis CI due not having a C++14 compiler available. - Please create a README.rst describing the tests, and run tests/update.py.
I'm in a bit of a dilemma over |
PR updated with most of the advices. |
Never mind I think I solved it by a41c767 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting close. A few more minor comments on changes.
outs = [] | ||
for lib in libs: | ||
archive = _select_archive(lib.files) | ||
if archive: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When would a cc_library
not produce any usable archives? Does that happen if there are no source files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can happen if there are only header files (which happens if C++ files are missing, for instance).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize I could have been clearer. In the case of a regular C compilation, the cc_library
responsible of building the C++ files will not produce any archive.
go/private/rules/cgo.bzl
Outdated
|
||
def _cgo_codegen_impl(ctx): | ||
go = go_context(ctx) | ||
if not go.cgo_tools: | ||
fail("Go toolchain does not support cgo") | ||
linkopts = ctx.attr.linkopts[:] | ||
copts = go.cgo_tools.c_options + go.cgo_tools.compiler_options + ctx.attr.copts | ||
cppopts = go.cgo_tools.c_options + go.cgo_tools.compiler_options + ctx.attr.copts + ctx.attr.cppopts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep cppopts
and copts
separate here for clarity.
cppopts = go.cgo_tools.compiler_options +ctx.attr.cppopts
copts = go.cgo_tools.c_options + ctx.attr.copts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it
go/private/rules/cgo.bzl
Outdated
@@ -161,10 +181,10 @@ def _cgo_codegen_impl(ctx): | |||
# The first -- below is to stop the cgo from processing args, the | |||
# second is an actual arg to forward to the underlying go tool | |||
args.add(["--", "--"]) | |||
args.add(copts) | |||
args.add(cppopts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both cppopts
and copts
can be added here.
tests/core/cgo/BUILD.bazel
Outdated
cgo = True, | ||
copts = ["-DRULES_GO_C"], | ||
cxxopts = ["-DRULES_GO_CPP"], | ||
srcs = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define something in cppopts
and check that define is visible in both add.c and add.cpp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -392,6 +392,18 @@ Attributes | |||
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. | | |||
| Only valid if :param:`cgo` = :value:`True`. | | |||
+----------------------------+-----------------------------+---------------------------------------+ | |||
| :param:`cxxopts` | :type:`string_list` | :value:`[]` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but copy to go_library
and go_test
.
Signed-off-by: Steeve Morin <[email protected]>
Signed-off-by: Steeve Morin <[email protected]>
Signed-off-by: Steeve Morin <[email protected]>
…one) Signed-off-by: Steeve Morin <[email protected]>
Signed-off-by: Steeve Morin <[email protected]>
I've updated the PR, thank you for the feedback! |
@jayconrod do you want me to rebase instead ? |
@steeve No need, I was just waiting for CI to run again after resolving the merge conflict. Thanks again for working on this. |
What it does
This PR splits C and C++ CGo compilation into separate steps. The main idea behind this is for specifying per language options (such as
std=c++14
for C++).For that, the
pack
builder has been modified to take multiple archives (C and C++) and fuse them.This is also a required step for adding ObjC support.
I have also added a commit which tries to make relative
CC
options absolute (via whitelisting)