Skip to content

Commit

Permalink
Merge pull request #488 from tweag/linkstatic-shell-tests
Browse files Browse the repository at this point in the history
Linkstatic shell tests
  • Loading branch information
Profpatsch authored Nov 23, 2018
2 parents 9e363eb + 4778b74 commit 0621cfc
Show file tree
Hide file tree
Showing 21 changed files with 223 additions and 38 deletions.
2 changes: 1 addition & 1 deletion haskell/c2hs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ load(
"target_unique_name",
)
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"C2hsLibraryInfo",
)
load("@bazel_skylib//:lib.bzl", "paths")
Expand Down
2 changes: 1 addition & 1 deletion haskell/cc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ These rules are temporary and will be deprecated in the future.
"""

load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"CcSkylarkApiProviderHacked",
"HaskellBinaryInfo",
"HaskellBuildInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/doctest.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Doctest support"""

load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellBinaryInfo",
"HaskellBuildInfo",
"HaskellLibraryInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/haddock.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ load(":private/context.bzl", "haskell_context")
load(":private/path_utils.bzl", "module_name")
load(":private/set.bzl", "set")
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaddockInfo",
"HaskellBuildInfo",
"HaskellLibraryInfo",
Expand Down
5 changes: 4 additions & 1 deletion haskell/haskell.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Core Haskell rules"""

load(":private/providers.bzl", "HaskellPrebuiltPackageInfo")
load(
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellPrebuiltPackageInfo",
)
load(":private/set.bzl", "set")
load("@bazel_skylib//:lib.bzl", "paths")
load(
Expand Down
2 changes: 1 addition & 1 deletion haskell/import.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
load(":private/context.bzl", "haskell_context")
load(":private/actions/package.bzl", "package")
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaddockInfo",
"HaskellBuildInfo",
"HaskellLibraryInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/lint.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ load(
"target_unique_name",
)
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellBinaryInfo",
"HaskellBuildInfo",
"HaskellLibraryInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/private/actions/compile.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ load(
)
load(":private/pkg_id.bzl", "pkg_id")
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"C2hsLibraryInfo",
"DefaultCompileInfo",
)
Expand Down
2 changes: 1 addition & 1 deletion haskell/private/actions/repl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ load(
"shell",
)
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellBinaryInfo",
"HaskellBuildInfo",
"HaskellLibraryInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/private/dependencies.bzl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
load(":private/path_utils.bzl", "ln")
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"CcSkylarkApiProviderHacked",
"HaskellBinaryInfo",
"HaskellBuildInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/private/haskell_impl.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ load(
"ln",
)
load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"C2hsLibraryInfo",
"HaskellBinaryInfo",
"HaskellBuildInfo",
Expand Down
2 changes: 1 addition & 1 deletion haskell/protobuf.bzl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Support for protocol buffers"""

load(
":private/providers.bzl",
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellBuildInfo",
"HaskellLibraryInfo",
"HaskellProtobufInfo",
Expand Down
4 changes: 3 additions & 1 deletion skylark/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
exports_files(["lint.bzl"])
exports_files([
"lint.bzl",
])

sh_binary(
name = "buildifier",
Expand Down
10 changes: 8 additions & 2 deletions tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ load(
)
load("@bazel_tools//tools/build_rules:test_rules.bzl", "rule_test")
load("//skylark:lint.bzl", "skylark_lint")
load(":sh_inline_test.bzl", "sh_inline_test")
load("@io_tweag_rules_haskell//haskell:import.bzl", haskell_import_new = "haskell_import")

ghc_version = "8.4.4"
Expand Down Expand Up @@ -268,12 +269,17 @@ rule_test(
rule = "//tests/cc_haskell_import:cc-bin",
)

sh_test(
sh_inline_test(
name = "test-haskell_binary-with-link-flags",
size = "small",
srcs = ["scripts/test-threaded.sh"],
args = ["$(location //tests/binary-with-link-flags:binary-with-link-flags)"],
data = ["//tests/binary-with-link-flags"],
script = """\
set -e
# Fails if executable was linked without -threaded flag.
$1 +RTS -N
""",
)

rule_test(
Expand Down
109 changes: 109 additions & 0 deletions tests/library-linkstatic-flag/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# test whether `linkstatic` works as expected
package(default_testonly = 1)

load("//tests:sh_inline_test.bzl", "sh_inline_test")
load(":get_library_files.bzl", "get_libraries_as_runfiles")

load(
"@io_tweag_rules_haskell//haskell:haskell.bzl",
"haskell_library",
)

# only .a files
haskell_library(
name = "library-static-only",
srcs = ["Lib.hs"],
visibility = ["//visibility:public"],
deps = [
"@hackage//:base",
"@hackage//:bytestring",
],
linkstatic = True, # <--
)

# both .a and .so files
haskell_library(
name = "library-static-and-dynamic",
srcs = ["Lib.hs"],
visibility = ["//visibility:public"],
deps = [
"@hackage//:base",
"@hackage//:bytestring",
],
linkstatic = False, # <--
)

# extract all libraries from the haskell_library
get_libraries_as_runfiles(
name = "library-static-only-libraries",
library = ":library-static-only",
)
get_libraries_as_runfiles(
name = "library-static-and-dynamic-libraries",
library = ":library-static-and-dynamic",
)

# sh_test’s `data` doesn’t add stuff to runfiles :(
# sh_library can bundle different targets as runfiles for sh_test
# TODO(Profpatsch): add functionality to sh_inline_test by default?
sh_library(
name = "bundled-dependency-files-static-only",
data = [":library-static-only-libraries"]
)
sh_library(
name = "bundled-dependency-files-static-and-dynamic",
data = [":library-static-and-dynamic-libraries"]
)

# ensure that linkstatic=True only creates only .a, no .so
sh_inline_test(
name = "test-linkstatic-static-only",
script = """
set -euo pipefail
for f in "$@"; do
if ! [[ "$f" =~ .a$ ]]; then
echo "not a static library: $f"
exit 1
fi
done
""",
# pass the file names as arguments
args = ["$(rootpaths :library-static-only-libraries)"],
data = [
# for rootpaths
":library-static-only-libraries",
# to actually get the files …
":bundled-dependency-files-static-only"],
size = "small",
)

# test whether .so is linked dynamically and .a statically
sh_inline_test(
name = "test-libraries-static-and-dynamic",
script = """
set -euo pipefail
is_dynamic () {
# taken from https://github.com/NixOS/nixpkgs/blob/0b3f50f844e2a6b507b18d7c5259bb850b382f87/pkgs/build-support/setup-hooks/auto-patchelf.sh#L167-L170
readelf -l -- "$1" | grep -q "^ *INTERP\\>"
}
for f in "$@"; do
if [[ "$f" =~ .a$ ]] && is_dynamic "$f"; then
echo "should be a static executable: $f"
exit 1
fi
if [[ "$f" =~ .so$ ]] && ! is_dynamic "$f"; then
echo "should be a dynamic executable: $f"
exit 1
fi
done
""",
# pass the file names as arguments
args = ["$(rootpaths :library-static-and-dynamic-libraries)"],
data = [
# for rootpaths
":library-static-and-dynamic-libraries",
# to actually get the files …
":bundled-dependency-files-static-and-dynamic"],
size = "small",
)
File renamed without changes.
File renamed without changes.
28 changes: 28 additions & 0 deletions tests/library-linkstatic-flag/get_library_files.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
load(
"@io_tweag_rules_haskell//haskell:private/providers.bzl",
"HaskellBuildInfo",
"HaskellLibraryInfo",
)
load("//haskell:private/set.bzl", "set")

def _get_libraries_as_runfiles_impl(ctx):
"""Extract all library files from a haskell_library target
and put them in this target’s files"""
bi = ctx.attr.library[HaskellBuildInfo]
return [DefaultInfo(
# not necessarily complete
files = depset(
direct = bi.static_libraries,
transitive = [set.to_depset(bi.dynamic_libraries)]
),
)]

get_libraries_as_runfiles = rule(
_get_libraries_as_runfiles_impl,
attrs = {
"library": attr.label(
mandatory = True,
providers = [HaskellBuildInfo, HaskellLibraryInfo],
)
}
)
17 changes: 0 additions & 17 deletions tests/library-static-only/BUILD

This file was deleted.

6 changes: 0 additions & 6 deletions tests/scripts/test-threaded.sh

This file was deleted.

60 changes: 60 additions & 0 deletions tests/sh_inline_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
load("@bazel_skylib//:lib.bzl", "shell")

def quote_make_variables(s):
"""Quote all genrule “Make” Variables in a string."""
return s.replace("$", "$$")

def target_from_string(name, string):
"""Write a skylark string to a target."""
native.genrule(
name = name + "-file",
outs = [name],
# this is exceptionally ugly.
cmd = """echo -n {quoted} > $(@)""".format(
# but should at least be quoted right
quoted = shell.quote(quote_make_variables(string)),
),
)

bash_runfiles_boilerplate = """\
# Copy-pasted from Bazel's Bash runfiles library (tools/bash/runfiles/runfiles.bash).
set -euo pipefail
if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
if [[ -f "$0.runfiles_manifest" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
elif [[ -f "$0.runfiles/MANIFEST" ]]; then
export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
export RUNFILES_DIR="$0.runfiles"
fi
fi
if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
"$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
else
echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
exit 1
fi
# --- end runfiles.bash initialization ---
"""

def sh_inline_test(name, script, **kwargs):
"""Like sh_test, but instead of srcs takes the shell script
as verbatim bazel string. The bash runfiles are in scope,
using `rlocation` works by default.
"""
script_name = name + ".sh"
script = bash_runfiles_boilerplate + script

target_from_string(script_name, script)

deps = kwargs.pop("deps", [])

native.sh_test(
name = name,
srcs = [script_name],
deps = ["@bazel_tools//tools/bash/runfiles"] + deps,
**kwargs
)

0 comments on commit 0621cfc

Please sign in to comment.