Browse Source

Support building on FreeBSD (#2463)

It is less care-taking since GitHub Workflow is not configured
micttyl 3 years ago
parent
commit
63487da665

+ 10 - 0
WORKSPACE

@@ -156,6 +156,11 @@ rules_m4_version = "0.2.1"
 
 http_archive(
     name = "rules_m4",
+    patch_args = ["-p1"],
+    patches = [
+        # Trying to upstream: https://github.com/jmillikin/rules_m4/pull/15
+        "@carbon//bazel/patches/m4:0001_Support_M4_building_on_FreeBSD.patch",
+    ],
     sha256 = "eaa674cd84546038ecbcc49cdd346134a20961a41fa1a541e80d8bf4b470c34d",
     strip_prefix = "rules_m4-{0}".format(rules_m4_version),
     urls = ["https://github.com/jmillikin/rules_m4/archive/v{0}.tar.gz".format(rules_m4_version)],
@@ -190,6 +195,11 @@ rules_bison_version = "478079b28605a38000eaf83719568d756b3383a0"
 
 http_archive(
     name = "rules_bison",
+    patch_args = ["-p1"],
+    patches = [
+        # Trying to upstream: https://github.com/jmillikin/rules_bison/pull/13
+        "@carbon//bazel/patches/bison:0001_Support_Bison_building_on_FreeBSD.patch",
+    ],
     sha256 = "6bc2d382e4ffccd66e60a74521c24722fc8fdfe9af49ff182f79bb5994fa1ba4",
     strip_prefix = "rules_bison-{0}".format(rules_bison_version),
     urls = ["https://github.com/jmillikin/rules_bison/archive/{0}.tar.gz".format(rules_bison_version)],

+ 36 - 0
bazel/cc_toolchains/clang_cc_toolchain_config.bzl

@@ -600,6 +600,39 @@ def _impl(ctx):
         ],
     )
 
+    freebsd_flags_feature = feature(
+        name = "freebsd_flags",
+        enabled = True,
+        flag_sets = [
+            flag_set(
+                actions = [
+                    ACTION_NAMES.c_compile,
+                    ACTION_NAMES.cpp_compile,
+                    ACTION_NAMES.cpp_header_parsing,
+                    ACTION_NAMES.cpp_module_compile,
+                ],
+                flag_groups = [
+                    flag_group(
+                        flags = [
+                            "-DHAVE_MALLCTL",
+                        ],
+                    ),
+                ],
+            ),
+            flag_set(
+                actions = [
+                    ACTION_NAMES.cpp_link_executable,
+                ],
+                flag_groups = [
+                    flag_group(
+                        flags = ["-fpie"],
+                        expand_if_available = "force_pic",
+                    ),
+                ],
+            ),
+        ],
+    )
+
     default_link_libraries_feature = feature(
         name = "default_link_libraries",
         enabled = True,
@@ -837,6 +870,9 @@ def _impl(ctx):
     elif ctx.attr.target_cpu in ["darwin", "darwin_arm64"]:
         features += [macos_flags_feature]
         sysroot = sysroot_dir
+    elif ctx.attr.target_cpu == "freebsd":
+        features += [freebsd_flags_feature]
+        sysroot = sysroot_dir
     else:
         fail("Unsupported target platform!")
 

+ 13 - 0
bazel/cc_toolchains/clang_configuration.bzl

@@ -89,6 +89,17 @@ def _compute_mac_os_sysroot(repository_ctx):
     output = _run(repository_ctx, [xcrun, "--show-sdk-path"]).stdout
     return output.splitlines()[0]
 
+def _compute_bsd_sysroot(repository_ctx):
+    """Look around for sysroot. Return root (/) if nothing found."""
+
+    # Try it-just-works for CMake users.
+    default = "/"
+    sysroot = repository_ctx.os.environ.get("CMAKE_SYSROOT", default)
+    sysroot_path = repository_ctx.path(sysroot)
+    if sysroot_path.exists:
+        return sysroot_path.realpath
+    return default
+
 def _compute_clang_cpp_include_search_paths(repository_ctx, clang, sysroot):
     """Runs the `clang` binary and extracts the include search paths.
 
@@ -172,6 +183,8 @@ def _configure_clang_toolchain_impl(repository_ctx):
     sysroot_dir = None
     if repository_ctx.os.name.lower().startswith("mac os"):
         sysroot_dir = _compute_mac_os_sysroot(repository_ctx)
+    if repository_ctx.os.name == "freebsd":
+        sysroot_dir = _compute_bsd_sysroot(repository_ctx)
     include_dirs = _compute_clang_cpp_include_search_paths(
         repository_ctx,
         clang_cpp,

+ 21 - 0
bazel/cc_toolchains/clang_toolchain.BUILD

@@ -22,6 +22,7 @@ cc_toolchain_suite(
     toolchains = {
         "darwin": ":cc-compiler-darwin",
         "darwin_arm64": ":cc-compiler-darwin-arm64",
+        "freebsd": "cc-compiler-freebsd",
         "k8": ":cc-compiler-k8",
         "x64_windows": ":cc-compiler-x64-windows",
     },
@@ -87,6 +88,26 @@ cc_toolchain_config(
     target_cpu = "darwin_arm64",
 )
 
+cc_toolchain(
+    name = "cc-compiler-freebsd",
+    all_files = ":empty",
+    ar_files = ":empty",
+    as_files = ":empty",
+    compiler_files = ":empty",
+    dwp_files = ":empty",
+    linker_files = ":empty",
+    objcopy_files = ":empty",
+    strip_files = ":empty",
+    supports_param_files = 1,
+    toolchain_config = ":local-freebsd",
+    toolchain_identifier = "local-freebsd",
+)
+
+cc_toolchain_config(
+    name = "local-freebsd",
+    target_cpu = "freebsd",
+)
+
 cc_toolchain(
     name = "cc-compiler-x64-windows",
     all_files = ":empty",

+ 327 - 0
bazel/patches/bison/0001_Support_Bison_building_on_FreeBSD.patch

@@ -0,0 +1,327 @@
+From 491f7eda0033875ac26d8511b98e33189b0c389c Mon Sep 17 00:00:00 2001
+From: Luke Yoo <w.lukeyoo@gmail.com>
+Date: Tue, 13 Dec 2022 04:57:42 -0800
+Subject: [PATCH] Support Bison building on FreeBSD
+
+This is based on the OpenBSD support in `v0.2.1`
+For later versions, it may be supported without it
+---
+ bison/internal/gnulib/config-freebsd.h | 213 +++++++++++++++++++++++++
+ bison/internal/gnulib/gnulib.BUILD     |  11 ++
+ bison/internal/gnulib/gnulib.bzl       |  15 ++
+ bison/internal/repository.bzl          |   4 +
+ 4 files changed, 243 insertions(+)
+ create mode 100644 bison/internal/gnulib/config-freebsd.h
+
+diff --git a/bison/internal/gnulib/config-freebsd.h b/bison/internal/gnulib/config-freebsd.h
+new file mode 100644
+index 0000000..57df34f
+--- /dev/null
++++ b/bison/internal/gnulib/config-freebsd.h
+@@ -0,0 +1,213 @@
++{GNULIB_CONFIG_HEADER}
++
++#define _GL_ATTRIBUTE_FORMAT_PRINTF(x, y)
++
++#define O_BINARY 0
++#define O_TEXT 0
++
++extern char **environ;
++
++/******************************************************************************/
++
++#define CHECK_PRINTF_SAFE 1
++#define C_LOCALE_MAYBE_EILSEQ 1
++#define DBL_EXPBIT0_BIT 20
++#define DBL_EXPBIT0_WORD 1
++#define FLT_EXPBIT0_BIT 23
++#define FLT_EXPBIT0_WORD 0
++#define FUNC_REALPATH_WORKS 1
++#define GETTIMEOFDAY_TIMEZONE struct timezone
++#define GNULIB_CANONICALIZE_LGPL 1
++#define GNULIB_CLOSE_STREAM 1
++#define GNULIB_DIRNAME 1
++#define GNULIB_FD_SAFER_FLAG 1
++#define GNULIB_FOPEN_SAFER 1
++#define GNULIB_FSCANF 1
++#define GNULIB_LOCK 1
++#define GNULIB_MALLOC_GNU 1
++#define GNULIB_MSVC_NOTHROW 1
++#define GNULIB_PIPE2_SAFER 1
++#define GNULIB_SCANF 1
++#define GNULIB_SNPRINTF 1
++#define GNULIB_STRERROR 1
++#define GNULIB_STRERROR_R_POSIX 1
++#define HAVE_ALLOCA 0
++#define HAVE_CALLOC_POSIX 1
++#define HAVE_CANONICALIZE_FILE_NAME 1
++#define HAVE_CATGETS 1
++#define HAVE_CLOCK_GETTIME 1
++#define HAVE_CLOCK_SETTIME 1
++#define HAVE_DECL_ALARM 1
++#define HAVE_DECL_CLEARERR_UNLOCKED 0
++#define HAVE_DECL_FEOF_UNLOCKED 0
++#define HAVE_DECL_FERROR_UNLOCKED 0
++#define HAVE_DECL_FFLUSH_UNLOCKED 0
++#define HAVE_DECL_FGETS_UNLOCKED 1
++#define HAVE_DECL_FPUTC_UNLOCKED 0
++#define HAVE_DECL_FPUTS_UNLOCKED 0
++#define HAVE_DECL_FREAD_UNLOCKED 0
++#define HAVE_DECL_FWRITE_UNLOCKED 0
++#define HAVE_DECL_GETCHAR_UNLOCKED 1
++#define HAVE_DECL_GETC_UNLOCKED 1
++#define HAVE_DECL_GETDTABLESIZE 1
++#define HAVE_DECL_GETHRTIME 0
++#define HAVE_DECL_MBSWIDTH_IN_WCHAR_H 0
++#define HAVE_DECL_OBSTACK_PRINTF 1
++#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0
++#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 0
++#define HAVE_DECL_PUTCHAR_UNLOCKED 1
++#define HAVE_DECL_PUTC_UNLOCKED 1
++#define HAVE_DECL_SETENV 1
++#define HAVE_DECL_SNPRINTF 1
++#define HAVE_DECL_STRDUP 1
++#define HAVE_DECL_STRERROR_R 1
++#define HAVE_DECL_STRNDUP 1
++#define HAVE_DECL_STRNLEN 1
++#define HAVE_DECL_UNSETENV 1
++#define HAVE_DECL_VSNPRINTF 1
++#define HAVE_DECL_WCWIDTH 1
++#define HAVE_DECL__SNPRINTF 0
++#define HAVE_DECL___ARGV 0
++#define HAVE_DUP2 1
++#define HAVE_ENVIRON_DECL 1
++#define HAVE_FCNTL 1
++#define HAVE_FREXPL_IN_LIBC 1
++#define HAVE_FREXP_IN_LIBC 1
++#define HAVE_GETCWD 1
++#define HAVE_GETDTABLESIZE 1
++#define HAVE_GETOPT_H 1
++#define HAVE_GETOPT_LONG_ONLY 1
++#define HAVE_GETRUSAGE 1
++#define HAVE_GETTIMEOFDAY 1
++#define HAVE_INTMAX_T 1
++#define HAVE_INTTYPES_H 1
++#define HAVE_INTTYPES_H_WITH_UINTMAX 1
++#define HAVE_ISASCII 1
++#define HAVE_ISNAND_IN_LIBC 1
++#define HAVE_ISNANF_IN_LIBC 1
++#define HAVE_ISNANL_IN_LIBC 1
++#define HAVE_ISWCNTRL 1
++#define HAVE_LANGINFO_CODESET 1
++#define HAVE_LDEXPL 1
++#define HAVE_LDEXPL_IN_LIBC 1
++#define HAVE_LDEXP_IN_LIBC 1
++#define HAVE_LIMITS_H 1
++#define HAVE_LINK 1
++#define HAVE_LONG_LONG_INT 1
++#define HAVE_LSTAT 1
++#define HAVE_MALLOC_GNU 1
++#define HAVE_MALLOC_POSIX 1
++#define HAVE_MAP_ANONYMOUS 1
++#define HAVE_MATH_H 1
++#define HAVE_MBRTOWC 1
++#define HAVE_MBSINIT 1
++#define HAVE_MBSTATE_T 1
++#define HAVE_MEMORY_H 1
++#define HAVE_MINMAX_IN_SYS_PARAM_H 1
++#define HAVE_MPROTECT 1
++#define HAVE_OBSTACK_PRINTF 1
++#define HAVE_PIPE 1
++#define HAVE_PIPE2 1
++#define HAVE_POSIX_SPAWN 1
++#define HAVE_POSIX_SPAWNATTR_T 1
++#define HAVE_POSIX_SPAWN_FILE_ACTIONS_T 1
++#define HAVE_PTHREAD_MUTEX_RECURSIVE 1
++#define HAVE_PTHREAD_RWLOCK 1
++#define HAVE_RAISE 1
++#define HAVE_RAWMEMCHR 1
++#define HAVE_READLINK 1
++#define HAVE_READLINKAT 1
++#define HAVE_REALLOC_POSIX 1
++#define HAVE_REALPATH 1
++#define HAVE_SEARCH_H 1
++#define HAVE_SETENV 1
++#define HAVE_SIGACTION 1
++#define HAVE_SIGALTSTACK 1
++#define HAVE_SIGINTERRUPT 1
++#define HAVE_SIGSET_T 1
++#define HAVE_SIG_ATOMIC_T 1
++#define HAVE_SNPRINTF 0
++#define HAVE_SNPRINTF_RETVAL_C99 1
++#define HAVE_SPAWN_H 1
++#define HAVE_STDINT_H 1
++#define HAVE_STDINT_H_WITH_UINTMAX 1
++#define HAVE_STDLIB_H 1
++#define HAVE_STPCPY 1
++#define HAVE_STRCHRNUL 1
++#define HAVE_STRDUP 1
++#define HAVE_STRERROR_R 1
++#define HAVE_STRINGS_H 1
++#define HAVE_STRING_H 1
++#define HAVE_STRNDUP 1
++#define HAVE_STRNLEN 1
++#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1
++#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1
++#define HAVE_STRUCT_TMS 1
++#define HAVE_STRVERSCMP 1
++#define HAVE_SYMLINK 1
++#define HAVE_SYS_CDEFS_H 1
++#define HAVE_SYS_MMAN_H 1
++#define HAVE_SYS_PARAM_H 1
++#define HAVE_SYS_RESOURCE_H 1
++#define HAVE_SYS_SOCKET_H 1
++#define HAVE_SYS_STAT_H 1
++#define HAVE_SYS_TIMES_H 1
++#define HAVE_SYS_TIME_H 1
++#define HAVE_SYS_TYPES_H 1
++#define HAVE_SYS_WAIT_H 1
++#define HAVE_TOWLOWER 1
++#define HAVE_TSEARCH 1
++#define HAVE_UNISTD_H 1
++#define HAVE_UNSETENV 1
++#define HAVE_UNSIGNED_LONG_LONG_INT 1
++#define HAVE_VAR___PROGNAME 1
++#define HAVE_VSNPRINTF 1
++#define HAVE_WAITID 1
++#define HAVE_WCHAR_H 1
++#define HAVE_WCHAR_T 1
++#define HAVE_WCRTOMB 1
++#define HAVE_WCSLEN 1
++#define HAVE_WCSNLEN 1
++#define HAVE_WCTYPE_H 1
++#define HAVE_WCWIDTH 1
++#define HAVE_WINT_T 1
++#define HAVE_WORKING_O_NOATIME 0
++#define HAVE_WORKING_O_NOFOLLOW 1
++#define HAVE__BOOL 1
++#define HAVE___XPG_STRERROR_R 1
++#define INSTALLPREFIX "/usr/local"
++#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
++#define MALLOC_0_IS_NONNULL 1
++# define __USE_MINGW_ANSI_STDIO 1
++#define PROMOTED_MODE_T mode_t
++#define REPLACE_FPRINTF_POSIX 1
++#define REPLACE_PRINTF_POSIX 1
++#define REPLACE_VFPRINTF_POSIX 1
++#define STDC_HEADERS 1
++#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1
++#define USER_LABEL_PREFIX
++#define USE_POSIX_THREADS 1
++#define USE_POSIX_THREADS_WEAK 1
++# define _ALL_SOURCE 1
++# define _DARWIN_C_SOURCE 1
++# define _GNU_SOURCE 1
++# define _NETBSD_SOURCE 1
++# define _OPENBSD_SOURCE 1
++# define _POSIX_PTHREAD_SEMANTICS 1
++# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
++# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
++# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
++# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
++# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
++# define __STDC_WANT_LIB_EXT2__ 1
++# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
++# define _TANDEM_SOURCE 1
++# define _HPUX_ALT_XOPEN_SOCKET_API 1
++# define __EXTENSIONS__ 1
++#define USE_UNLOCKED_IO 0
++#define _DARWIN_USE_64_BIT_INODE 1
++#define _NETBSD_SOURCE 1
++#define _USE_STD_STAT 1
++#define restrict __restrict
++
++{GNULIB_CONFIG_FOOTER}
+diff --git a/bison/internal/gnulib/gnulib.BUILD b/bison/internal/gnulib/gnulib.BUILD
+index e23b2b8..69d969b 100644
+--- a/bison/internal/gnulib/gnulib.BUILD
++++ b/bison/internal/gnulib/gnulib.BUILD
+@@ -19,6 +19,7 @@ cc_library(
+     hdrs = select({
+         "@bazel_tools//src/conditions:darwin": glob(["config-darwin/*.h"]),
+         "@bazel_tools//src/conditions:windows": glob(["config-windows/*.h"]),
++        "@bazel_tools//src/conditions:freebsd": glob(["config-freebsd/*.h"]),
+         "//conditions:default": glob(["config-linux/*.h"]),
+     }),
+     includes = select({
+@@ -28,6 +29,9 @@ cc_library(
+         "@bazel_tools//src/conditions:windows": [
+             "config-windows",
+         ],
++        "@bazel_tools//src/conditions:freebsd": [
++            "config-freebsd",
++        ],
+         "//conditions:default": [
+             "config-linux",
+         ],
+@@ -42,6 +46,12 @@ cc_library(
+     deps = [":config_h"],
+ )
+ 
++cc_library(
++    name = "maybe_alloca_h",
++    hdrs = ["maybe-alloca/alloca.h"],
++    includes = ["maybe-alloca"],
++)
++
+ _GNULIB_HDRS = glob([
+     "lib/*.h",
+     "lib/bitset/*.h",
+@@ -192,6 +202,7 @@ cc_library(
+         "//:timevar_def",
+     ] + select({
+         "@bazel_tools//src/conditions:windows": [":gnulib_windows_shims"],
++        "@bazel_tools//src/conditions:freebsd": [":maybe_alloca_h"],
+         "//conditions:default": [],
+     }),
+ )
+diff --git a/bison/internal/gnulib/gnulib.bzl b/bison/internal/gnulib/gnulib.bzl
+index 159ee4c..2038f4d 100644
+--- a/bison/internal/gnulib/gnulib.bzl
++++ b/bison/internal/gnulib/gnulib.bzl
+@@ -83,6 +83,7 @@ def gnulib_overlay(ctx, bison_version, extra_copts = []):
+         ("darwin", ctx.attr._gnulib_config_darwin_h),
+         ("linux", ctx.attr._gnulib_config_linux_h),
+         ("windows", ctx.attr._gnulib_config_windows_h),
++        ("freebsd", ctx.attr._gnulib_config_freebsd_h),
+     ]:
+         config_prefix = "gnulib/config-{}/".format(os)
+ 
+@@ -148,6 +149,20 @@ def gnulib_overlay(ctx, bison_version, extra_copts = []):
+         "(const char **) environ": "NULL",
+     }, executable = False)
+ 
++    # Some platforms have alloca() but in <stdlib.h>
++    ctx.file(
++        "gnulib/maybe-alloca/alloca.h",
++        content =
++            """
++    #if defined(__GLIBC__)
++    #include_next <alloca.h>
++    #else
++    #include <stdlib.h>
++    #endif
++    """,
++        executable = False,
++    )
++
+ _WINDOWS_STDLIB_SHIMS = [
+     "alloca",
+     "errno",
+diff --git a/bison/internal/repository.bzl b/bison/internal/repository.bzl
+index 7e17763..934e8c9 100644
+--- a/bison/internal/repository.bzl
++++ b/bison/internal/repository.bzl
+@@ -133,5 +133,9 @@ bison_repository = repository_rule(
+             default = "//bison/internal:gnulib/config-windows.h",
+             allow_single_file = True,
+         ),
++        "_gnulib_config_freebsd_h": attr.label(
++            default = "//bison/internal:gnulib/config-freebsd.h",
++            allow_single_file = True,
++        ),
+     },
+ )
+-- 
+2.38.1
+

+ 9 - 0
bazel/patches/bison/BUILD

@@ -0,0 +1,9 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+package(default_visibility = ["//visibility:public"])
+
+exports_files(glob([
+    "*.patch",
+]))

+ 351 - 0
bazel/patches/m4/0001_Support_M4_building_on_FreeBSD.patch

@@ -0,0 +1,351 @@
+From c07d3368b31e587db7a73352c4fa3c25f0e488b7 Mon Sep 17 00:00:00 2001
+From: Luke Yoo <w.lukeyoo@gmail.com>
+Date: Tue, 13 Dec 2022 04:48:39 -0800
+Subject: [PATCH] Support M4 building on FreeBSD
+
+This is based on the OpenBSD support in `v0.2.2`
+For later versions, it may be supported without it
+---
+ m4/internal/gnulib/config-freebsd.h | 232 ++++++++++++++++++++++++++++
+ m4/internal/gnulib/gnulib.BUILD     |  13 ++
+ m4/internal/gnulib/gnulib.bzl       |  18 +++
+ m4/internal/repository.bzl          |   4 +
+ 4 files changed, 267 insertions(+)
+ create mode 100644 m4/internal/gnulib/config-freebsd.h
+
+diff --git a/m4/internal/gnulib/config-freebsd.h b/m4/internal/gnulib/config-freebsd.h
+new file mode 100644
+index 0000000..639748e
+--- /dev/null
++++ b/m4/internal/gnulib/config-freebsd.h
+@@ -0,0 +1,232 @@
++{GNULIB_CONFIG_HEADER}
++
++#define _GL_ATTRIBUTE_FORMAT_PRINTF(x, y)
++
++#define O_BINARY 0
++#define O_TEXT 0
++
++extern char **environ;
++
++/******************************************************************************/
++
++#define CHECK_PRINTF_SAFE 1
++#define C_LOCALE_MAYBE_EILSEQ 1
++#define DBL_EXPBIT0_BIT 20
++#define DBL_EXPBIT0_WORD 1
++#define FAULT_YIELDS_SIGBUS 0
++#define FLT_EXPBIT0_BIT 23
++#define FLT_EXPBIT0_WORD 0
++#define FUNC_FFLUSH_STDIN 0
++#define FUNC_NL_LANGINFO_YESEXPR_WORKS 1
++#define FUNC_REALPATH_WORKS 1
++#define GETTIMEOFDAY_TIMEZONE struct timezone
++#define GNULIB_CANONICALIZE_LGPL 1
++#define GNULIB_CLOSE_STREAM 1
++#define GNULIB_DIRNAME 1
++#define GNULIB_FD_SAFER_FLAG 1
++#define GNULIB_FFLUSH 1
++#define GNULIB_FILENAMECAT 1
++#define GNULIB_FOPEN_SAFER 1
++#define GNULIB_FSCANF 1
++#define GNULIB_LOCK 1
++#define GNULIB_MSVC_NOTHROW 1
++#define GNULIB_PIPE2_SAFER 1
++#define GNULIB_SCANF 1
++#define GNULIB_SIGPIPE 1
++#define GNULIB_SNPRINTF 1
++#define GNULIB_STRERROR 1
++#define HAVE_ALLOCA 0
++#define HAVE_BTOWC 1
++#define HAVE_CANONICALIZE_FILE_NAME 1
++#define HAVE_DECL_ALARM 1
++#define HAVE_DECL_CLEARERR_UNLOCKED 0
++#define HAVE_DECL_FEOF_UNLOCKED 0
++#define HAVE_DECL_FERROR_UNLOCKED 1
++#define HAVE_DECL_FFLUSH_UNLOCKED 1
++#define HAVE_DECL_FGETS_UNLOCKED 1
++#define HAVE_DECL_FPURGE 0
++#define HAVE_DECL_FPUTC_UNLOCKED 0
++#define HAVE_DECL_FPUTS_UNLOCKED 0
++#define HAVE_DECL_FREAD_UNLOCKED 0
++#define HAVE_DECL_FSEEKO 1
++#define HAVE_DECL_FTELLO 1
++#define HAVE_DECL_FWRITE_UNLOCKED 0
++#define HAVE_DECL_GETCHAR_UNLOCKED 1
++#define HAVE_DECL_GETC_UNLOCKED 1
++#define HAVE_DECL_GETDTABLESIZE 1
++#define HAVE_DECL_ISBLANK 1
++#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0
++#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 0
++#define HAVE_DECL_PUTCHAR_UNLOCKED 1
++#define HAVE_DECL_PUTC_UNLOCKED 1
++#define HAVE_DECL_SIGALTSTACK 1
++#define HAVE_DECL_SNPRINTF 1
++#define HAVE_DECL_STRERROR_R 1
++#define HAVE_DECL_STRNDUP 1
++#define HAVE_DECL_STRNLEN 1
++#define HAVE_DECL_STRSIGNAL 1
++#define HAVE_DECL_SYS_SIGLIST 1
++#define HAVE_DECL__SNPRINTF 0
++#define HAVE_DECL___ARGV 0
++#define HAVE_DUP2 1
++#define HAVE_ENVIRON_DECL 1
++#define HAVE_FCNTL 1
++#define HAVE_FREXPL_IN_LIBC 1
++#define HAVE_FREXP_IN_LIBC 1
++#define HAVE_FSEEKO 1
++#define HAVE_GETCWD 1
++#define HAVE_GETDTABLESIZE 1
++#define HAVE_GETEGID 1
++#define HAVE_GETEUID 1
++#define HAVE_GETGID 1
++#define HAVE_GETOPT_H 1
++#define HAVE_GETOPT_LONG_ONLY 1
++#define HAVE_GETTIMEOFDAY 1
++#define HAVE_GETUID 1
++#define HAVE_INTMAX_T 1
++#define HAVE_INTTYPES_H 1
++#define HAVE_INTTYPES_H_WITH_UINTMAX 1
++#define HAVE_ISBLANK 1
++#define HAVE_ISNAND_IN_LIBC 1
++#define HAVE_ISNANF_IN_LIBC 1
++#define HAVE_ISNANL_IN_LIBC 1
++#define HAVE_ISWCNTRL 1
++#define HAVE_ISWCTYPE 1
++#define HAVE_LANGINFO_CODESET 1
++#define HAVE_LANGINFO_H 1
++#define HAVE_LDEXPL_IN_LIBC 1
++#define HAVE_LDEXP_IN_LIBC 1
++#define HAVE_LIBINTL_H 1
++#define HAVE_LIMITS_H 1
++#define HAVE_LINK 1
++#define HAVE_LONG_LONG_INT 1
++#define HAVE_LSTAT 1
++#define HAVE_MALLOC_H 1
++#define HAVE_MALLOC_POSIX 1
++#define HAVE_MAP_ANONYMOUS 1
++#define HAVE_MATH_H 1
++#define HAVE_MBRTOWC 1
++#define HAVE_MBSINIT 1
++#define HAVE_MBSTATE_T 1
++#define HAVE_MBTOWC 1
++#define HAVE_MEMORY_H 1
++#define HAVE_MINMAX_IN_SYS_PARAM_H 1
++#define HAVE_MKDTEMP 1
++#define HAVE_MKSTEMP 1
++#define HAVE_MPROTECT 1
++#define HAVE_NL_LANGINFO 1
++#define HAVE_PIPE 1
++#define HAVE_PIPE2 1
++#define HAVE_POSIX_SPAWN 1
++#define HAVE_POSIX_SPAWNATTR_T 1
++#define HAVE_POSIX_SPAWN_FILE_ACTIONS_T 1
++#define HAVE_PTHREAD_MUTEX_RECURSIVE 1
++#define HAVE_PTHREAD_RWLOCK 1
++#define HAVE_RAISE 1
++#define HAVE_RAWMEMCHR 1
++#define HAVE_READLINK 1
++#define HAVE_REALPATH 1
++#define HAVE_SECURE_GETENV 1
++#define HAVE_SETRLIMIT 1
++#define HAVE_SIGACTION 1
++#define HAVE_SIGALTSTACK 1
++#define HAVE_SIGINTERRUPT 1
++#define HAVE_SIGSET_T 1
++#define HAVE_SIG_ATOMIC_T 1
++#define HAVE_SNPRINTF 0
++#define HAVE_SNPRINTF_RETVAL_C99 1
++#define HAVE_SPAWN_H 1
++#define HAVE_STACK_OVERFLOW_HANDLING 1
++#define HAVE_STACK_T 1
++#define HAVE_STDINT_H 1
++#define HAVE_STDINT_H_WITH_UINTMAX 1
++#define HAVE_STDLIB_H 1
++#define HAVE_STRCHRNUL 1
++#define HAVE_STRERROR_R 1
++#define HAVE_STRINGS_H 1
++#define HAVE_STRING_H 1
++#define HAVE_STRNDUP 1
++#define HAVE_STRNLEN 1
++#define HAVE_STRSIGNAL 1
++#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1
++#define HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 1
++#define HAVE_SYMLINK 1
++#define HAVE_SYS_CDEFS_H 1
++#define HAVE_SYS_MMAN_H 1
++#define HAVE_SYS_PARAM_H 1
++#define HAVE_SYS_SOCKET_H 1
++#define HAVE_SYS_STAT_H 1
++#define HAVE_SYS_TIME_H 1
++#define HAVE_SYS_TYPES_H 1
++#define HAVE_SYS_WAIT_H 1
++#define HAVE_TOWLOWER 1
++#define HAVE_UCONTEXT_H 0
++#define HAVE_UNISTD_H 1
++#define HAVE_UNSIGNED_LONG_LONG_INT 1
++#define HAVE_VAR___PROGNAME 1
++#define HAVE_VASPRINTF 1
++#define HAVE_WAITID 1
++#define HAVE_WCHAR_H 1
++#define HAVE_WCHAR_T 1
++#define HAVE_WCRTOMB 1
++#define HAVE_WCSLEN 1
++#define HAVE_WCSNLEN 1
++#define HAVE_WCTYPE_H 1
++#define HAVE_WINT_T 1
++#define HAVE_WORKING_O_NOATIME 0
++#define HAVE_WORKING_O_NOFOLLOW 1
++#define HAVE__BOOL 1
++#define HAVE___BUILTIN_EXPECT 1
++#define HAVE___FPURGE 1
++#define HAVE___FREADING 1
++#define HAVE___INLINE 1
++#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
++#define MALLOC_0_IS_NONNULL 1
++# define __USE_MINGW_ANSI_STDIO 1
++#define PROMOTED_MODE_T mode_t
++#define SIGNAL_SAFE_LIST 1
++#define STDC_HEADERS 1
++#define TYPEOF_STRUCT_STAT_ST_ATIM_IS_STRUCT_TIMESPEC 1
++#define USER_LABEL_PREFIX
++#define USE_POSIX_THREADS 1
++#define USE_POSIX_THREADS_WEAK 1
++# define _ALL_SOURCE 1
++# define _DARWIN_C_SOURCE 1
++# define _GNU_SOURCE 1
++# define _NETBSD_SOURCE 1
++# define _OPENBSD_SOURCE 1
++# define _POSIX_PTHREAD_SEMANTICS 1
++# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
++# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
++# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
++# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
++# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
++# define __STDC_WANT_LIB_EXT2__ 1
++# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
++# define _TANDEM_SOURCE 1
++# define _HPUX_ALT_XOPEN_SOCKET_API 1
++# define __EXTENSIONS__ 1
++#define USE_UNLOCKED_IO 0
++#define _DARWIN_USE_64_BIT_INODE 1
++#define _NETBSD_SOURCE 1
++#define _REGEX_INCLUDE_LIMITS_H 1
++#define _REGEX_LARGE_OFFSETS 1
++#define _USE_STD_STAT 1
++#define re_comp rpl_re_comp
++#define re_compile_fastmap rpl_re_compile_fastmap
++#define re_compile_pattern rpl_re_compile_pattern
++#define re_exec rpl_re_exec
++#define re_match rpl_re_match
++#define re_match_2 rpl_re_match_2
++#define re_search rpl_re_search
++#define re_search_2 rpl_re_search_2
++#define re_set_registers rpl_re_set_registers
++#define re_set_syntax rpl_re_set_syntax
++#define re_syntax_options rpl_re_syntax_options
++#define regcomp rpl_regcomp
++#define regerror rpl_regerror
++#define regexec rpl_regexec
++#define regfree rpl_regfree
++#define restrict __restrict
++
++{GNULIB_CONFIG_FOOTER}
+diff --git a/m4/internal/gnulib/gnulib.BUILD b/m4/internal/gnulib/gnulib.BUILD
+index b3d3e1c..16bdb8f 100644
+--- a/m4/internal/gnulib/gnulib.BUILD
++++ b/m4/internal/gnulib/gnulib.BUILD
+@@ -23,6 +23,9 @@ cc_library(
+         "@bazel_tools//src/conditions:windows": [
+             "config-windows/config.h",
+         ],
++        "@bazel_tools//src/conditions:freebsd": [
++            "config-freebsd/config.h",
++        ],
+         "//conditions:default": [
+             "config-linux/config.h",
+         ],
+@@ -34,6 +37,9 @@ cc_library(
+         "@bazel_tools//src/conditions:windows": [
+             "config-windows",
+         ],
++        "@bazel_tools//src/conditions:freebsd": [
++            "config-freebsd",
++        ],
+         "//conditions:default": [
+             "config-linux",
+         ],
+@@ -48,6 +54,12 @@ cc_library(
+     deps = [":config_h"],
+ )
+ 
++cc_library(
++    name = "maybe_alloca_h",
++    hdrs = ["maybe-alloca/alloca.h"],
++    includes = ["maybe-alloca"],
++)
++
+ _GNULIB_HDRS = glob([
+     "lib/*.h",
+     "lib/glthread/*.h",
+@@ -215,6 +227,7 @@ cc_library(
+     visibility = ["//:__pkg__"],
+     deps = [":config_h"] + select({
+         "@bazel_tools//src/conditions:windows": [":gnulib_windows_shims"],
++        "@bazel_tools//src/conditions:freebsd": [":maybe_alloca_h"],
+         "//conditions:default": [],
+     }),
+ )
+diff --git a/m4/internal/gnulib/gnulib.bzl b/m4/internal/gnulib/gnulib.bzl
+index 85d19d9..10aa0a0 100644
+--- a/m4/internal/gnulib/gnulib.bzl
++++ b/m4/internal/gnulib/gnulib.bzl
+@@ -97,6 +97,10 @@ def gnulib_overlay(ctx, m4_version, extra_copts = []):
+         "{GNULIB_CONFIG_HEADER}": config_header,
+         "{GNULIB_CONFIG_FOOTER}": _CONFIG_FOOTER,
+     }, executable = False)
++    ctx.template("gnulib/config-freebsd/config.h", ctx.attr._gnulib_config_freebsd_h, substitutions = {
++        "{GNULIB_CONFIG_HEADER}": config_header,
++        "{GNULIB_CONFIG_FOOTER}": _CONFIG_FOOTER,
++    }, executable = False)
+ 
+     for shim in _WINDOWS_STDLIB_SHIMS:
+         in_h = "gnulib/lib/{}.in.h".format(shim.replace("/", "_"))
+@@ -145,6 +149,20 @@ static const char * _replaced_get_charset_aliases (void)
+         "SIGSTKSZ": "GNULIB_SIGSTKSZ",
+     })
+ 
++    # Some platforms have alloca() but in <stdlib.h>
++    ctx.file(
++        "gnulib/maybe-alloca/alloca.h",
++        content =
++            """
++    #if defined(__GLIBC__)
++    #include_next <alloca.h>
++    #else
++    #include <stdlib.h>
++    #endif
++    """,
++        executable = False,
++    )
++
+ _WINDOWS_STDLIB_SHIMS = [
+     "alloca",
+     "errno",
+diff --git a/m4/internal/repository.bzl b/m4/internal/repository.bzl
+index c668d8c..3a8363f 100644
+--- a/m4/internal/repository.bzl
++++ b/m4/internal/repository.bzl
+@@ -146,5 +146,9 @@ m4_repository = repository_rule(
+             default = "//m4/internal:gnulib/config-windows.h",
+             allow_single_file = True,
+         ),
++        "_gnulib_config_freebsd_h": attr.label(
++            default = "//m4/internal:gnulib/config-freebsd.h",
++            allow_single_file = True,
++        ),
+     },
+ )
+-- 
+2.38.1
+

+ 9 - 0
bazel/patches/m4/BUILD

@@ -0,0 +1,9 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+package(default_visibility = ["//visibility:public"])
+
+exports_files(glob([
+    "*.patch",
+]))