Bootstrap make reproducibly (#817)
* Make cc_toolchain_utils.bzl more reusable By using getattr, the helper functions in this file can be reused in rules that do not define all of the framework attributes, e.g. bootstrap rules. * Bootstrap make reproducibly on Linux and macOS Uses the Bazel C/C++ toolchain to bootstrap make and ensure that the resulting binary contains no absolute and thus non-hermetic paths. Building make reproducibly helps with remote caching and removes the dependency on a C compiler installed on the host.
This commit is contained in:
parent
a2f1e5d8c3
commit
0cf751c053
|
@ -8,6 +8,13 @@ load(
|
|||
"FOREIGN_CC_BUILT_TOOLS_HOST_FRAGMENTS",
|
||||
"built_tool_rule_impl",
|
||||
)
|
||||
load(
|
||||
"//foreign_cc/private:cc_toolchain_util.bzl",
|
||||
"absolutize_path_in_str",
|
||||
"get_env_vars",
|
||||
"get_flags_info",
|
||||
"get_tools_info",
|
||||
)
|
||||
load("//foreign_cc/private/framework:platform.bzl", "os_name")
|
||||
|
||||
def _make_tool_impl(ctx):
|
||||
|
@ -29,8 +36,54 @@ def _make_tool_impl(ctx):
|
|||
"cp -p ./{}/gnumake.exe $$INSTALLDIR$$/bin/make.exe".format(dist_dir),
|
||||
]
|
||||
else:
|
||||
env = get_env_vars(ctx)
|
||||
flags_info = get_flags_info(ctx)
|
||||
tools_info = get_tools_info(ctx)
|
||||
|
||||
ar_path = tools_info.cxx_linker_static
|
||||
frozen_arflags = flags_info.cxx_linker_static
|
||||
|
||||
cc_path = tools_info.cc
|
||||
cflags = flags_info.cc
|
||||
sysroot_cflags = [flag for flag in cflags if flag.startswith("--sysroot=")]
|
||||
non_sysroot_cflags = [flag for flag in cflags if not flag.startswith("--sysroot=")]
|
||||
|
||||
ld_path = tools_info.cxx_linker_executable
|
||||
ldflags = flags_info.cxx_linker_executable
|
||||
sysroot_ldflags = [flag for flag in ldflags if flag.startswith("--sysroot=")]
|
||||
non_sysroot_ldflags = [flag for flag in ldflags if not flag.startswith("--sysroot=")]
|
||||
|
||||
# Make's build script does not forward CFLAGS to all compiler and linker
|
||||
# invocations, so we append --sysroot flags directly to CC and LD.
|
||||
absolute_cc = _absolutize(ctx.workspace_name, cc_path, True)
|
||||
if sysroot_cflags:
|
||||
absolute_cc += " " + _join_flags_list(ctx.workspace_name, sysroot_cflags)
|
||||
absolute_ld = _absolutize(ctx.workspace_name, ld_path, True)
|
||||
if sysroot_ldflags:
|
||||
absolute_ld += " " + _join_flags_list(ctx.workspace_name, sysroot_ldflags)
|
||||
|
||||
# If libtool is used as AR, the output file has to be prefixed with
|
||||
# "-o". Since the make Makefile only uses ar-style invocations, the
|
||||
# output file always comes first and we can append this argument to the
|
||||
# flags list.
|
||||
absolute_ar = _absolutize(ctx.workspace_name, ar_path, True)
|
||||
arflags = [e for e in frozen_arflags]
|
||||
if absolute_ar == "libtool" or absolute_ar.endswith("/libtool"):
|
||||
arflags.append("-o")
|
||||
|
||||
env.update({
|
||||
"AR": absolute_ar,
|
||||
"ARFLAGS": _join_flags_list(ctx.workspace_name, arflags),
|
||||
"CC": absolute_cc,
|
||||
"CFLAGS": _join_flags_list(ctx.workspace_name, non_sysroot_cflags),
|
||||
"LD": absolute_ld,
|
||||
"LDFLAGS": _join_flags_list(ctx.workspace_name, non_sysroot_ldflags),
|
||||
})
|
||||
|
||||
configure_env = " ".join(["%s=\"%s\"" % (key, value) for key, value in env.items()])
|
||||
script = [
|
||||
"./configure --without-guile --with-guile=no --disable-dependency-tracking --prefix=$$INSTALLDIR$$",
|
||||
"%s ./configure --without-guile --with-guile=no --disable-dependency-tracking --prefix=$$INSTALLDIR$$" % configure_env,
|
||||
"cat build.cfg",
|
||||
"./build.sh",
|
||||
"./make install",
|
||||
]
|
||||
|
@ -54,3 +107,9 @@ make_tool = rule(
|
|||
"@bazel_tools//tools/cpp:toolchain_type",
|
||||
],
|
||||
)
|
||||
|
||||
def _absolutize(workspace_name, text, force = False):
|
||||
return absolutize_path_in_str(workspace_name, "$$EXT_BUILD_ROOT$$/", text, force)
|
||||
|
||||
def _join_flags_list(workspace_name, flags):
|
||||
return " ".join([_absolutize(workspace_name, flag) for flag in flags])
|
||||
|
|
|
@ -118,7 +118,7 @@ def _files_map(files_list):
|
|||
return by_names_map
|
||||
|
||||
def _defines_from_deps(ctx):
|
||||
return depset(transitive = [dep[CcInfo].compilation_context.defines for dep in ctx.attr.deps])
|
||||
return depset(transitive = [dep[CcInfo].compilation_context.defines for dep in getattr(ctx.attr, "deps", [])])
|
||||
|
||||
def _build_cc_link_params(
|
||||
ctx,
|
||||
|
@ -301,9 +301,9 @@ def get_flags_info(ctx, link_output_file = None):
|
|||
cc_toolchain = cc_toolchain_,
|
||||
)
|
||||
|
||||
copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + ctx.attr.copts) or []
|
||||
cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + ctx.attr.copts) or []
|
||||
linkopts = (ctx.fragments.cpp.linkopts + ctx.attr.linkopts) or []
|
||||
copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + getattr(ctx.attr, "copts", [])) or []
|
||||
cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + getattr(ctx.attr, "copts", [])) or []
|
||||
linkopts = (ctx.fragments.cpp.linkopts + getattr(ctx.attr, "linkopts", [])) or []
|
||||
defines = _defines_from_deps(ctx)
|
||||
|
||||
flags = CxxFlagsInfo(
|
||||
|
|
|
@ -412,6 +412,7 @@ def _make_toolchain(version):
|
|||
http_archive,
|
||||
name = "gnumake_src",
|
||||
build_file_content = _ALL_CONTENT,
|
||||
patches = ["@rules_foreign_cc//toolchains:make-reproducible-bootstrap.patch"],
|
||||
sha256 = "e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19",
|
||||
strip_prefix = "make-4.3",
|
||||
urls = [
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
diff --git Makefile.in Makefile.in
|
||||
index 9535058..0b12e99 100644
|
||||
--- Makefile.in
|
||||
+++ Makefile.in
|
||||
@@ -1042,8 +1042,8 @@ make_LDADD = $(LIBOBJS) $(GUILE_LIBS) lib/libgnu.a $(GETLOADAVG_LIBS) \
|
||||
@LIBINTL@
|
||||
|
||||
AM_CPPFLAGS = -Isrc -I$(top_srcdir)/src -Ilib -I$(top_srcdir)/lib \
|
||||
- -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" \
|
||||
- -DLOCALEDIR=\"$(localedir)\" $(am__append_2)
|
||||
+ -DLIBDIR=\".\" -DINCLUDEDIR=\"external/rules_foreign_cc/toolchains/make/include\" \
|
||||
+ -DLOCALEDIR=\"external/rules_foreign_cc/toolchains/make/share/locale\" $(am__append_2)
|
||||
AM_CFLAGS = $(GUILE_CFLAGS)
|
||||
|
||||
# Extra stuff to include in the distribution.
|
||||
|
Loading…
Reference in New Issue