Adds toolchain for freebsd. (#794)

* Adds toolchain for freebsd.

* Address buildifier lint warnings.

* Use /usr/bin/env bash

* Leave the Linux-specific shebang alone.

* Adds note about Bazel CI issue requesting for FreeBSD support and experimental status.

* Fix typo.

* Clean up trailing whitespace.

* Updates bazel-skylib version for tests to pass on FreeBSD.

* Update foreign_cc/repositories.bzl

Co-authored-by: UebelAndre <github@uebelandre.com>
This commit is contained in:
Yesudeep Mangalapilly 2021-11-29 02:54:06 -08:00 committed by GitHub
parent f61ce5d10b
commit a2f1e5d8c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 375 additions and 14 deletions

View File

@ -4,7 +4,7 @@ index a5a37ac..e381ce8 100644
+++ b/docs/BUILD.bazel
@@ -35,7 +35,7 @@ genrule(
cmd = """cat << EOF > $@
#!/bin/bash
#!/usr/bin/env bash
set -e
-cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/README.md
+cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/src/index.md

View File

@ -4,7 +4,7 @@ index a5a37ac..091e679 100644
+++ b/docs/BUILD.bazel
@@ -35,7 +35,7 @@ genrule(
cmd = """cat << EOF > $@
#!/bin/bash
#!/usr/bin/env bash
set -e
-cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/README.md
+cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/src/index.md

View File

@ -10,7 +10,7 @@ index 461df15..efa4c26 100644
+ srcs = DOCS_TARGETS + ["index.md"],
outs = ["generate_docs.sh"],
cmd = """cat << EOF > $@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail
-cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:flatten_docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/flatten.md
-cat \\$${BUILD_WORKSPACE_DIRECTORY}/$(location //:cmake_docs) > \\$${BUILD_WORKSPACE_DIRECTORY}/cmake.md

View File

@ -30,3 +30,10 @@ For more generalized updates, please see [NEWS.md](./NEWS.md) or checkout the
[ccb]: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_binary
[ccl]: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_library
[cct]: https://docs.bazel.build/versions/master/be/c-cpp.html#cc_toolchain
## Caveats
* FreeBSD support is currently experimental and on a best-effort basis.
Google currently doesn't have a CI test environment for FreeBSD,
but please make your voice heard by upvoting this
[issue](https://github.com/bazelbuild/continuous-integration/issues/258).

View File

@ -92,7 +92,7 @@ export COMMIT="$$(cat bazel-out/stable-status.txt | grep STABLE_SCM_VERSION | cu
export SHORT_COMMIT="$$(cat bazel-out/stable-status.txt | grep STABLE_SCM_SHORT_VERSION | cut -d' ' -f2)"
export RELEASE="$$(cat bazel-out/stable-status.txt | grep STABLE_RELEASE | cut -d' ' -f2)"
cat << EOF > $@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail
short_commit="$${SHORT_COMMIT}"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -euo pipefail

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
echo "# simple" > Makefile
echo "CC = ${CC}" > Makefile

View File

@ -1,4 +1,7 @@
#!/bin/bash -eu
#!/usr/bin/env bash
set -o errexit
set -o nounset
if [[ $(uname) == *"NT"* ]]; then
# If Windows

View File

@ -1,4 +1,7 @@
#!/bin/bash -eu
#!/usr/bin/env bash
set -o errexit
set -o nounset
if [[ $(uname) == *"NT"* ]]; then
# If Windows

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
if [[ ! -e "$GN" ]]; then
echo "gn does not exist"

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
if [[ "$OSTYPE" == "win32" ]]; then
python.exe build/gen.py --no-last-commit-position

View File

@ -0,0 +1,263 @@
"""Define default foreign_cc framework commands.
FreeBSD doesn't use bash by default but users can install it
using:
$ sudo pkg install bash
Also, Bash is one of the prerequisites for Bazel:
https://docs.bazel.build/versions/main/install-compile-source.html#bootstrap-unix-prereq
"""
load(":commands.bzl", "FunctionAndCallInfo")
def shebang():
return "#!/usr/bin/env bash"
def script_extension():
return ".sh"
def pwd():
return "$(pwd)"
def echo(text):
return "echo \"{text}\"".format(text = text)
def export_var(name, value):
return "export {name}={value}".format(name = name, value = value)
def local_var(name, value):
return "local {name}={value}".format(name = name, value = value)
def use_var(name):
return "$" + name
def env():
return "env"
def path(expression):
return "export PATH=\"{expression}:$PATH\"".format(expression = expression)
def touch(path):
return "touch " + path
def enable_tracing():
return "set -x"
def disable_tracing():
return "set +x"
def mkdirs(path):
return "mkdir -p " + path
def rm_rf(path):
return "rm -rf " + path
def if_else(condition, if_text, else_text):
return """\
if [ {condition} ]; then
{if_text}
else
{else_text}
fi
""".format(condition = condition, if_text = if_text, else_text = else_text)
# buildifier: disable=function-docstring
def define_function(name, text):
lines = []
lines.append("function " + name + "() {")
for line_ in text.splitlines():
lines.append(" " + line_)
lines.append("}")
return "\n".join(lines)
def replace_in_files(dir, from_, to_):
return FunctionAndCallInfo(
text = """\
if [ -d "$1" ]; then
SAVEIFS=$IFS
IFS=$'\n'
# Find all real files. Symlinks are assumed to be relative to something within the directory we're seaching and thus ignored
local files=$(find -P -f $1 \\( -type f -and \\( -name "*.pc" -or -name "*.la" -or -name "*-config" -or -name "*.mk" -or -name "*.cmake" \\) \\))
IFS=$SAVEIFS
for file in ${files[@]}; do
local backup=$(mktemp)
touch -r "${file}" "${backup}"
sed -i '' -e 's@'"$2"'@'"$3"'@g' "${file}"
if [[ "$?" -ne "0" ]]; then
exit 1
fi
touch -r "${backup}" "${file}"
rm "${backup}"
done
fi
""",
)
def copy_dir_contents_to_dir(source, target):
# Beause FreeBSD `cp` doesn't have `--no-copy-directory`, we have to
# do something more complex for this environment.
return """\
if [[ -d "{source}" ]]; then
cp -L -R "{source}"/* "{target}"
else
cp -L -R "{source}" "{target}"
fi
find {target} -type f -exec touch -r "{source}" "{{}}" \\;
""".format(
source = source,
target = target,
)
def symlink_contents_to_dir(source, target):
text = """\
if [[ -z "$1" ]]; then
echo "arg 1 to symlink_contents_to_dir is unexpectedly empty"
exit 1
fi
if [[ -z "$2" ]]; then
echo "arg 2 to symlink_contents_to_dir is unexpectedly empty"
exit 1
fi
local target="$2"
mkdir -p "$target"
if [[ -f "$1" ]]; then
##symlink_to_dir## "$1" "$target"
elif [[ -L "$1" && ! -d "$1" ]]; then
local actual=$(readlink "$1")
##symlink_contents_to_dir## "$actual" "$target"
elif [[ -d "$1" ]]; then
SAVEIFS=$IFS
IFS=$'\n'
local children=($(find "$1/" -maxdepth 1 -mindepth 1))
IFS=$SAVEIFS
for child in "${children[@]:-}"; do
##symlink_to_dir## "$child" "$target"
done
fi
"""
return FunctionAndCallInfo(text = text)
def symlink_to_dir(source, target):
text = """\
if [[ -z "$1" ]]; then
echo "arg 1 to symlink_to_dir is unexpectedly empty"
exit 1
fi
if [[ -z "$2" ]]; then
echo "arg 2 to symlink_to_dir is unexpectedly empty"
exit 1
fi
local target="$2"
mkdir -p "$target"
if [[ -f "$1" ]]; then
# In order to be able to use `replace_in_files`, we ensure that we create copies of specfieid
# files so updating them is possible.
if [[ "$1" == *.pc || "$1" == *.la || "$1" == *-config || "$1" == *.mk || "$1" == *.cmake ]]; then
dest="$target/$(basename $1)"
cp "$1" "$dest" && chmod +w "$dest" && touch -r "$1" "$dest"
else
ln -s -f "$1" "$target"
fi
elif [[ -L "$1" && ! -d "$1" ]]; then
cp -pR "$1" "$2"
elif [[ -d "$1" ]]; then
SAVEIFS=$IFS
IFS=$'\n'
local children=($(find "$1/" -maxdepth 1 -mindepth 1))
IFS=$SAVEIFS
local dirname=$(basename "$1")
mkdir -p "$target/$dirname"
for child in "${children[@]:-}"; do
if [[ -n "$child" && "$dirname" != *.ext_build_deps ]]; then
##symlink_to_dir## "$child" "$target/$dirname"
fi
done
else
echo "Can not copy $1"
fi
"""
return FunctionAndCallInfo(text = text)
def script_prelude():
return "set -euo pipefail"
def increment_pkg_config_path(source):
text = """\
local children=$(find "$1/" -mindepth 1 -name '*.pc')
# assume there is only one directory with pkg config
for child in $children; do
export PKG_CONFIG_PATH="$${PKG_CONFIG_PATH:-}$$:$(dirname $child)"
return
done
"""
return FunctionAndCallInfo(text = text)
def cat(filepath):
return "cat \"{}\"".format(filepath)
def redirect_out_err(from_process, to_file):
return from_process + " &> " + to_file
def assert_script_errors():
return "set -e"
def cleanup_function(on_success, on_failure):
text = "\n".join([
"local ecode=$?",
"if [ $ecode -eq 0 ]; then",
on_success,
"else",
on_failure,
"fi",
])
return FunctionAndCallInfo(text = text, call = "trap \"cleanup_function\" EXIT")
def children_to_path(dir_):
text = """\
if [ -d {dir_} ]; then
local tools=$(find $EXT_BUILD_DEPS/bin/ -maxdepth 1 -mindepth 1)
for tool in $tools;
do
if [[ -d \"$tool\" ]] || [[ -L \"$tool\" ]]; then
export PATH=$PATH:$tool
fi
done
fi""".format(dir_ = dir_)
return FunctionAndCallInfo(text = text)
def define_absolute_paths(dir_, abs_path):
return "##replace_in_files## {dir_} {REPLACE_VALUE} {abs_path}".format(
dir_ = dir_,
REPLACE_VALUE = "\\${EXT_BUILD_DEPS}",
abs_path = abs_path,
)
def replace_absolute_paths(dir_, abs_path):
return "##replace_in_files## {dir_} {abs_path} {REPLACE_VALUE}".format(
dir_ = dir_,
REPLACE_VALUE = "\\${EXT_BUILD_DEPS}",
abs_path = abs_path,
)
def define_sandbox_paths(dir_, abs_path):
return "##replace_in_files## {dir_} {REPLACE_VALUE} {abs_path}".format(
dir_ = dir_,
REPLACE_VALUE = "\\${EXT_BUILD_ROOT}",
abs_path = abs_path,
)
def replace_sandbox_paths(dir_, abs_path):
return "##replace_in_files## {dir_} {abs_path} {REPLACE_VALUE}".format(
dir_ = dir_,
REPLACE_VALUE = "\\${EXT_BUILD_ROOT}",
abs_path = abs_path,
)
def replace_symlink(file):
return """\
if [[ -L "{file}" ]]; then
target="$(readlink -f "{file}")"
rm "{file}" && cp -a "${{target}}" "{file}"
fi
""".format(file = file)

View File

@ -25,6 +25,12 @@ TOOLCHAIN_MAPPINGS = [
],
file = Label("@rules_foreign_cc//foreign_cc/private/framework/toolchains:linux_commands.bzl"),
),
_toolchain_mapping(
exec_compatible_with = [
"@platforms//os:freebsd",
],
file = Label("@rules_foreign_cc//foreign_cc/private/framework/toolchains:freebsd_commands.bzl"),
),
_toolchain_mapping(
exec_compatible_with = [
"@platforms//os:windows",

View File

@ -63,9 +63,11 @@ def rules_foreign_cc_dependencies(
maybe(
http_archive,
name = "bazel_skylib",
# `main` as of 2021-10-27
# Release request: https://github.com/bazelbuild/bazel-skylib/issues/336
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.1.1/bazel-skylib-1.1.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/archive/6e30a77347071ab22ce346b6d20cf8912919f644.zip",
],
sha256 = "c6966ec828da198c5d9adbaa94c05e3a1c7f21bd012a0b29ba8ddbccb2c93b0d",
strip_prefix = "bazel-skylib-6e30a77347071ab22ce346b6d20cf8912919f644",
sha256 = "247361e64b2a85b40cb45b9c071e42433467c6c87546270cbe2672eb9f317b5a",
)

View File

@ -29,10 +29,17 @@ config_setting(
visibility = ["//visibility:private"],
)
config_setting(
name = "freebsd",
constraint_values = ["@platforms//os:freebsd"],
visibility = ["//visibility:private"],
)
diff_test(
name = "shell_script_inner_fun_test",
file1 = ":shell_script_inner_fun",
file2 = select({
":freebsd": "expected/inner_fun_text_freebsd.txt",
":macos": "expected/inner_fun_text_macos.txt",
"//conditions:default": "expected/inner_fun_text.txt",
}),
@ -58,6 +65,7 @@ symlink_contents_to_dir_test_rule(
diff_test(
name = "shell_method_symlink_contents_to_dir_test",
file1 = select({
":freebsd": "expected/out_symlinked_dirs_freebsd.txt",
":macos": "expected/out_symlinked_dirs_macos.txt",
"//conditions:default": "expected/out_symlinked_dirs.txt",
}),

View File

@ -0,0 +1,67 @@
function symlink_contents_to_dir() {
if [[ -z "$1" ]]; then
echo "arg 1 to symlink_contents_to_dir is unexpectedly empty"
exit 1
fi
if [[ -z "$2" ]]; then
echo "arg 2 to symlink_contents_to_dir is unexpectedly empty"
exit 1
fi
local target="$2"
mkdir -p "$target"
if [[ -f "$1" ]]; then
symlink_to_dir "$1" "$target"
elif [[ -L "$1" && ! -d "$1" ]]; then
local actual=$(readlink "$1")
symlink_contents_to_dir "$actual" "$target"
elif [[ -d "$1" ]]; then
SAVEIFS=$IFS
IFS=$'
'
local children=($(find "$1/" -maxdepth 1 -mindepth 1))
IFS=$SAVEIFS
for child in "${children[@]:-}"; do
symlink_to_dir "$child" "$target"
done
fi
}
function symlink_to_dir() {
if [[ -z "$1" ]]; then
echo "arg 1 to symlink_to_dir is unexpectedly empty"
exit 1
fi
if [[ -z "$2" ]]; then
echo "arg 2 to symlink_to_dir is unexpectedly empty"
exit 1
fi
local target="$2"
mkdir -p "$target"
if [[ -f "$1" ]]; then
# In order to be able to use `replace_in_files`, we ensure that we create copies of specfieid
# files so updating them is possible.
if [[ "$1" == *.pc || "$1" == *.la || "$1" == *-config || "$1" == *.mk || "$1" == *.cmake ]]; then
dest="$target/$(basename $1)"
cp "$1" "$dest" && chmod +w "$dest" && touch -r "$1" "$dest"
else
ln -s -f "$1" "$target"
fi
elif [[ -L "$1" && ! -d "$1" ]]; then
cp -pR "$1" "$2"
elif [[ -d "$1" ]]; then
SAVEIFS=$IFS
IFS=$'
'
local children=($(find "$1/" -maxdepth 1 -mindepth 1))
IFS=$SAVEIFS
local dirname=$(basename "$1")
mkdir -p "$target/$dirname"
for child in "${children[@]:-}"; do
if [[ -n "$child" && "$dirname" != *.ext_build_deps ]]; then
symlink_to_dir "$child" "$target/$dirname"
fi
done
else
echo "Can not copy $1"
fi
}
symlink_contents_to_dir $SOURCE_DIR $TARGET_DIR

View File

@ -0,0 +1,2 @@
header1.h
header2.h