Skip to content

Commit

Permalink
Split C and C++ compilation (#1366)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
steeve authored and jayconrod committed Apr 18, 2018
1 parent 0dca364 commit dcaae02
Show file tree
Hide file tree
Showing 17 changed files with 249 additions and 62 deletions.
38 changes: 37 additions & 1 deletion go/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Binaries that depend on this library may also set this value.
go_binary(
name = "cmd",
srcs = ["main.go"],
srcs = ["main.go"],
deps = ["//version:go_default_library"],
x_defs = {"example.com/repo/version.Version", "0.9"},
)
Expand Down Expand Up @@ -235,6 +235,18 @@ Attributes
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cxxopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C++ compilation command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cppopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C/C++ preprocessor command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`clinkopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C link command. |
Expand Down Expand Up @@ -392,6 +404,18 @@ Attributes
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cxxopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C++ compilation command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cppopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C/C++ preprocessor command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`clinkopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C link command. |
Expand Down Expand Up @@ -503,6 +527,18 @@ Attributes
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cxxopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C++ compilation command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`cppopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C/C++ preprocessor command. |
| Subject to `"Make variable"`_ substitution and `Bourne shell tokenization`_. |
| Only valid if :param:`cgo` = :value:`True`. |
+----------------------------+-----------------------------+---------------------------------------+
| :param:`clinkopts` | :type:`string_list` | :value:`[]` |
+----------------------------+-----------------------------+---------------------------------------+
| List of flags to add to the C link command. |
Expand Down
4 changes: 2 additions & 2 deletions go/private/actions/archive.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def emit_archive(go, source=None):
runfiles = runfiles.merge(a.runfiles)
if a.source.mode != go.mode: fail("Archive mode does not match {} is {} expected {}".format(a.data.label, mode_string(a.source.mode), mode_string(go.mode)))

if len(extra_objects) == 0 and source.cgo_archive == None:
if len(extra_objects) == 0 and not source.cgo_archives:
go.compile(go,
sources = split.go,
importpath = source.library.importmap,
Expand All @@ -77,7 +77,7 @@ def emit_archive(go, source=None):
in_lib = partial_lib,
out_lib = out_lib,
objects = extra_objects,
archive = source.cgo_archive,
archives = source.cgo_archives,
)
data = GoArchiveData(
name = source.library.name,
Expand Down
7 changes: 3 additions & 4 deletions go/private/actions/pack.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def emit_pack(go,
in_lib = None,
out_lib = None,
objects = [],
archive = None):
archives = []):
"""See go/toolchains.rst#pack for full documentation."""

if in_lib == None: fail("in_lib is a required parameter")
Expand All @@ -32,9 +32,8 @@ def emit_pack(go,
inputs.extend(objects)
arguments.add(objects, before_each="-obj")

if archive:
inputs.append(archive)
arguments.add(["-arc", archive])
inputs.extend(archives)
arguments.add(archives, before_each="-arc")

go.actions.run(
inputs = inputs,
Expand Down
10 changes: 8 additions & 2 deletions go/private/common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ hdr_exts = [

c_exts = [
".c",
".h",
]

cxx_exts = [
".cc",
".cxx",
".cpp",
Expand All @@ -56,7 +60,7 @@ cc_hdr_filetype = FileType(hdr_exts)

# Extensions of files we can build with the Go compiler or with cc_library.
# This is a subset of the extensions recognized by go/build.
cgo_filetype = FileType(go_exts + asm_exts + c_exts)
cgo_filetype = FileType(go_exts + asm_exts + c_exts + cxx_exts)

def pkg_dir(workspace_root, package_name):
"""Returns a relative path to a package directory from the root of the
Expand All @@ -75,12 +79,14 @@ def split_srcs(srcs):
asm = [],
headers = [],
c = [],
cxx = [],
)
ext_pairs = (
(sources.go, go_exts),
(sources.headers, hdr_exts),
(sources.asm, asm_exts),
(sources.c, c_exts),
(sources.cxx, cxx_exts),
)
extmap = {}
for outs, exts in ext_pairs:
Expand All @@ -97,7 +103,7 @@ def split_srcs(srcs):
return sources

def join_srcs(source):
return source.go + source.headers + source.asm + source.c
return source.go + source.headers + source.asm + source.c + source.cxx

def env_execute(ctx, arguments, environment = {}, **kwargs):
"""env_executes a command in a repository context. It prepends "env -i"
Expand Down
12 changes: 7 additions & 5 deletions go/private/context.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ def _new_args(go):
"-compiler_path", go.cgo_tools.compiler_path,
"-cc", go.cgo_tools.compiler_executable,
])
args.add(go.cgo_tools.compiler_options, before_each = "-c_flag")
args.add(go.cgo_tools.compiler_options, before_each = "-cxx_flag")
args.add(go.cgo_tools.compiler_options, before_each = "-cpp_flag")
args.add(go.cgo_tools.linker_options, before_each = "-ld_flag")
return args
Expand Down Expand Up @@ -129,10 +131,10 @@ def _merge_embed(source, embed):
source["runfiles"] = source["runfiles"].merge(s.runfiles)
source["cgo_deps"] = source["cgo_deps"] + s.cgo_deps
source["cgo_exports"] = source["cgo_exports"] + s.cgo_exports
if s.cgo_archive:
if source["cgo_archive"]:
fail("multiple libraries with cgo_archive embedded")
source["cgo_archive"] = s.cgo_archive
if s.cgo_archives:
if source["cgo_archives"]:
fail("multiple libraries with cgo_archives embedded")
source["cgo_archives"] = s.cgo_archives

def _library_to_source(go, attr, library, coverage_instrumented):
#TODO: stop collapsing a depset in this line...
Expand All @@ -149,7 +151,7 @@ def _library_to_source(go, attr, library, coverage_instrumented):
"deps" : getattr(attr, "deps", []),
"gc_goopts" : getattr(attr, "gc_goopts", []),
"runfiles" : go._ctx.runfiles(collect_data = True),
"cgo_archive" : None,
"cgo_archives" : [],
"cgo_deps" : [],
"cgo_exports" : [],
}
Expand Down
Loading

0 comments on commit dcaae02

Please sign in to comment.