daml/bazel_tools/fat_cc_library.bzl
Moritz Kiefer e0c5abd647
Switch to GHC 8.10.3 (#8394)
* Switch to GHC 8.10.3

changelog_begin
changelog_end

* Update bazel-haskell-deps.bzl

Co-authored-by: Andreas Herrmann <42969706+aherrmann-da@users.noreply.github.com>

* Comment on rules_haskell patch

changelog_begin
changelog_end

* .

changelog_begin
changelog_end

Co-authored-by: Andreas Herrmann <42969706+aherrmann-da@users.noreply.github.com>
2021-01-25 11:53:53 +00:00

138 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@os_info//:os_info.bzl", "is_darwin", "is_windows")
def _fat_cc_library_impl(ctx):
input_lib = ctx.attr.input_lib
cc_info = input_lib[CcInfo]
static_libs = []
# For now we assume that we have static PIC libs for all libs.
# It should be possible to extend this but we do not have a need
# for it so far and it would complicate things.
for lib in cc_info.linking_context.libraries_to_link.to_list():
static_lib = None
if lib.pic_static_library:
static_lib = lib.pic_static_library
elif is_windows and lib.static_library:
# On Windows we don't seem to have `pic_static_library`s available.
static_lib = lib.static_library
else:
fail("No (PIC) static library found for '{}'.".format(
str(lib.dynamic_library.path),
))
static_libs += [static_lib]
dyn_lib = ctx.outputs.dynamic_library
static_lib = ctx.outputs.static_library
toolchain = find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
compiler = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = ACTION_NAMES.c_compile,
)
ctx.actions.run(
mnemonic = "CppLinkFatDynLib",
outputs = [dyn_lib],
executable = compiler,
tools = toolchain.all_files.to_list(),
arguments =
["-o", dyn_lib.path, "-shared"] +
ctx.attr.whole_archive_flag +
[f.path for f in static_libs] +
ctx.attr.no_whole_archive_flag +
# Some libs seems to depend on libstdc++ implicitely
["-lstdc++"] +
(["-framework", "CoreFoundation"] if is_darwin else []) +
# On Windows some libs seems to depend on Windows sockets
(["-lws2_32"] if is_windows else []),
inputs = static_libs,
env = {"PATH": ""},
)
mri_script_content = "\n".join(
["create {}".format(static_lib.path)] +
["addlib {}".format(lib.path) for lib in static_libs] +
["save", "end"],
) + "\n"
mri_script = ctx.actions.declare_file(ctx.label.name + "_mri")
ctx.actions.write(mri_script, mri_script_content)
ar = toolchain.ar_executable
if ar.find("libtool") >= 0:
# We are on MacOS where ar_executable is actually libtool, see
# https://github.com/bazelbuild/bazel/issues/5127.
ctx.actions.run(
mnemonic = "CppLinkFatStaticLib",
outputs = [static_lib],
executable = ar,
inputs = static_libs,
arguments =
["-no_warning_for_no_symbols", "-static", "-o", static_lib.path] +
[f.path for f in static_libs],
)
else:
ctx.actions.run_shell(
mnemonic = "CppLinkFatStaticLib",
outputs = [static_lib],
inputs = [mri_script] + static_libs,
command = "{ar} -M < {mri_script}".format(ar = ar, mri_script = mri_script.path),
)
fat_lib = cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = toolchain,
dynamic_library = dyn_lib,
static_library = static_lib,
)
new_linking_context = cc_common.create_linking_context(
libraries_to_link = [fat_lib],
)
new_cc_info = CcInfo(
linking_context = new_linking_context,
compilation_context = cc_info.compilation_context,
)
return [new_cc_info]
# Shared libraries built with Bazel do not declare their dependencies on other libraries properly.
# Instead that dependency is tracked in Bazel internally. This breaks the GHCi linker if
# RTLD_LAZY doesnt work which happens quite often. To make matters worse, we also cannot use
# linkstatic = True, since the GHCi linker cannot handle some relocations.
# To work around this mess, we create fat libraries that do not have additional dependencies.
# See https://github.com/tweag/rules_haskell/issues/720
fat_cc_library = rule(
_fat_cc_library_impl,
attrs = dict({
"input_lib": attr.label(),
"_cc_toolchain": attr.label(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
"whole_archive_flag": attr.string_list(
# ld on MacOS doesnt understand --whole-archive
default = ["-Wl,-all_load"] if is_darwin else ["-Wl,--whole-archive"],
),
"no_whole_archive_flag": attr.string_list(
default = [] if is_darwin else ["-Wl,--no-whole-archive"],
),
}),
fragments = ["cpp"],
outputs = {
"dynamic_library": "lib%{name}.dll" if is_windows else "lib%{name}.so",
"static_library": "lib%{name}.a",
},
)