diff --git a/WORKSPACE b/WORKSPACE index 324c84df4881..5017a240139d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -255,12 +255,6 @@ mosek_repository( name = "mosek", ) -load("//tools:soft_failure.bzl", "soft_failure_binary_repository") -soft_failure_binary_repository( - name = "drake_visualizer", - local_path = __workspace_dir__ + "/build/install/bin/drake-visualizer", -) - load("//tools:gfortran.bzl", "gfortran_repository") gfortran_repository( name = "gfortran", @@ -360,3 +354,8 @@ pkg_config_package( name = "zlib", modname = "zlib", ) + +load("//tools:director.bzl", "director_repository") +director_repository( + name = "director", +) diff --git a/drake/automotive/BUILD b/drake/automotive/BUILD index e16f11b73398..840444d925f4 100644 --- a/drake/automotive/BUILD +++ b/drake/automotive/BUILD @@ -436,7 +436,7 @@ py_binary( ":automotive_demo", ":lcm-spy", ":steering_command_driver", - "@drake_visualizer//:drake-visualizer", + "//tools:drake_visualizer", "@lcm//:lcm-logger", ], main = "automotive_demo.py", diff --git a/drake/automotive/README.md b/drake/automotive/README.md index 75b20b93935b..997e4e23de3d 100644 --- a/drake/automotive/README.md +++ b/drake/automotive/README.md @@ -7,25 +7,6 @@ getting started with Bazel, see http://drake.mit.edu/bazel.html. Note that the *libraries* in this directory subtree support the CMake build system; only the demo is Bazel-specific. -Prepare the drake-visualizer ----------------------------- - -The ``drake-visualizer`` is only available via a CMake build. We recommend -that you run a CMake build per the Drake instructions, using the same source -tree as this demo. In that case, the ``drake-visualizer`` will automatically -be discovered and launched by this demo. - -Otherwise, you will see a message like: - -``` -soft_failure.bzl: @drake_visualizer//:drake-visualizer does not work because - drake-distro/build/install/bin/drake-visualizer was missing -``` - -In this case, the automotive demo must be run with the ``--no-visualizer`` -switch, and you will have to manually launch some other build of the -``drake-visualizer``. - Running the demos ----------------- diff --git a/drake/automotive/automotive_demo.py b/drake/automotive/automotive_demo.py index 8f1aa9832d40..2ccbb9766d92 100644 --- a/drake/automotive/automotive_demo.py +++ b/drake/automotive/automotive_demo.py @@ -186,7 +186,7 @@ def receive(channel, data): def main(): demo_path = "drake/automotive/automotive_demo" steering_command_driver_path = "drake/automotive/steering_command_driver" - drake_visualizer_path = "external/drake_visualizer/drake-visualizer" + drake_visualizer_path = "tools/drake_visualizer" lcm_spy_path = "drake/automotive/lcm-spy" lcm_logger_path = "external/lcm/lcm-logger" diff --git a/tools/BUILD b/tools/BUILD index 0a49fab89625..1a0edc67a810 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -17,6 +17,15 @@ sh_binary( data = ["asan.supp"], ) +sh_binary( + name = "drake_visualizer", + srcs = select({ + "//tools:apple": ["drake_visualizer_apple.sh"], + "//conditions:default": ["drake_visualizer_linux.sh"], + }), + data = ["@director"], +) + sh_binary( name = "lsan", srcs = ["lsan.sh"], diff --git a/tools/director.bzl b/tools/director.bzl new file mode 100644 index 000000000000..402b85e4ba56 --- /dev/null +++ b/tools/director.bzl @@ -0,0 +1,55 @@ +# -*- mode: python -*- +# vi: set ft=python : + +def _impl(repository_ctx): + if repository_ctx.os.name == "mac os x": + archive = "dd-0.1.0-160-ga50a077-qt-5.8.0-Darwin.tar.gz" + sha256 = "6873427eb417e03688e85ac59955777fda67f89781245f3146470c5156045691" + elif repository_ctx.os.name == "linux": + sed = repository_ctx.which("sed") + + if not sed: + fail("Could NOT determine Linux distribution information because" + + " sed is missing") + + result = repository_ctx.execute([ + sed, + "-n", + "/^\(NAME\|VERSION_ID\)=/{s/[^=]*=//;s/\"//g;p}", + "/etc/os-release"]) + + if result.return_code != 0: + fail("Could NOT determine Linux distribution information", + attr=result.stderr) + + distro = [l.strip() for l in result.stdout.strip().split("\n")] + distro = " ".join(distro) + + if distro == "Ubuntu 14.04": + archive = "dd-0.1.0-160-ga50a077-qt-4.8.6-trusty-x86_64.tar.gz" + sha256 = "7d8e5bf66648edffc8f003d0c0a19c80745cdf7b5c9a524069b041dd67c865d1" + elif distro == "Ubuntu 16.04": + archive = "dd-0.1.0-160-ga50a077-qt-5.5.1-xenial-x86_64.tar.gz" + sha256 = "c4dbd896454a293c3bb65761763ce0571e83dd81b6986e1458073d88a7ef55c7" + else: + fail("Linux distribution is NOT supported", attr=distro) + else: + fail("Operating system is NOT supported", attr=repository_ctx.os.name) + + url = "https://d2mbb5ninhlpdu.cloudfront.net/director/{}".format(archive) + root_path = repository_ctx.path("") + + repository_ctx.download_and_extract(url, root_path, sha256=sha256) + + file_content = """ +filegroup( + name = "director", + srcs = glob(["**/*"]), + data = ["@vtk"], + visibility = ["//visibility:public"], +) +""" + + repository_ctx.file("BUILD", content=file_content, executable=False) + +director_repository = repository_rule(implementation = _impl) diff --git a/tools/drake_visualizer_apple.sh b/tools/drake_visualizer_apple.sh new file mode 100755 index 000000000000..c5c47f9187f9 --- /dev/null +++ b/tools/drake_visualizer_apple.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +export DYLD_LIBRARY_PATH="external/director/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" +# TODO(jamiesnape): Do not hard code absolute path to vtk@8.0. +export PYTHONPATH="external/director/lib/python2.7/dist-packages:/usr/local/opt/vtk@8.0/lib/python2.7/site-packages${PYTHONPATH:+:$PYTHONPATH}" + +exec "external/director/bin/drake-visualizer" "$@" diff --git a/tools/drake_visualizer_linux.sh b/tools/drake_visualizer_linux.sh new file mode 100755 index 000000000000..dda7f92f5c60 --- /dev/null +++ b/tools/drake_visualizer_linux.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="external/director/lib:external/vtk/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +export PYTHONPATH="external/director/lib/python2.7/dist-packages:external/vtk/lib/python2.7/site-packages${PYTHONPATH:+:$PYTHONPATH}" + +exec "external/director/bin/drake-visualizer" "$@" diff --git a/tools/soft_failure.bzl b/tools/soft_failure.bzl deleted file mode 100644 index c4ded73a0d92..000000000000 --- a/tools/soft_failure.bzl +++ /dev/null @@ -1,112 +0,0 @@ -# -*- python -*- - -# This file provides a repository rule: -# -# soft_failure_binary_repository(name, local_path) -# -# The rule brings an external program into the workspace in a soft-failure way. -# For example, an invocation like this ... -# -# soft_failure_binary_repository( -# name = "foo", -# local_path = "/usr/local/bin/bar" -# ) -# -# ... will create a binary target @foo//:bar that can be used via "bazel run", -# or as in the data=[...] attribute of some other rule, test, etc. At build -# time the path will be symlinked in the repository; the build will succeed -# even if the referenced path is missing. Only if the @foo//:bar target is -# actually run and the referenced path does not exist will we die with a -# diagnostic. The pass / failure condition is hermetic; if the program later -# (dis)appears, any targets that depended on *running* it will be rebuilt. -# -# === Implementation notes follow == -# -# This rule is tricky due to https://github.com/bazelbuild/bazel/issues/1595. -# In the repository rule, we can't do any sensing that will vary over time -# (such as $PATH lookup or "$(which ...)"), so instead we must ask our caller -# to hard-code where the program comes from. What we can do is have a rule in -# our generated BUILD file that yields different results. For that, we use a -# glob() call, detailed below. -# -# When building the repository, we add a symlink for where the program should -# be. By using glob() against that symlink in our BUILD, Bazel will notice at -# build time whether or not the symlink resolves, and bring it into the sandbox -# only if so. Bazel notices when glob() outcomes change, so rebuilds anytime -# the actual program (dis)appears. - -def _soft_failure_binary_repository_impl(repository_ctx): - repo_name = repository_ctx.name - local_path = getattr(repository_ctx.attr, "local_path") - basename = local_path[(local_path.rfind("/") + 1):] - - # Symlink the requested binary's path into the repository. The symlink - # might be broken, but we are careful to handle that below. - symlink_basename = "__symlink_" + basename - repository_ctx.symlink(local_path, symlink_basename) - symlink_path = "external/" + repo_name + "/" + symlink_basename - - # Set up an error message to be used by generated code. - label = "@{repo_name}//:{basename}".format( - repo_name=repo_name, basename=basename) - warning = "soft_failure.bzl: " + ( - "{label} does not work because {local_path} was missing".format( - label=label, local_path=local_path)) - - # Emit the wrapper that unconditionally fails at runtime; this is selected - # at build-time when the glob() fails. - wrapper_failure_basename = "__failure_" + basename - wrapper_sh = """#!/bin/sh - echo "{warning}" - exit 1 - """.format(warning=warning) - repository_ctx.file(wrapper_failure_basename, content=wrapper_sh) - - # Emit the wrapper that delegates to the target program; this is selected - # at build-time when the glob() succeeds. - wrapper_success_basename = "__success_" + basename - wrapper_sh = """#!/bin/sh - if [ ! -L "{symlink_path}" ]; then - # We are running outside of the sandbox. - exec "{local_path}" "$@" - fi - if [ ! -x "{symlink_path}" ]; then - # We are running inside of the sandbox; the symlink exists but is broken. - echo "{warning}; this is unexpected, because it was present at build-time" - exit 1 - fi - exec "{symlink_path}" "$@" - """.format( - symlink_path=symlink_path, - local_path=local_path, - warning=warning) - repository_ctx.file(wrapper_success_basename, content=wrapper_sh) - - # Emit the BUILD file into the repository. Define a sh_binary named as the - # target binary's basename (so "/path/to/tool" turns into label ":tool"). - # The sh_binary source code will be one of the two wrapper scripts above. - BUILD = """ - data = glob(["{symlink_basename}"]) or print("{warning}") - src = "{wrapper_success_basename}" if data else "{wrapper_failure_basename}" - sh_binary( - name = "{basename}", - srcs = [src], - data = data, - visibility = ["//visibility:public"], - ) - """.format( - symlink_basename=symlink_basename, - warning=warning, - basename=basename, - wrapper_success_basename=wrapper_success_basename, - wrapper_failure_basename=wrapper_failure_basename) - BUILD = BUILD.replace("\n ", "\n") # Strip leading indent from lines. - repository_ctx.file("BUILD", content=BUILD) - -soft_failure_binary_repository = repository_rule( - attrs = { - "local_path": attr.string(mandatory = True), - }, - local = True, - implementation = _soft_failure_binary_repository_impl, -) diff --git a/tools/vtk.bzl b/tools/vtk.bzl index 1ef0c9bfe73e..e15ff442090d 100644 --- a/tools/vtk.bzl +++ b/tools/vtk.bzl @@ -23,7 +23,7 @@ Argument: name: A unique name for this rule. """ -VTK_MAJOR_MINOR_VERSION = "7.1" +VTK_MAJOR_MINOR_VERSION = "8.0" def _vtk_cc_library(os_name, name, hdrs=None, visibility=None, deps=None, header_only=False): @@ -54,7 +54,7 @@ def _vtk_cc_library(os_name, name, hdrs=None, visibility=None, deps=None, if not header_only: linkopts = [ - "-L/usr/local/opt/vtk@8.0/lib", + "-L/usr/local/opt/vtk@{}/lib".format(VTK_MAJOR_MINOR_VERSION), "-l{}-{}".format(name, VTK_MAJOR_MINOR_VERSION), ] else: @@ -77,8 +77,8 @@ cc_library( def _impl(repository_ctx): if repository_ctx.os.name == "mac os x": - # TODO(jamiesnape): Use VTK_MAJOR_MINOR_VERSION instead of hard-coding. - repository_ctx.symlink("/usr/local/opt/vtk@8.0/include", "include") + repository_ctx.symlink("/usr/local/opt/vtk@{}/include".format( + VTK_MAJOR_MINOR_VERSION), "include") repository_ctx.file("empty.cc", executable=False) elif repository_ctx.os.name == "linux": @@ -100,11 +100,11 @@ def _impl(repository_ctx): distro = " ".join(distro) if distro == "Ubuntu 14.04": - archive = "vtk-v7.1.1-1584-g28deb56-qt-4.8.6-trusty-x86_64.tar.gz" - sha256 = "709fb9a5197ee5a87bc92760c2fe960b89326acd11a0ce6adf9d7d023563f5d4" + archive = "vtk-v8.0.0.rc2-qt-4.8.6-trusty-x86_64.tar.gz" + sha256 = "78880d8b951355a6ad5a6bfc42275ae42f31e2e05f1b52e3a9883226556b1685" elif distro == "Ubuntu 16.04": - archive = "vtk-v7.1.1-1584-g28deb56-qt-5.5.1-xenial-x86_64.tar.gz" - sha256 = "d21cae88b2276fd59c94f0e41244fc8f7e31ff796518f731e4fffc25f8e01cbc" + archive = "vtk-v8.0.0.rc2-qt-5.5.1-xenial-x86_64.tar.gz " + sha256 = "963f81abd90da4470df1fb20aee8b4ead815f543f3ae9fa00ef2ea6be5cc2c0c" else: fail("Linux distribution is NOT supported", attr=distro) @@ -487,7 +487,4 @@ filegroup( repository_ctx.file("BUILD", content=file_content, executable=False) -vtk_repository = repository_rule( - local = True, - implementation = _impl, -) +vtk_repository = repository_rule(implementation = _impl)