Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linkstatic shell tests #488

Merged
merged 6 commits into from
Nov 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly yes, to navigate around bazelbuild/bazel#3115

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a note inline about this at the top of providers.bzl about this?

"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",
)
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
)