Skip to content

Commit

Permalink
Merge pull request #4905 from david-german-tri/static_ipopt
Browse files Browse the repository at this point in the history
Add IPOPT to the Bazel build
  • Loading branch information
jwnimmer-tri authored Jan 26, 2017
2 parents bdb2bcd + 6e76b03 commit b7bb572
Show file tree
Hide file tree
Showing 8 changed files with 323 additions and 7 deletions.
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

0 comments on commit b7bb572

Please sign in to comment.