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",
|
"FOREIGN_CC_BUILT_TOOLS_HOST_FRAGMENTS",
|
||||||
"built_tool_rule_impl",
|
"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")
|
load("//foreign_cc/private/framework:platform.bzl", "os_name")
|
||||||
|
|
||||||
def _make_tool_impl(ctx):
|
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),
|
"cp -p ./{}/gnumake.exe $$INSTALLDIR$$/bin/make.exe".format(dist_dir),
|
||||||
]
|
]
|
||||||
else:
|
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 = [
|
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",
|
"./build.sh",
|
||||||
"./make install",
|
"./make install",
|
||||||
]
|
]
|
||||||
|
@ -54,3 +107,9 @@ make_tool = rule(
|
||||||
"@bazel_tools//tools/cpp:toolchain_type",
|
"@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
|
return by_names_map
|
||||||
|
|
||||||
def _defines_from_deps(ctx):
|
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(
|
def _build_cc_link_params(
|
||||||
ctx,
|
ctx,
|
||||||
|
@ -301,9 +301,9 @@ def get_flags_info(ctx, link_output_file = None):
|
||||||
cc_toolchain = cc_toolchain_,
|
cc_toolchain = cc_toolchain_,
|
||||||
)
|
)
|
||||||
|
|
||||||
copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + ctx.attr.copts) or []
|
copts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts + getattr(ctx.attr, "copts", [])) or []
|
||||||
cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + ctx.attr.copts) or []
|
cxxopts = (ctx.fragments.cpp.copts + ctx.fragments.cpp.cxxopts + getattr(ctx.attr, "copts", [])) or []
|
||||||
linkopts = (ctx.fragments.cpp.linkopts + ctx.attr.linkopts) or []
|
linkopts = (ctx.fragments.cpp.linkopts + getattr(ctx.attr, "linkopts", [])) or []
|
||||||
defines = _defines_from_deps(ctx)
|
defines = _defines_from_deps(ctx)
|
||||||
|
|
||||||
flags = CxxFlagsInfo(
|
flags = CxxFlagsInfo(
|
||||||
|
|
|
@ -412,6 +412,7 @@ def _make_toolchain(version):
|
||||||
http_archive,
|
http_archive,
|
||||||
name = "gnumake_src",
|
name = "gnumake_src",
|
||||||
build_file_content = _ALL_CONTENT,
|
build_file_content = _ALL_CONTENT,
|
||||||
|
patches = ["@rules_foreign_cc//toolchains:make-reproducible-bootstrap.patch"],
|
||||||
sha256 = "e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19",
|
sha256 = "e05fdde47c5f7ca45cb697e973894ff4f5d79e13b750ed57d7b66d8defc78e19",
|
||||||
strip_prefix = "make-4.3",
|
strip_prefix = "make-4.3",
|
||||||
urls = [
|
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