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

Add IPOPT to the Bazel build #4905

Merged
merged 3 commits into from
Jan 26, 2017
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
7 changes: 7 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ new_git_repository(
build_file = "tools/fcl.BUILD",
)

new_git_repository(
name = "ipopt",
remote = "https://github.com/RobotLocomotion/ipopt-mirror.git",
commit = "11649b7a063e03af38fcc59cf8cdb0694735c84c",
build_file = "tools/ipopt.BUILD",
)

# Necessary for buildifier.
http_archive(
name = "io_bazel_rules_go",
Expand Down
68 changes: 68 additions & 0 deletions drake/examples/Pendulum/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- python -*-
# This file contains rules for Bazel; see drake/doc/bazel.rst.

load("//tools:cpplint.bzl", "cpplint")
load("//tools:drake.bzl", "cc_googletest")

cc_library(
name = "pendulum_state_vector",
srcs = ["gen/pendulum_state_vector.cc"],
hdrs = ["gen/pendulum_state_vector.h"],
linkstatic = 1,
deps = [
"//drake/systems/framework:vector",
],
)

cc_library(
name = "pendulum_plant",
srcs = ["pendulum_plant.cc"],
hdrs = ["pendulum_plant.h"],
deps = [
":pendulum_state_vector",
"//drake/systems/framework",
],
)

cc_library(
name = "pendulum_swing_up",
srcs = ["pendulum_swing_up.cc"],
hdrs = ["pendulum_swing_up.h"],
deps = [
":pendulum_plant",
"//drake/systems/trajectory_optimization:direct_collocation",
],
)

# === test/ ===

cc_googletest(
name = "pendulum_urdf_dynamics_test",
data = ["Pendulum.urdf"],
deps = [
":pendulum_plant",
"//drake/common:eigen_matrix_compare",
"//drake/multibody:rigid_body_tree",
"//drake/multibody/parsers",
"//drake/multibody/rigid_body_plant",
],
)

cc_googletest(
name = "pendulum_dynamic_constraint_test",
deps = [
":pendulum_plant",
"//drake/common:eigen_matrix_compare",
"//drake/systems/trajectory_optimization:direct_collocation",
],
)

cc_googletest(
name = "pendulum_trajectory_optimization_test",
deps = [
":pendulum_swing_up",
"//drake/common:eigen_matrix_compare",
],
)

cpplint()
34 changes: 27 additions & 7 deletions drake/solvers/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ cc_library(
# - equality_constrained_qp_solver
# - linear_system_solver
# - moby_lcp_solver
# - Gurobi (on Ubuntu)
# - IPOPT (on Ubuntu only)
# - Gurobi (on Ubuntu only)

# Unsupported solvers:
# - dReal
# - IPOPT
# - NLOPT
# - SNOPT
# - MOSEK
Expand All @@ -71,7 +71,6 @@ cc_library(
"dreal_solver.h",
"equality_constrained_qp_solver.cc",
"equality_constrained_qp_solver.h",
"ipopt_solver.h",
"linear_system_solver.cc",
"linear_system_solver.h",
"mathematical_program.cc",
Expand All @@ -80,7 +79,6 @@ cc_library(
"mosek_solver.h",
"nlopt_solver.h",
"no_dreal.cc",
"no_ipopt.cc",
"no_mosek.cc",
"no_nlopt.cc",
"no_snopt.cc",
Expand All @@ -97,6 +95,7 @@ cc_library(
":decision_variable",
":function",
":gurobi_solver",
":ipopt_solver",
"//drake/common",
"//drake/common:autodiff",
"//drake/common:number_traits",
Expand Down Expand Up @@ -173,6 +172,27 @@ cc_library(
}),
)

cc_library(
name = "ipopt_solver",
srcs = select({
"//tools:apple": ["no_ipopt.cc"],
"//tools:linux": ["ipopt_solver.cc"],
}),
hdrs = ["ipopt_solver.h"],
linkstatic = 1,
visibility = ["//visibility:private"],
deps = select({
"//tools:linux": [
"@ipopt//:lib",
":mathematical_program_api",
"//drake/math:autodiff",
],
"//tools:apple": [
":mathematical_program_api",
],
}),
)

# === test/ ===
cc_googletest(
name = "binding_test",
Expand Down Expand Up @@ -249,8 +269,8 @@ cc_googletest(
srcs = [
"test/linear_system_solver_test.cc",
"test/mathematical_program_test_util.h",
"test/optimization_examples.h",
"test/optimization_examples.cc",
"test/optimization_examples.h",
],
deps = [
":mathematical_program",
Expand Down Expand Up @@ -300,10 +320,10 @@ cc_googletest(
cc_googletest(
name = "nonlinear_program_test",
srcs = [
"test/nonlinear_program_test.cc",
"test/mathematical_program_test_util.h",
"test/optimization_examples.h",
"test/nonlinear_program_test.cc",
"test/optimization_examples.cc",
"test/optimization_examples.h",
],
deps = [
":mathematical_program",
Expand Down
10 changes: 10 additions & 0 deletions tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ config_setting(
name = "with_gurobi",
values = {"define": "WITH_GUROBI=ON"},
)

config_setting(
name = "linux",
values = {"cpu": "k8"},
)

config_setting(
name = "apple",
values = {"cpu": "darwin"},
)
132 changes: 132 additions & 0 deletions tools/ipopt.BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# We build IPOPT by shelling out to autotools.

# A prefix-string for genrule cmd attributes, which uses the Kythe cdexec tool,
# in quiet mode, to execute in the genrule output directory.
CDEXEC = "$(location @//tools/third_party/kythe/tools/cdexec:cdexec) -q $(@D)"

# We run autotools in a genrule, and only files explicitly identified as outputs
# of that genrule can be made available to other rules. Therefore, we need a
# list of every file in the IPOPT install.
# See https://github.com/bazelbuild/bazel/issues/281.

# find include/coin -name "*.h" -o -name "*.hpp" -o -name "*.hdd" | sort |
# sed 's/$/",/g'| sed 's/^/"/g'
IPOPT_HDRS = [
"include/coin/AmplTNLP.hpp",
"include/coin/HSLLoader.h",
"include/coin/IpAlgTypes.hpp",
"include/coin/IpBlas.hpp",
"include/coin/IpCachedResults.hpp",
"include/coin/IpCompoundVector.hpp",
"include/coin/IpDebug.hpp",
"include/coin/IpDenseVector.hpp",
"include/coin/IpException.hpp",
"include/coin/IpExpansionMatrix.hpp",
"include/coin/IpIpoptApplication.hpp",
"include/coin/IpIpoptCalculatedQuantities.hpp",
"include/coin/IpIpoptData.hpp",
"include/coin/IpIpoptNLP.hpp",
"include/coin/IpIteratesVector.hpp",
"include/coin/IpJournalist.hpp",
"include/coin/IpLapack.hpp",
"include/coin/IpMatrix.hpp",
"include/coin/IpNLP.hpp",
"include/coin/IpNLPScaling.hpp",
"include/coin/IpObserver.hpp",
"include/coin/IpoptConfig.h",
"include/coin/IpOptionsList.hpp",
"include/coin/IpOrigIpoptNLP.hpp",
"include/coin/IpReferenced.hpp",
"include/coin/IpRegOptions.hpp",
"include/coin/IpReturnCodes.h",
"include/coin/IpReturnCodes.hpp",
"include/coin/IpReturnCodes_inc.h",
"include/coin/IpSmartPtr.hpp",
"include/coin/IpSolveStatistics.hpp",
"include/coin/IpStdCInterface.h",
"include/coin/IpSymMatrix.hpp",
"include/coin/IpTaggedObject.hpp",
"include/coin/IpTimedTask.hpp",
"include/coin/IpTimingStatistics.hpp",
"include/coin/IpTNLPAdapter.hpp",
"include/coin/IpTNLP.hpp",
"include/coin/IpTNLPReducer.hpp",
"include/coin/IpTypes.hpp",
"include/coin/IpUtils.hpp",
"include/coin/IpVector.hpp",
"include/coin/PardisoLoader.h",
"include/coin/ThirdParty/arith.h",
"include/coin/ThirdParty/asl.h",
"include/coin/ThirdParty/asl_pfg.h",
"include/coin/ThirdParty/asl_pfgh.h",
"include/coin/ThirdParty/defs.h",
"include/coin/ThirdParty/dmumps_c.h",
"include/coin/ThirdParty/funcadd.h",
"include/coin/ThirdParty/getstub.h",
"include/coin/ThirdParty/macros.h",
"include/coin/ThirdParty/metis.h",
"include/coin/ThirdParty/mpi.h",
"include/coin/ThirdParty/mumps_compat.h",
"include/coin/ThirdParty/mumps_c_types.h",
"include/coin/ThirdParty/nlp2.h",
"include/coin/ThirdParty/nlp.h",
"include/coin/ThirdParty/proto.h",
"include/coin/ThirdParty/psinfo.h",
"include/coin/ThirdParty/rename.h",
"include/coin/ThirdParty/stdio1.h",
"include/coin/ThirdParty/struct.h",
]

# ls lib | grep "\.a$" | sed 's/$/",/g'| sed 's/^/"lib\//g'
# These are artisanally topo-sorted: demand before supply.
# If you change the order, you may get undefined-reference linker errors.
IPOPT_LIBS = [
"lib/libipopt.a",
"lib/libipoptamplinterface.a",
"lib/libcoinmumps.a",
# TODO(#4913): Remove the dependency on METIS.
"lib/libcoinmetis.a",
"lib/libcoinasl.a",
"lib/libcoinlapack.a",
"lib/libcoinblas.a",
]

# Invokes ./configure, make, and make install to build IPOPT. We arbitrarily
# use make -j 8 and hope for the best in terms of overall CPU consumption, since
# Bazel has no way to tell a genrule how many cores it should use.
#
# We emit static libraries because dynamic libraries would have different names
# on OS X and on Linux, and Bazel genrules don't allow platform-dependent outs.
# https://github.com/bazelbuild/bazel/issues/281
BUILD_IPOPT_CMD = (
CDEXEC + " `pwd`/external/ipopt/configure --enable-shared=no 2> /dev/null" +
" && " + CDEXEC + " make -j 32 2> /dev/null" +
" && " + CDEXEC + " make install 2> /dev/null"
)

genrule(
name = "build_with_autotools",
srcs = glob(["**/*"]),
outs = IPOPT_HDRS + IPOPT_LIBS,
cmd = BUILD_IPOPT_CMD,
tools = ["@//tools/third_party/kythe/tools/cdexec:cdexec"],
visibility = ["//visibility:private"],
)

# Only Linux builds should depend on this target. gfortran is not available as
# a system library on OS X.
# TODO(david-german-tri): Ingest the fortran library path from the pkg-config
# files generated during the IPOPT build.
cc_library(
name = "lib",
srcs = IPOPT_LIBS,
hdrs = IPOPT_HDRS,
includes = ["include/coin"],
linkopts = [
"-lgfortran",
"-ldl",
],
linkstatic = 1,
visibility = ["//visibility:public"],
alwayslink = 1,
)
10 changes: 10 additions & 0 deletions tools/third_party/kythe/tools/cdexec/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package(
default_visibility = ["//visibility:public"],
)

exports_files(["cdexec.bzl"])

sh_binary(
name = "cdexec",
srcs = ["cdexec.sh"],
)
12 changes: 12 additions & 0 deletions tools/third_party/kythe/tools/cdexec/cdexec.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Skylark module with utilities and macros for running actions with cdexec."""

def rootpath(path):
"""Returns a string which cdexec will interpret as absolute.

Specifically, if the path starts with '/', it is returned unmodified.
Otherwise, the returns the path prefixed by the literal string '${PWD}/'
which will be expanded by the `cdexec` script into the Bazel exec root.
"""
if path.startswith("/"):
return path
return "${PWD}/" + path
Loading